17#include <TChainElement.h>
20#include <TFriendElement.h>
22#include <TMethodCall.h>
33#ifndef XAOD_STANDALONE
96 "Did not call finishWritingTo() before destroying the TEvent object!");
112 if (pattern.size()) {
128 std::string_view treeName) {
131 if (
file ==
nullptr) {
133 return StatusCode::SUCCESS;
160 ATH_MSG_ERROR(
"Couldn't find metadata tree on input. Object is unusable!");
161 return StatusCode::FAILURE;
168 return StatusCode::FAILURE;
173 ATH_MSG_WARNING(
"Was expecting a metadata tree with size 1, instead of "
175 ATH_MSG_WARNING(
"The input file was most probably produced by hadd...");
181 static const std::string eventFormatTypeName =
183 ::TClass *cl = ::TClass::GetClass(eventFormatTypeName.c_str());
190 auto readEventFormatMetadata =
191 [&](std::string_view thisTreeName) -> StatusCode {
193 TTree *metaTree =
file->Get<TTree>(thisTreeName.data());
194 if (metaTree ==
nullptr) {
195 ATH_MSG_ERROR(
"Couldn't find metadata tree \"" << thisTreeName
197 return StatusCode::FAILURE;
200 if (metaTree->LoadTree(0) < 0) {
202 << thisTreeName <<
"\"");
203 return StatusCode::FAILURE;
207 const std::string eventFormatBranchName =
209 if (!metaTree->GetBranch(eventFormatBranchName.c_str())) {
213 ATH_MSG_INFO(
"Input file provides no event or metadata");
214 return StatusCode::RECOVERABLE;
221 metaTree->SetBranchAddress(eventFormatBranchName.c_str(), &format, &br);
223 ATH_MSG_ERROR(
"Failed to connect to xAOD::EventFormat object");
224 return StatusCode::FAILURE;
229 for (
const auto &[key, element] : *format) {
240 return StatusCode::SUCCESS;
246 if (
sc.isRecoverable()) {
249 return StatusCode::SUCCESS;
256 std::set<std::string> lOtherMetaTreeNames = {};
257 TList *lKeys =
file->GetListOfKeys();
260 for (
int iKey = 0; iKey < lKeys->GetEntries(); iKey++) {
262 std::string keyName = lKeys->At(iKey)->GetName();
269 const char *className = ((::TKey *)lKeys->At(iKey))->GetClassName();
270 static constexpr Bool_t LOAD = kFALSE;
271 static constexpr Bool_t SILENT = kTRUE;
272 ::TClass *cl = ::TClass::GetClass(className, LOAD, SILENT);
273 if ((cl !=
nullptr) && cl->InheritsFrom(::TTree::Class())) {
275 lOtherMetaTreeNames.insert(std::move(keyName));
282 for (
const std::string &metaTreeName : lOtherMetaTreeNames) {
283 ATH_CHECK(readEventFormatMetadata(metaTreeName));
306 stats.setNEvents(stats.nEvents() +
m_inTree->GetEntries());
312 listener->handle(beginIncident);
321 listener->handle(endIncident);
325 return StatusCode::SUCCESS;
348 if (useTreeCache && (!
m_inChain->GetCacheSize())) {
358 ATH_MSG_ERROR(
"Couldn't get the list of files from the input TChain");
359 return StatusCode::FAILURE;
361 if (!
files->GetEntries()) {
362 ATH_MSG_ERROR(
"No files are present in the received TChain");
363 return StatusCode::FAILURE;
365 const ::TChainElement *chEl =
366 dynamic_cast<const ::TChainElement *
>(
files->At(0));
369 return StatusCode::FAILURE;
372 std::unique_ptr<TFile> dummyFile{TFile::Open(chEl->GetTitle())};
375 return StatusCode::FAILURE;
390 return StatusCode::SUCCESS;
400 ::TFile *
file =
tree->GetCurrentFile();
414 std::string_view treeName) {
419 return StatusCode::FAILURE;
424 ATH_MSG_ERROR(
"Object already writing to a file. Close that file first!");
425 return StatusCode::FAILURE;
433 m_outTree = std::make_unique<TTree>(treeName.data(),
"xAOD event tree");
443 return StatusCode::SUCCESS;
456 ATH_MSG_ERROR(
"The object doesn't seem to be connected to an output file!");
457 return StatusCode::FAILURE;
467 listener->handle(incident);
481 return StatusCode::SUCCESS;
487 metatree->SetAutoSave(10000);
488 metatree->SetAutoFlush(-30000000);
489 metatree->SetDirectory(
file);
498 ::Error(
"xAOD::TEvent::finishWritingTo",
499 XAOD_MESSAGE(
"Class name parsing fails for %s ! "),
e.what());
500 return StatusCode::FAILURE;
506 std::vector<std::pair<std::string, TObjectManager *>> outputMetaObjects;
510 if (objMgr ==
nullptr) {
512 return StatusCode::FAILURE;
514 outputMetaObjects.emplace_back(key, objMgr);
519 for (
auto &[key, mgr] : outputMetaObjects) {
523 const ::Int_t splitLevel = (key.ends_with(
"Aux.") ? 1 : 0);
525 *(mgr->branchPtr()) =
526 metatree->Branch(key.c_str(), mgr->holder()->getClass()->GetName(),
527 mgr->holder()->getPtr(), 32000, splitLevel);
528 if (!mgr->branch()) {
530 << mgr->holder()->getClass()->GetName() <<
"/" << key
532 return StatusCode::FAILURE;
536 static constexpr bool METADATA =
true;
541 if (metatree->Fill() <= 0) {
542 ATH_MSG_ERROR(
"Failed to write event format metadata into the output");
543 metatree->SetDirectory(
nullptr);
544 return StatusCode::FAILURE;
549 metatree->SetDirectory(
nullptr);
555 return StatusCode::SUCCESS;
594 static constexpr bool TOP_STORE =
true;
595 if (
record(std::make_unique<TAuxStore>(key, TOP_STORE, mode), key)
597 ATH_MSG_ERROR(
"Couldn't connect TAuxStore object to the output");
666 const ::Long64_t fileEntry =
m_inChain->LoadTree(entry);
669 <<
" from the input chain");
683 static constexpr bool USE_TREE_CACHE =
false;
708 <<
" from the input file");
724 static const std::string dynStorePostfix =
"Aux.Dynamic";
725 if (key.ends_with(dynStorePostfix)) {
733 static constexpr bool SILENT =
true;
734 static constexpr bool METADATA =
false;
741 result += mgr->getEntry(getall);
749 listener->handle(incident);
768 return m_inChain->GetListOfFiles()->GetEntries();
804 ::Long64_t entry = 0;
805 for (::Long64_t i = 0; i <
file; ++i) {
846 std::string unsetObjects;
847 std::vector<std::pair<std::string, TVirtualManager *>> outputObjectsCopy;
850 outputObjectsCopy.emplace_back(key, mgr.get());
852 for (
auto &[key, mgr] : outputObjectsCopy) {
854 if (!mgr->create()) {
857 if (unsetObjects.size()) {
858 unsetObjects +=
", ";
860 unsetObjects.append(
"\"" + key +
"\"");
866 static constexpr bool METADATA =
false;
869 "in the output for object \""
876 if (unsetObjects.size()) {
877 ATH_MSG_ERROR(
"The following objects were not set in the current event: "
885 ATH_MSG_ERROR(
"Output tree filling failed with return value: " << ret);
905 std::vector<std::string> &vkeys,
906 bool metadata)
const {
908 std::set<std::string>
keys;
912 std::vector<TObjArray *> fullListOfBranches = {};
918 fullListOfBranches.push_back(
m_inMetaTree->GetListOfBranches());
924 fullListOfBranches.push_back(
m_inTree->GetListOfBranches());
929 TList *fList =
m_inTree->GetListOfFriends();
931 for (TObject *feObj : *fList) {
934 auto *pElement =
dynamic_cast<TFriendElement *
>(feObj);
935 if (pElement ==
nullptr) {
938 TTree *friendTree = pElement->GetTree();
940 fullListOfBranches.push_back(friendTree->GetListOfBranches());
948 for (
const TObjArray *in : fullListOfBranches) {
950 for (
const TObject *obj : *in) {
952 if (obj ==
nullptr) {
955 const TBranch *element =
dynamic_cast<const TBranch *
>(obj);
958 return StatusCode::FAILURE;
960 const std::string objClassName = element->GetClassName();
961 std::string key = obj->GetName();
964 if (objClassName == targetClassName) {
965 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
967 keys.insert(std::move(key));
974 ATH_MSG_DEBUG(
"Scanning input objects for \"" << targetClassName <<
"\"");
975 for (
const auto &[key, vmgr] : inAux) {
979 if (mgr ==
nullptr) {
982 const std::string &objClassName = mgr->holder()->getClass()->GetName();
985 if (objClassName == targetClassName) {
986 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
994 const TObjArray *out =
m_outTree->GetListOfBranches();
997 for (
const TObject *obj : *out) {
998 if (obj ==
nullptr) {
1001 const TBranch *element =
dynamic_cast<const TBranch *
>(obj);
1002 if (element ==
nullptr) {
1004 return StatusCode::FAILURE;
1006 const std::string objClassName = element->GetClassName();
1007 std::string key = obj->GetName();
1010 if (objClassName == targetClassName) {
1011 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
1013 keys.insert(std::move(key));
1021 ATH_MSG_DEBUG(
"Scanning output objects for \"" << targetClassName <<
"\"");
1022 for (
const auto &[key, vmgr] : outAux) {
1025 if (mgr ==
nullptr) {
1028 const std::string &objClassName = mgr->holder()->getClass()->GetName();
1031 if (objClassName == targetClassName) {
1032 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
1038 vkeys.insert(vkeys.end(),
keys.begin(),
keys.end());
1041 return StatusCode::SUCCESS;
1066 return StatusCode::FAILURE;
1074 return StatusCode::SUCCESS;
1078 if (silent ==
false) {
1081 return StatusCode::RECOVERABLE;
1087 if (silent ==
false) {
1095 ::TBranch *br =
m_inTree->GetBranch(key.c_str());
1096 if (br ==
nullptr) {
1101 return StatusCode::RECOVERABLE;
1105 br->SetMakeClass(0);
1109 std::string className = br->GetClassName();
1110 if (className ==
"") {
1114 className = ef->className();
1117 "Couldn't find an appropriate type with a dictionary for branch \""
1119 return StatusCode::FAILURE;
1122 ::TClass *realClass = ::TClass::GetClass(className.c_str());
1123 if (((!realClass) || (!realClass->IsLoaded())) && ef) {
1127 className = ef->className();
1128 realClass = ::TClass::GetClass(className.c_str());
1130 if ((!realClass) || (!realClass->IsLoaded())) {
1133 "Couldn't find an appropriate type with a dictionary for branch \""
1135 return StatusCode::FAILURE;
1142 static const ::EDataType dataType = kOther_t;
1148 void *ptr =
nullptr;
1153 if (mgr ==
nullptr) {
1154 ATH_MSG_ERROR(
"Couldn't access output manager for: " << key);
1155 return StatusCode::FAILURE;
1158 ptr = mgr->holder()->get();
1164 if (ptr ==
nullptr) {
1165 ptr = realClass->New();
1170 auto mgr = std::make_unique<TObjectManager>(
1171 nullptr, std::make_unique<THolder>(ptr, realClass), renewOnRead);
1180 << key <<
"\" is " << br->GetSplitLevel()
1181 <<
". This can only be read in kAthenaAccess mode.");
1183 *(mgr->holder()->getPtr()) =
nullptr;
1185 return StatusCode::FAILURE;
1189 const ::Int_t status =
1190 m_inTree->SetBranchAddress(key.c_str(), mgr->holder()->getPtr(),
1191 mgr->branchPtr(), realClass, dataType, kTRUE);
1194 << className <<
"\" to input branch \"" << key
1195 <<
"\". Return code: " << status);
1197 *(mgr->holder()->getPtr()) = 0;
1199 return StatusCode::FAILURE;
1219 return StatusCode::SUCCESS;
1235 return StatusCode::FAILURE;
1240 return StatusCode::SUCCESS;
1245 if (br ==
nullptr) {
1246 if (silent ==
false) {
1248 <<
"\" not available on input");
1250 return StatusCode::RECOVERABLE;
1254 if (br->GetEntries() == 0) {
1255 if (silent ==
false) {
1257 <<
"\" doesn't hold any data");
1259 return StatusCode::RECOVERABLE;
1263 br->SetMakeClass(0);
1267 ::EDataType dt = kOther_t;
1268 if (br->GetExpectedType(cl, dt) || (!cl)) {
1269 ATH_MSG_ERROR(
"Couldn't get the type for metadata branch \"" << key
1271 return StatusCode::FAILURE;
1275 void *ptr = cl->New();
1277 auto mgr = std::make_unique<TObjectManager>(
1278 nullptr, std::make_unique<THolder>(ptr, cl), renewOnRead);
1282 key.c_str(), mgr->holder()->getPtr(), mgr->branchPtr(), cl, dt, kTRUE);
1285 << cl->GetName() <<
"\" to input branch \"" << key
1286 <<
"\". Return code: " << status);
1288 *(mgr->holder()->getPtr()) = 0;
1290 return StatusCode::FAILURE;
1299 ATH_MSG_ERROR(
"Couldn't read in metadata object with key \"" << key
1301 return StatusCode::FAILURE;
1314 static constexpr bool METADATA =
true;
1319 return StatusCode::SUCCESS;
1336 return StatusCode::FAILURE;
1340 if ((!
m_inTree->GetBranch(prefix.c_str())) &&
1344 return StatusCode::SUCCESS;
1349 return StatusCode::SUCCESS;
1357 static constexpr bool SILENT =
false;
1361 return StatusCode::SUCCESS;
1367 static constexpr bool TOP_STORE =
true;
1368 auto store = std::make_unique<TAuxStore>(
1381 static constexpr bool IS_OWNER =
true;
1383 std::make_unique<TAuxManager>(store.release(), IS_OWNER);
1386 return StatusCode::SUCCESS;
1391 return StatusCode::FAILURE;
1407 return StatusCode::SUCCESS;
1413 return StatusCode::FAILURE;
1421 static constexpr bool SILENT =
false;
1425 return StatusCode::SUCCESS;
1431 static constexpr bool TOP_STORE =
true;
1432 auto store = std::make_unique<TAuxStore>(
1445 static constexpr bool IS_OWNER =
true;
1447 std::make_unique<TAuxManager>(store.release(), IS_OWNER);
1450 return StatusCode::SUCCESS;
1455 return StatusCode::FAILURE;
1475 (isAuxStore ==
false)) {
1476 return StatusCode::SUCCESS;
1489 auto itr = objects.find(key +
"Aux.");
1490 if (itr == objects.end()) {
1493 return StatusCode::SUCCESS;
1495 auxMgr = itr->second.get();
1496 auxKey = key +
"Aux.";
1499 if (metadata ==
false) {
1501 const ::Int_t readBytes = auxMgr->
getEntry();
1502 if (readBytes < 0) {
1504 "Couldn't load current entry for auxiliary object with key \""
1506 return StatusCode::FAILURE;
1511 const std::string dynAuxKey = auxKey +
"Dynamic";
1512 auto dynAuxMgr = objects.find(dynAuxKey);
1514 if ((dynAuxMgr != objects.end()) &&
1520 dynAuxMgr->second->getEntry();
1531 auto dynAuxMgr = objects.find(dynAuxKey);
1532 if (dynAuxMgr == objects.end()) {
1534 return StatusCode::FAILURE;
1536 dynAuxMgr->second->getEntry();
1543 return StatusCode::SUCCESS;
1549 switch (mgr.holder()->typeKind()) {
1564 if (
vec && (!
vec->trackIndices())) {
1565 Details::forceTrackIndices(*
vec);
1571 << mgr.holder()->getClass()->GetName()
1572 <<
"\" as SG::AuxVectorBase or SG::AuxElement");
1573 return StatusCode::FAILURE;
1583 << auxKey <<
"\" is not of the right type");
1584 return StatusCode::FAILURE;
1600 << auxKey <<
"\" is not of the right type");
1601 return StatusCode::FAILURE;
1608 return StatusCode::FAILURE;
1613 vec->setStore(store);
1615 aux->setStore(store);
1618 return StatusCode::FAILURE;
1622 return StatusCode::SUCCESS;
1641 const std::string &key,
bool overwrite,
bool metadata,
1647 "No output tree defined. Did you forget to call writeTo(...)?");
1648 return StatusCode::FAILURE;
1658 ATH_MSG_ERROR(
"Meta-object \"" << typeName <<
"\"/\"" << key
1659 <<
"\" already recorded");
1660 return StatusCode::FAILURE;
1663 TClass *cl = TClass::GetClass(typeName.c_str());
1665 ATH_MSG_ERROR(
"Didn't find dictionary for type: " << typeName);
1666 return StatusCode::FAILURE;
1671 nullptr, std::make_unique<THolder>(obj, cl, isOwner), renewOnRead);
1673 return StatusCode::SUCCESS;
1680 <<
"\" already accessed from the input, can't be "
1681 "overwritten in memory");
1682 return StatusCode::FAILURE;
1686 const Int_t splitLevel = (key.ends_with(
"Aux.") ? 1 : 0);
1693 TClass *cl = TClass::GetClass(typeName.c_str());
1694 if (cl ==
nullptr) {
1695 ATH_MSG_ERROR(
"Didn't find dictionary for type: " << typeName);
1696 return StatusCode::FAILURE;
1707 auto mgr = std::make_unique<TObjectManager>(
1708 nullptr, std::make_unique<THolder>(obj, cl, isOwner), renewOnRead);
1713 static constexpr Int_t basketSize = 32000;
1715 m_outTree->Branch(key.c_str(), cl->GetName(),
1718 ATH_MSG_ERROR(
"Failed to create branch \"" << key <<
"\" out of type \""
1719 << cl->GetName() <<
"\"");
1722 return StatusCode::FAILURE;
1727 static constexpr bool METADATA =
false;
1732 return StatusCode::SUCCESS;
1738 ATH_MSG_ERROR(
"Manager object of the wrong type encountered");
1739 return StatusCode::FAILURE;
1748 TClass *cl = TClass::GetClass(typeName.c_str());
1750 ::strcmp(cl->GetName(), omgr->
holder()->
getClass()->GetName())) {
1752 << key <<
"\" the previous type was \""
1754 <<
"\", but the newly requested type is \"" << typeName
1756 return StatusCode::FAILURE;
1764 static constexpr bool METADATA =
false;
1768 return StatusCode::SUCCESS;
1777 if (iomgr !=
nullptr) {
1779 static const bool OVERWRITE =
true;
1780 static const bool IS_OWNER =
true;
1782 key, OVERWRITE, metadata, IS_OWNER));
1783 return StatusCode::SUCCESS;
1788 if (auxmgr !=
nullptr) {
1792 "TAuxStore auxiliary objects can only be recorded for event data");
1793 return StatusCode::FAILURE;
1797 return StatusCode::SUCCESS;
1801 ATH_MSG_ERROR(
"Unknown auxiliary store manager type encountered");
1802 return StatusCode::FAILURE;
1815 return StatusCode::SUCCESS;
1820 ATH_MSG_ERROR(
"Function called on an uninitialised object");
1821 return StatusCode::FAILURE;
1830 for (; itr != end; ++itr) {
1833 const std::string &branchName = itr->second.branchName();
1836 if (branchName.find(
"Aux.") != std::string::npos) {
1845 const std::string intName = branchName.substr(0, branchName.size() - 4);
1853 ::Bool_t auxFound = kFALSE;
1856 std::vector<TObjArray *> fullListOfBranches = {};
1858 fullListOfBranches.push_back(
m_inTree->GetListOfBranches());
1861 if (
m_inTree->GetListOfFriends()) {
1863 TList *fList =
m_inTree->GetListOfFriends();
1865 for (TObject *feObj : *fList) {
1868 auto *pElement =
dynamic_cast<TFriendElement *
>(feObj);
1871 TTree *friendTree = pElement->GetTree();
1873 fullListOfBranches.push_back(friendTree->GetListOfBranches());
1878 for (TObjArray *branches : fullListOfBranches) {
1879 for (Int_t i = 0; i < branches->GetEntriesFast(); ++i) {
1880 if (!branches->At(i))
1883 const TString
name(branches->At(i)->GetName());
1884 if (
name.BeginsWith(branchName) ||
name.BeginsWith(dynName)) {
1892 << intName <<
"\" belonging to branch \""
1893 << branchName <<
"\"");
1900 ::TClass *cl = ::TClass::GetClass(el->className().c_str());
1901 if ((!cl) || (!cl->IsLoaded())) {
1903 << el->className() <<
"\"");
1910 static ::TClass *
const baseCl = ::TClass::GetClass(baseName.c_str());
1912 ATH_MSG_ERROR(
"Couldn't get dictionary for type \"" << baseName
1914 return StatusCode::FAILURE;
1924 static constexpr bool TOP_STORE =
true;
1925 TAuxStore temp(branchName, TOP_STORE, mode);
1926 static constexpr bool PRINT_WARNINGS =
false;
1934 stats.branch(branchName,
id);
1938 stats.setBranchNum(stats.branchNum() + temp.getAuxIDs().size());
1952 return StatusCode::SUCCESS;
1968 const std::string &key) {
1973 "No output tree defined. Did you forget to call writeTo(...)?");
1974 return StatusCode::FAILURE;
1978 const std::set<std::string> *filter = 0;
1981 filter = &(filter_itr->second);
1990 store->selectAux(*filter);
1995 static constexpr bool OWNS_STORE =
true;
1997 std::make_unique<TAuxManager>(store.release(), OWNS_STORE);
2000 return StatusCode::SUCCESS;
2004 if (vitr->second->object() == store.get()) {
2006 return StatusCode::SUCCESS;
2015 if (mgr ==
nullptr) {
2017 << key <<
"\" already exists, and is not of type TAuxStore");
2018 return StatusCode::FAILURE;
2023 store->selectAux(*filter);
2030 mgr->setObject(store.release());
2033 return StatusCode::SUCCESS;
2047 ::TMethodCall setNameCall;
2051 setNameCall.InitWithPrototype(mgr.holder()->getClass(),
"setName",
2053 if (setNameCall.IsValid()) {
2056 const ::TString params =
2057 ::TString::Format(
"\"%s\"", mgr.branch()->GetName());
2058 const char *charParams = params.Data();
2059 setNameCall.Execute(mgr.holder()->get(), charParams);
2062 ATH_MSG_WARNING(
"Couldn't find setName(...) function for container \""
2063 << mgr.branch()->GetName() <<
"\" (type: "
2064 << mgr.holder()->getClass()->GetName() <<
")");
2069 static const TClass *
const holderClass =
2071 if (!mgr.holder()->getClass()->InheritsFrom(holderClass)) {
2073 return StatusCode::SUCCESS;
2081 return StatusCode::FAILURE;
2088 static constexpr bool TOP_STORE =
false;
2089 auto store = std::make_unique<TAuxStore>(
2090 mgr.branch()->GetName(), TOP_STORE,
2109 static constexpr bool SHARED_OWNER =
false;
2110 m_inputObjects[std::string(mgr.branch()->GetName()) +
"Dynamic"] =
2111 std::make_unique<TAuxManager>(store.get(), SHARED_OWNER);
2114 storeHolder->
setStore(store.release());
2117 return StatusCode::SUCCESS;
2140 return StatusCode::SUCCESS;
2144 if (!mgr->holder()->getClass()->InheritsFrom(
"SG::IAuxStoreIO")) {
2145 return StatusCode::SUCCESS;
2153 return StatusCode::FAILURE;
2160 auto item_itr =
m_auxItemList.find(mgr->branch()->GetName());
2162 sel.selectAux(item_itr->second);
2169 sel.getSelectedAuxIDs(
aux->getSelectedAuxIDs());
2173 if (auxids.
empty()) {
2174 return StatusCode::SUCCESS;
2178 const std::string dynNamePrefix =
2187 typedef std::pair<std::string, SG::auxid_t> AuxVarSort_t;
2188 std::vector<AuxVarSort_t> varsort;
2189 varsort.reserve(auxids.
size());
2191 varsort.emplace_back(
r.getName(
id),
id);
2193 std::sort(varsort.begin(), varsort.end());
2196 for (
const auto &p : varsort) {
2202 const std::string brName = dynNamePrefix + p.first;
2205 Object_t::iterator bmgr = objects.find(brName);
2208 if (bmgr == objects.end()) {
2211 const std::type_info *brType =
aux->getIOType(
id);
2214 return StatusCode::FAILURE;
2217 std::string brProperTypeName =
"<unknown>";
2223 if (strlen(brType->name()) == 1) {
2226 brProperTypeName = brTypeName;
2230 if (rootType ==
'\0') {
2232 << brName <<
"\" of type \"" << brTypeName <<
"\"");
2233 return StatusCode::FAILURE;
2237 std::ostringstream leaflist;
2238 leaflist << brName <<
"/" << rootType;
2241 static constexpr bool IS_OWNER =
false;
2242 auto auxmgr = std::make_unique<TPrimitiveAuxBranchManager>(
2243 id,
nullptr,
new THolder(
aux->getIOData(
id),
nullptr, IS_OWNER));
2246 static constexpr Int_t BASKET_SIZE = 32000;
2247 *(auxmgr->branchPtr()) =
2248 outTree.Branch(brName.c_str(), auxmgr->holder()->get(),
2249 leaflist.str().c_str(), BASKET_SIZE);
2250 if (!auxmgr->branch()) {
2252 << brName <<
"\" out of type \"" << brProperTypeName
2255 *(auxmgr->holder()->getPtr()) = 0;
2256 return StatusCode::FAILURE;
2258 br = auxmgr->branch();
2261 objects[brName] = std::move(auxmgr);
2266 static constexpr Bool_t LOAD_IF_NOT_FOUND = kTRUE;
2267 static constexpr Bool_t SILENT = kTRUE;
2268 TClass *cl = TClass::GetClass(*brType, LOAD_IF_NOT_FOUND, SILENT);
2269 if (cl ==
nullptr) {
2272 cl = TClass::GetClass(brTypeName.c_str());
2274 if (cl ==
nullptr) {
2276 << brName <<
"\" of type \"" << brTypeName <<
"\"");
2277 return StatusCode::FAILURE;
2282 brProperTypeName = cl->GetName();
2285 static constexpr bool IS_OWNER =
false;
2286 auto auxmgr = std::make_unique<TAuxBranchManager>(
2287 id,
nullptr,
new THolder(
aux->getIOData(
id), cl, IS_OWNER));
2290 static constexpr Int_t BASKET_SIZE = 32000;
2291 static constexpr Int_t SPLIT_LEVEL = 0;
2292 *(auxmgr->branchPtr()) = outTree.Branch(brName.c_str(), cl->GetName(),
2293 auxmgr->holder()->getPtr(),
2294 BASKET_SIZE, SPLIT_LEVEL);
2295 if (!auxmgr->branch()) {
2297 << brName <<
"\" out of type \"" << brProperTypeName
2300 *(auxmgr->holder()->getPtr()) = 0;
2301 return StatusCode::FAILURE;
2303 br = auxmgr->branch();
2306 objects[brName] = std::move(auxmgr);
2311 if (outTree.GetEntries()) {
2312 void *ptr = br->GetAddress();
2314 for (::Long64_t i = 0; i < outTree.GetEntries(); ++i) {
2317 br->SetAddress(ptr);
2324 mgr->branch()->GetName(),
2333 bmgr = objects.find(brName);
2334 if (bmgr == objects.end()) {
2335 ATH_MSG_FATAL(
"There is an internal logic error in the code...");
2336 return StatusCode::FAILURE;
2342 const_cast<void *
>(
static_cast<const void *
>(
aux->getIOData(
id)));
2343 bmgr->second->setObject(nc_data);
2347 return StatusCode::SUCCESS;
2355 return StatusCode::FAILURE;
2359 const std::set<std::string> *filter = 0;
2362 filter = &(filter_itr->second);
2371 store->selectAux(*filter);
2376 static constexpr bool OWNS_STORE =
false;
2377 m_outputObjects[key] = std::make_unique<TAuxManager>(store, OWNS_STORE);
2380 return StatusCode::SUCCESS;
2384 if (vitr->second->object() == store) {
2386 return StatusCode::SUCCESS;
2395 if (mgr ==
nullptr) {
2397 << key <<
"\" already exists, and is not of type TAuxStore");
2398 return StatusCode::FAILURE;
2403 store->selectAux(*filter);
2410 mgr->setObject(store);
2413 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.
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.
StatusCode writeTo(::TFile *file, int autoFlush=200, std::string_view treeName=EVENT_TREE_NAME)
Connect the object to an output file.
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.
::Long64_t getEntries() const
Get how many entries are available from the current input file(s)
StatusCode finishWritingTo(::TFile *file)
Finish writing to an output file.
::Int_t fill()
Function filling one event into the output tree.
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 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 readFrom(::TFile *file, bool useTreeCache=true, std::string_view treeName=EVENT_TREE_NAME)
Connect the object to a new input file.
StatusCode putAux(::TTree &outTree, TVirtualManager &mgr, bool metadata)
Function saving the dynamically created auxiliary properties.
EAuxMode m_auxMode
The auxiliary access mode.
virtual ~TEvent()
Destructor.
TEvent(EAuxMode mode=kClassAccess)
Default constructor.
::Int_t getEntry(::Long64_t entry, ::Int_t getall=0)
Function loading a given entry of the input TTree.
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.
static const char *const EVENT_TREE_NAME
Default name of the event tree.
::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.
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 char *const METADATA_TREE_NAME
Name of the metadata tree.
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...