ATLAS Offline Software
Loading...
Searching...
No Matches
Athena::RootNtupleEventSelector Class Reference

Class implementing the GAUDI IEvtSelector interface using ROOT TTree as a backend. More...

#include <RootNtupleEventSelector.h>

Inheritance diagram for Athena::RootNtupleEventSelector:
Collaboration diagram for Athena::RootNtupleEventSelector:

Public Member Functions

 RootNtupleEventSelector (const std::string &name, ISvcLocator *svcLoc)
 Constructor with parameters:
virtual ~RootNtupleEventSelector ()
 Destructor:
virtual StatusCode initialize () override
virtual StatusCode stop () override
virtual StatusCode finalize () override
virtual void handle (const Incident &incident) override
virtual StatusCode io_reinit () override
 Callback method to reinitialize the internal state of the component for I/O purposes (e.g.
virtual int size (Context &refCtxt) const override
 ICollectionSize interface
virtual StatusCode createContext (Context *&refpCtxt) const override
virtual StatusCode last (Context &refContext) const override
virtual StatusCode next (Context &refCtxt) const override
virtual StatusCode next (Context &refCtxt, int jump) const override
virtual StatusCode previous (Context &refCtxt) const override
virtual StatusCode previous (Context &refCtxt, int jump) const override
virtual StatusCode rewind (Context &refCtxt) const override
virtual StatusCode createAddress (const Context &refCtxt, IOpaqueAddress *&) const override
virtual StatusCode releaseContext (Context *&refCtxt) const override
virtual StatusCode resetCriteria (const std::string &cr, Context &ctx) const override
virtual StatusCode seek (Context &refCtxt, int evtnum) const override
 Seek to a given event number.
virtual int curEvent (const Context &refCtxt) const override
 return the current event number.
virtual StatusCode preLoadAddresses (StoreID::type storeID, tadList &list) override
virtual StatusCode loadAddresses (StoreID::type storeID, tadList &list) override
 get all new addresses from Provider for this Event.
virtual StatusCode updateAddress (StoreID::type storeID, SG::TransientAddress *tad, const EventContext &ctx) override
 update a transient Address

Private Member Functions

StatusCode endInputFile (RootNtupleEventContext *rctx) const
void setupInputCollection (Gaudi::Details::PropertyBase &inputCollectionsName)
 callback to synchronize the list of input files
StatusCode createRootBranchAddresses (StoreID::type storeID, tadList &tads)
 helper method to create proxies
TTree * fetchNtuple (const std::string &fname, const std::string &tupleName) const
 helper method to retrieve the correct tuple
void addMetadataFromDirectoryName (const std::string &metadirname, TFile *fileObj, const std::string &prefix="") const
void addMetadataFromDirectory (TDirectoryFile *metadir, const std::string &prefix="") const
void addMetadata (TTree *metatree, const std::string &path="") const
void addMetadata (TObjString *metastring, const std::string &path="") const
StatusCode createMetaDataRootBranchAddresses (StoreGateSvc *store, TTree *tree, const std::string &prefix) const
 helper method to create proxies for the metadata store
StatusCode do_init_io ()
 helper method to init the i/o components

Private Attributes

std::vector< std::vector< CollMetaData > > m_collEvts
 helper method to get the collection index (into m_inputCollectionsName) and tuple index (into m_tupleNames') for a given event index evtidx`.
TTree * m_tuple
 current tree being read
bool m_needReload
 The (python) selection function to apply on the TChain we are reading.
std::optional< InputFileIncidentGuardm_inputFileGuard
 RAII guard: guarantees a matching EndInputFile for every BeginInputFile.
bool m_fireBIF {true}
 Flag to fire BeginInputFile on the next BeginEvent incident.
std::vector< TFile * > m_files

Friends

class Athena::RootNtupleEventContext

Detailed Description

Class implementing the GAUDI IEvtSelector interface using ROOT TTree as a backend.

Definition at line 48 of file RootNtupleEventSelector.h.

Constructor & Destructor Documentation

◆ RootNtupleEventSelector()

Athena::RootNtupleEventSelector::RootNtupleEventSelector ( const std::string & name,
ISvcLocator * svcLoc )

Constructor with parameters:

Definition at line 223 of file RootNtupleEventSelector.cxx.

224 :
225 extends ( name, svcLoc ),
226 m_dataStore( "StoreGateSvc/StoreGateSvc", name ),
227 m_imetaStore( "StoreGateSvc/InputMetaDataStore", name ),
228 m_ometaStore( "StoreGateSvc/MetaDataStore", name ),
229 m_clidsvc ( "ClassIDSvc", name ),
230 m_dictsvc ( "AthDictLoaderSvc", name ),
231 m_incsvc ( "IncidentSvc", name ),
232 m_nbrEvts ( 0 ),
233 m_curEvt ( 0 ),
234 m_collEvts ( ),
235 m_tuple (NULL),
236 m_needReload (true)
237{
238 declareProperty( "DataStore",
239 m_dataStore,
240 "Store where to publish data");
241
242 declareProperty( "InputMetaStore",
243 m_imetaStore,
244 "Store where to publish (input) metadata");
245
246 declareProperty( "MetaStore",
247 m_ometaStore,
248 "Store where to publish (output) metadata");
249
250 declareProperty( "InputCollections",
251 m_inputCollectionsName,
252 "List of input (ROOT) file names" );
253 m_inputCollectionsName.declareUpdateHandler
255
256 declareProperty( "TupleName",
257 m_tupleName = "CollectionTree",
258 "Name of the TTree to load/read from input file(s). "
259 "May be a semicolon-separated string to read multiple TTrees.");
260
261 declareProperty( "SkipEvents",
262 m_skipEvts = 0,
263 "Number of events to skip at the beginning" );
264
265 declareProperty( "ActiveBranches",
266 m_activeBranchNames,
267 "List of branch names to activate" );
268}
void setupInputCollection(Gaudi::Details::PropertyBase &inputCollectionsName)
callback to synchronize the list of input files
TTree * m_tuple
current tree being read
std::vector< std::vector< CollMetaData > > m_collEvts
helper method to get the collection index (into m_inputCollectionsName) and tuple index (into m_tuple...
bool m_needReload
The (python) selection function to apply on the TChain we are reading.

◆ ~RootNtupleEventSelector()

Athena::RootNtupleEventSelector::~RootNtupleEventSelector ( )
virtual

Destructor:

Definition at line 272 of file RootNtupleEventSelector.cxx.

273{}

Member Function Documentation

◆ addMetadata() [1/2]

void Athena::RootNtupleEventSelector::addMetadata ( TObjString * metastring,
const std::string & path = "" ) const
private

Definition at line 1212 of file RootNtupleEventSelector.cxx.

1213{
1214 std::string *converted = new std::string(metastring->String());
1215 if (!m_imetaStore->record(converted, path).isSuccess()) {
1216 ATH_MSG_INFO("Could not create metadata for string [" << path << "]");
1217 }
1218}
#define ATH_MSG_INFO(x)

◆ addMetadata() [2/2]

void Athena::RootNtupleEventSelector::addMetadata ( TTree * metatree,
const std::string & path = "" ) const
private

Definition at line 1200 of file RootNtupleEventSelector.cxx.

1201{
1202 if (metatree->GetEntry(0) < 0) {
1203 ATH_MSG_INFO("Problem retrieving data from metadata-tree [" << path << "] !!");
1204 return;
1205 }
1206
1207 if (!createMetaDataRootBranchAddresses(m_imetaStore.get(), metatree, path).isSuccess()) {
1208 ATH_MSG_INFO("Could not create metadata for tree [" << path << "]");
1209 }
1210}
StatusCode createMetaDataRootBranchAddresses(StoreGateSvc *store, TTree *tree, const std::string &prefix) const
helper method to create proxies for the metadata store

◆ addMetadataFromDirectory()

void Athena::RootNtupleEventSelector::addMetadataFromDirectory ( TDirectoryFile * metadir,
const std::string & prefix = "" ) const
private

Definition at line 1158 of file RootNtupleEventSelector.cxx.

1159{
1160 std::unordered_set<std::string> meta_keys;
1161 const TList *keys = metadir->GetListOfKeys();
1162 for (Int_t i=0; i < keys->GetSize(); ++i) {
1163 TKey* key = dynamic_cast<TKey*>(keys->At(i));
1164 if (!key) {
1165 continue;
1166 }
1167
1168 const std::string meta_key = key->GetName();
1169 if (!meta_keys.emplace(key->GetName()).second) {
1170 // key was already in the set:
1171 // meta_key is another cycle from a previous key entry.
1172 // *ASSUME* the highest cycle is the one we are interested in
1173 // *AND* that it was the previous one...
1174 continue;
1175 }
1176
1177 std::string fullPrefix(prefix);
1178 if (prefix != "") fullPrefix += "/";
1179 const std::string path = fullPrefix + key->GetName();
1180
1181 TString fullKeyName(TString::Format("%s;%hi", key->GetName(), key->GetCycle()));
1182 TObject *objRef = metadir->Get(fullKeyName);
1183
1184 TTree *metatree = dynamic_cast<TTree*>(objRef);
1185 if (metatree) {
1186 addMetadata(metatree, path);
1187 continue;
1188 }
1189
1190 TObjString *metaObjString = dynamic_cast<TObjString*>(objRef);
1191 if (metaObjString) {
1192 addMetadata(metaObjString, path);
1193 continue;
1194 }
1195
1196 ATH_MSG_WARNING("Unsupported metadata type: " << objRef->ClassName());
1197 }
1198}
#define ATH_MSG_WARNING(x)
void addMetadata(TTree *metatree, const std::string &path="") const
path
python interpreter configuration --------------------------------------—
Definition athena.py:130

◆ addMetadataFromDirectoryName()

void Athena::RootNtupleEventSelector::addMetadataFromDirectoryName ( const std::string & metadirname,
TFile * fileObj,
const std::string & prefix = "" ) const
private

Definition at line 1151 of file RootNtupleEventSelector.cxx.

1152{
1153 TDirectoryFile *metadir = (TDirectoryFile*)fileObj->Get(metadirname.c_str());
1154 if (!metadir) return;
1155 addMetadataFromDirectory(metadir, prefix);
1156}
void addMetadataFromDirectory(TDirectoryFile *metadir, const std::string &prefix="") const

◆ createAddress()

StatusCode Athena::RootNtupleEventSelector::createAddress ( const Context & refCtxt,
IOpaqueAddress *&  ) const
overridevirtual

Definition at line 669 of file RootNtupleEventSelector.cxx.

671{
672 //std::cerr << "::TTES::createAddress()...\n";
673 return StatusCode::SUCCESS;
674}

◆ createContext()

StatusCode Athena::RootNtupleEventSelector::createContext ( Context *& refpCtxt) const
overridevirtual

IEvtSelector interface

Definition at line 661 of file RootNtupleEventSelector.cxx.

662{
664 refCtx = ctx;
665 return StatusCode::SUCCESS;
666}

◆ createMetaDataRootBranchAddresses()

StatusCode Athena::RootNtupleEventSelector::createMetaDataRootBranchAddresses ( StoreGateSvc * store,
TTree * tree,
const std::string & prefix ) const
private

helper method to create proxies for the metadata store

Definition at line 976 of file RootNtupleEventSelector.cxx.

979{
980 if (0 == store) {
981 ATH_MSG_ERROR("null pointer to store !");
982 return StatusCode::FAILURE;
983 }
984
985 if (0 == tree) {
986 ATH_MSG_ERROR("null pointer to n-tuple !");
987 return StatusCode::FAILURE;
988 }
989
990 // Record tree in Storegate for later writing
991 TransferTree* temp = new TransferTree(tree);
992 if (store->record(temp,prefix).isFailure()) ATH_MSG_ERROR("Unable to record metadata tree " << tree->GetName());
993
994 const std::string tree_name = tree->GetName();
995 TObjArray *branches = tree->GetListOfBranches();
996 if (!branches) {
997 ATH_MSG_INFO("no branches!!");
998 return StatusCode::SUCCESS;
999 }
1000
1001 // loop over branches
1002 for (Int_t i = 0; i < branches->GetEntries(); ++i) {
1003 TBranch *branch = (TBranch *)branches->At(i);
1004 if (branch) {
1005
1006 CLID id = 0;
1007 const void* value_ptr = tree;
1008 const std::string type_name = branch->GetClassName();
1009 const std::string br_name = branch->GetName();
1010 const std::string sg_key = prefix.empty()
1011 ? br_name
1012 : prefix + "/" + br_name;
1013 TClass *cls = NULL;
1014 if (!type_name.empty()) {
1015 cls = TClass::GetClass(type_name.c_str());
1016 }
1017 const std::type_info *ti = 0;
1018
1019 if (cls) {
1020 ti = cls->GetTypeInfo();
1021 // first, try to load a dict for that class...
1022 if (ti) {
1023 m_dictsvc->load_type(*ti);
1024 }
1025 if (!ti) {
1026 ATH_MSG_WARNING("could not find a type-info for [" <<
1027 type_name << "]");
1028 continue;
1029 }
1030 std::string ti_typename = System::typeinfoName(*ti);
1031 if (!m_clidsvc->getIDOfTypeInfoName(ti_typename, id)
1032 .isSuccess()) {
1033 // try another one...
1034 {
1035 // Protect against data race inside TClassEdit.
1036 // https://github.com/root-project/root/issues/10353
1037 // Should be fixed in root 6.26.02.
1038 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
1039 ti_typename = TClassEdit::ShortType(ti_typename.c_str(),
1040 TClassEdit::kDropAllDefault);
1041 }
1042 if (!m_clidsvc->getIDOfTypeInfoName(ti_typename, id)
1043 .isSuccess()) {
1044 ATH_MSG_INFO("** could not find a CLID from type-info ["
1045 << System::typeinfoName(*ti) << "]");
1046 ATH_MSG_INFO("** could not find a CLID from type-info-alias ["
1047 << ti_typename << "]");
1048 continue;
1049 }
1050 }
1051 } else {
1052 // probably a built-in type...
1053 TObjArray *leaves = branch->GetListOfLeaves();
1054 if (leaves &&
1055 leaves->GetEntries() == 1) {
1056 const std::string type_name = ((TLeaf*)leaves->At(0))->GetTypeName();
1057 if (!m_clidsvc->getIDOfTypeName(::root_typename(type_name), id)
1058 .isSuccess()) {
1059 ATH_MSG_INFO("** could not find a CLID for type-name ["
1060 << type_name << "]");
1061 continue;
1062 }
1063 }
1064 }
1065 if (id == 0) {
1066 ATH_MSG_INFO("** could not find a CLID for type-name ["
1067 << type_name << "]");
1068 continue;
1069 }
1070 CxxUtils::RefCountedPtr<Athena::RootBranchAddress> addr
1071 (new Athena::RootBranchAddress
1072 (ROOT_StorageType, id,
1073 tree_name,
1074 br_name,
1075 (unsigned long)(value_ptr),
1076 (unsigned long)(0)));
1077 if (!store->recordAddress(sg_key, std::move(addr), true).isSuccess()) {
1078 ATH_MSG_ERROR("could not record address at [" << sg_key << "] in store ["
1079 << store->name() << "]");
1080 }
1081 // SG::TransientAddress* taddr = new SG::TransientAddress
1082 // (id, sg_key, addr);
1083 // taddr->setProvider(this);
1084 // taddr->clearAddress(true);
1085 // tads.push_back(taddr);
1086 }
1087 }
1088 return StatusCode::SUCCESS;
1089}
#define ATH_MSG_ERROR(x)
uint32_t CLID
The Class ID type.
void record(const T *p, const std::string &key)
Definition TestStore.h:81
virtual const std::string & name() const override
Definition TestStore.cxx:97
TestStore store
Definition TestStore.cxx:23
TChain * tree

◆ createRootBranchAddresses()

StatusCode Athena::RootNtupleEventSelector::createRootBranchAddresses ( StoreID::type storeID,
tadList & tads )
private

helper method to create proxies

Definition at line 869 of file RootNtupleEventSelector.cxx.

871{
872 if (storeID != StoreID::EVENT_STORE) {
873 ATH_MSG_INFO("-- not the event-store --");
874 return(StatusCode::SUCCESS);
875 }
876
877 if (0 == m_tuple) {
878 ATH_MSG_ERROR("null pointer to n-tuple !");
879 return StatusCode::FAILURE;
880 }
881
882 TObjArray *leaves = m_tuple->GetListOfLeaves();
883 if (!leaves) {
884 ATH_MSG_INFO("no leaves!!");
885 return StatusCode::SUCCESS;
886 }
887
888 // loop over leaves
889 for (Int_t i = 0; i < leaves->GetEntries(); ++i) {
890 TLeaf *leaf = (TLeaf *)leaves->At(i);
891 TBranch *branch = leaf->GetBranch();
892 if (branch) {
893
894 CLID id = 0;
895 const void* value_ptr = m_tuple;
896 const std::string type_name = leaf->GetTypeName();
897 const std::string br_name = branch->GetName();
898 const std::string sg_key = br_name;//m_tupleName.value()+"/"+br_name;
899 TClass *cls = TClass::GetClass(type_name.c_str());
900 const std::type_info *ti = 0;
901
902 if (cls) {
903 ti = cls->GetTypeInfo();
904 // first, try to load a dict for that class...
905 if (ti) {
906 m_dictsvc->load_type(*ti);
907 }
908 if (!ti) {
909 ATH_MSG_WARNING("could not find a type-info for [" <<
910 type_name << "]");
911 continue;
912 }
913 std::string ti_typename = System::typeinfoName(*ti);
914 if (!m_clidsvc->getIDOfTypeInfoName(ti_typename, id)
915 .isSuccess()) {
916 // try another one...
917 {
918 // Protect against data race inside TClassEdit.
919 // https://github.com/root-project/root/issues/10353
920 // Should be fixed in root 6.26.02.
921 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
922 ti_typename = TClassEdit::ShortType(ti_typename.c_str(),
923 TClassEdit::kDropAllDefault);
924 }
925 if (!m_clidsvc->getIDOfTypeInfoName(ti_typename, id)
926 .isSuccess()) {
927 ATH_MSG_DEBUG("** could not find a CLID from type-info ["
928 << System::typeinfoName(*ti) << "]");
929 ATH_MSG_DEBUG("** could not find a CLID from type-info-alias ["
930 << ti_typename << "]");
931 continue;
932 }
933 }
934 } else {
935 // probably a built-in type...
936 if (!m_clidsvc->getIDOfTypeName(::root_typename(type_name), id)
937 .isSuccess()) {
938 ATH_MSG_DEBUG("** could not find a CLID for type-name ["
939 << type_name << "]");
940 continue;
941 }
942 }
943 if (id == 0) {
944 ATH_MSG_DEBUG("** could not find a CLID for type-name ["
945 << type_name << "]");
946 continue;
947 }
948 Athena::RootBranchAddress* addr = new Athena::RootBranchAddress
949 (ROOT_StorageType, id,
950 m_tuple->GetName(),
951 br_name,
952 (unsigned long)(value_ptr),
953 (unsigned long)(m_curEvt-1));
954
955 // recycle old rootaddress, if any.
956 SG::DataProxy* proxy = m_dataStore->proxy (id, sg_key);
957 if (proxy) {
958 proxy->setAddress (addr);
959 }
960 else {
961 auto taddr = new SG::TransientAddress(id, sg_key, addr, false);
962 taddr->setProvider(this, storeID);
963 // only add the *new* TransientAddress to the input list as the *old* ones
964 // are already tracked by the datastore (via the sticky proxies)
965 tads.push_back(taddr);
966 }
967 }
968 }
969 m_needReload = false;
970 // BeginInputFile is deferred to handle() on BeginEvent — see comment there.
971
972 return StatusCode::SUCCESS;
973}
#define ATH_MSG_DEBUG(x)
@ EVENT_STORE
Definition StoreID.h:26

◆ curEvent()

int Athena::RootNtupleEventSelector::curEvent ( const Context & refCtxt) const
overridevirtual

return the current event number.

Returns
The current event number.

Definition at line 752 of file RootNtupleEventSelector.cxx.

753{
754 return m_curEvt;
755}

◆ do_init_io()

StatusCode Athena::RootNtupleEventSelector::do_init_io ( )
private

helper method to init the i/o components

Definition at line 1221 of file RootNtupleEventSelector.cxx.

1222{
1223 // std::cout << "::fetchNtuple..." << std::endl;
1224
1225 // initialize some helper structures and data
1226 {
1227 CollMetaData zero;
1228 zero.min_entries = -1;
1229 zero.max_entries = -1;
1230 zero.entries = -1;
1231 m_collEvts.resize (m_tupleNames.size());
1232 for (size_t i = 0; i < m_collEvts.size(); i++) {
1233 m_collEvts[i].resize(m_inputCollectionsName.value().size(), zero);
1234 }
1235 }
1236
1237 m_tuple = fetchNtuple(m_inputCollectionsName.value()[0],
1238 m_tupleNames[0]);
1239 if (!m_tuple) {
1240 throw "RootNtupleEventSelector: Unable to fetch Ntuple";
1241 }
1242
1243 // std::cout << "::clear-root-addresses..." << std::endl;
1244 // reset the list of branches
1245 m_needReload = true;
1246
1247 // skip events we are asked to skip
1248 m_curEvt = m_skipEvts;
1249 m_nbrEvts = 0;
1250
1251 // std::cout << "::fetchNtuple...[done]" << std::endl;
1252 return StatusCode::SUCCESS;
1253}
TTree * fetchNtuple(const std::string &fname, const std::string &tupleName) const
helper method to retrieve the correct tuple
void zero(TH2 *h)
zero the contents of a 2d histogram

◆ endInputFile()

StatusCode Athena::RootNtupleEventSelector::endInputFile ( RootNtupleEventContext * rctx) const
private

Definition at line 431 of file RootNtupleEventSelector.cxx.

432{
433 // Fire EndInputFile via guard reset
434 m_inputFileGuard.reset();
435
436 // prepare for next file, if any...
437 // std::cout << "=========================================================="
438 // << std::endl;
439 // std::cerr << "::switch to next file...\n";
440
441 // iterate over proxies and
442 // mark as garbage and drop the RootBranchAddress (as a side effect of
443 // ::setAddress(NULL).
444 // this way, the next time we hit ::createRootBranchAddress or ::updateAddress
445 // all internal states are kosher.
446 for (const SG::DataProxy* cdp : m_dataStore->proxies()) {
447 if (dynamic_cast<Athena::RootBranchAddress*> (cdp->address()) != nullptr) {
448 if (SG::DataProxy* dp = m_dataStore->proxy_exact (cdp->sgkey())) {
449 dp->setAddress (nullptr);
450 }
451 }
452 }
453
454 const bool forceRemove = false;
455 CHECK( m_dataStore->clearStore(forceRemove) ); //must clear the storegate so that any tampering user did in EndInputFile incident is cleared
456 m_needReload = true;
457 // Defer BeginInputFile for the next file to the next BeginEvent.
458 // The actual file name is resolved in handle() from m_tuple.
459 m_fireBIF = true;
460
461 return StatusCode::SUCCESS;
462}
#define CHECK(...)
Evaluate an expression and check for errors.
bool m_fireBIF
Flag to fire BeginInputFile on the next BeginEvent incident.
std::optional< InputFileIncidentGuard > m_inputFileGuard
RAII guard: guarantees a matching EndInputFile for every BeginInputFile.

◆ fetchNtuple()

TTree * Athena::RootNtupleEventSelector::fetchNtuple ( const std::string & fname,
const std::string & tupleName ) const
private

helper method to retrieve the correct tuple

Definition at line 1092 of file RootNtupleEventSelector.cxx.

1094{
1095 // std::cout << "::fetchNtuple(" << fname << ")..." << std::endl;
1096 TTree* tree = NULL;
1097 RootGlobalsRestore rgr;
1098 // std::cout << "::TFile::Open()..." << std::endl;
1099 TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(fname.c_str());
1100 TFile* fnew = nullptr;
1101 if (!f) {
1102 f = TFile::Open(fname.c_str(), "READ");
1103 fnew = f;
1104 if (f) {
1105 f->SetName(fname.c_str());
1106 }
1107 }
1108 if (!f || f->IsZombie()) {
1109 ATH_MSG_ERROR("could not open next file in input collection ["
1110 << fname << "]");
1111 if (f) {
1112 f->Close();
1113 }
1114 return tree;
1115 }
1116 // std::cout << "::TFile::GetTree(" << m_tupleName << ")..." << std::endl;
1117 tree = (TTree*)f->Get(tupleName.c_str());
1118 if (!tree) {
1119 ATH_MSG_ERROR("could not retrieve tree [" << tupleName << "]"
1120 << " from file [" << fname << "]");
1121 f->Close();
1122 return tree;
1123 }
1124
1125 if (fnew)
1126 m_files.push_back(fnew);
1127
1128 // std::cout << "::TTree::SetBranchStatus()..." << std::endl;
1129 // disable all branches
1130 tree->SetBranchStatus("*", 0);
1131 if (!m_eventNumberVar.value().empty()) {
1132 tree->SetBranchStatus(m_eventNumberVar.value().c_str(), 1);
1133 }
1134 if (!m_runNumberVar.value().empty()) {
1135 tree->SetBranchStatus(m_runNumberVar.value().c_str(), 1);
1136 }
1137 if (!m_lbnVar.value().empty()) {
1138 tree->SetBranchStatus(m_lbnVar.value().c_str(), 1);
1139 }
1140
1141 if (!m_imetaStore->clearStore().isSuccess()) {
1142 ATH_MSG_INFO("could not clear store [" << m_imetaStore.typeAndName() << "]");
1143 return tree;
1144 }
1145
1146 addMetadataFromDirectoryName(tupleName+"Meta", f);
1147 addMetadataFromDirectoryName("Lumi", f, "Lumi");
1148 return tree;
1149}
void addMetadataFromDirectoryName(const std::string &metadirname, TFile *fileObj, const std::string &prefix="") const

◆ finalize()

StatusCode Athena::RootNtupleEventSelector::finalize ( )
overridevirtual

Definition at line 410 of file RootNtupleEventSelector.cxx.

411{
412 ATH_MSG_INFO ("Finalize...");
413 // FIXME: this should be tweaked/updated if/when a selection function
414 // or filtering predicate is applied (one day?)
415 ATH_MSG_INFO ("Total events read: " << (m_nbrEvts - m_skipEvts));
416
417 // Explicitly delete all the files we created.
418 // If we leave it up to root, then xrootd can get cleaned up before
419 // the root destructors run, leading to a crash.
420 for (TFile* f : m_files)
421 delete f;
422 m_files.clear();
423
424 return StatusCode::SUCCESS;
425}

◆ handle()

void Athena::RootNtupleEventSelector::handle ( const Incident & incident)
overridevirtual

Definition at line 1311 of file RootNtupleEventSelector.cxx.

1311 {
1312 if (m_fireBIF && incident.type() == IncidentType::BeginEvent) {
1313 std::string fname = m_tuple->GetCurrentFile()->GetName();
1315 fname, {},
1316 /*endFileName=*/fname);
1317 m_fireBIF = false;
1318 }
1319}
static InputFileIncidentGuard begin(IIncidentSvc &incSvc, std::string_view source, std::string_view beginFileName, std::string_view guid, std::string_view endFileName={}, std::string_view beginType=IncidentType::BeginInputFile, std::string_view endType=IncidentType::EndInputFile)
Factory: fire the begin incident and return a guard whose destructor fires the matching end incident.

◆ initialize()

StatusCode Athena::RootNtupleEventSelector::initialize ( )
overridevirtual

Definition at line 275 of file RootNtupleEventSelector.cxx.

276{
277 ATH_MSG_INFO ("Enter RootNtupleEventSelector initialization...");
278
279 // retrieve clidsvc
280 if ( !m_clidsvc.retrieve().isSuccess() ) {
282 ("Could not retrieve [" << m_clidsvc.typeAndName() << "]");
283 return StatusCode::FAILURE;
284 }
285
286 // retrieve dictsvc
287 if ( !m_dictsvc.retrieve().isSuccess() ) {
289 ("Could not retrieve [" << m_dictsvc.typeAndName() << "]");
290 return StatusCode::FAILURE;
291 }
292
293 m_tupleNames = CxxUtils::tokenize (m_tupleName.value(), " ;");
294
295 if ( m_tupleNames.empty() ) {
297 ("You have to give a TTree name to read from the ROOT files !");
298 return StatusCode::FAILURE;
299 }
300
301 CHECK( m_incsvc.retrieve() );
302 m_incsvc->addListener(this,IncidentType::BeginEvent,99); //used to trigger BeginInputFile on start of first event of file - 99 priority so AFTER storegatesvc done
303
304
305 setupInputCollection( m_inputCollectionsName );
306 const std::size_t nbrInputFiles = m_inputCollectionsName.value().size();
307 if ( nbrInputFiles < 1 ) {
309 ("You need to give at least 1 input file !!" << endmsg
310 << "(Got [" << nbrInputFiles << "] file instead !)");
311 return StatusCode::FAILURE;
312 } else {
314 ("Selector configured to read [" << nbrInputFiles << "] file(s)..."
315 << endmsg
316 << " TTree [" << m_tupleName.value() << "]");
317 }
318
319 {
320 // register this service for 'I/O' events
321 ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name());
322 if (!iomgr.retrieve().isSuccess()) {
323 ATH_MSG_FATAL("Could not retrieve IoComponentMgr !");
324 return StatusCode::FAILURE;
325 }
326 if (!iomgr->io_register(this).isSuccess()) {
327 ATH_MSG_FATAL("Could not register myself with the IoComponentMgr !");
328 return StatusCode::FAILURE;
329 }
330 // register input file's names with the I/O manager
331 const std::vector<std::string>& incol = m_inputCollectionsName.value();
332 bool allGood = true;
333 for (std::size_t icol = 0, imax = incol.size(); icol < imax; icol++) {
334 if (!iomgr->io_register(this,
335 IIoComponentMgr::IoMode::READ,
336 incol[icol]).isSuccess()) {
337 ATH_MSG_FATAL("could not register [" << incol[icol] << "] for output !");
338 allGood = false;
339 } else {
340 ATH_MSG_VERBOSE("io_register[" << this->name() << "](" << incol[icol] << ") [ok]");
341 }
342 }
343 if (!allGood) {
344 return StatusCode::FAILURE;
345 }
346 }
347
348 if (!do_init_io().isSuccess()) {
349 return StatusCode::FAILURE;
350 }
351 // retrieve event store
352 // this needs to happen *after* having initialized the i/o
353 // as our branches (which need a valid m_ntuple pointer)
354 // may be asked to be registered as we are a ProxyProvider.
355 // retrieving the event store will poke the ProxyProviderSvc...
356 /*
357 if ( !m_dataStore.retrieve().isSuccess() ) {
358 ATH_MSG_ERROR
359 ("Could not retrieve [" << m_dataStore.typeAndName() << "] !!");
360 return StatusCode::FAILURE;
361 }
362
363 // ditto for (input) meta data store
364 if (!m_imetaStore.retrieve().isSuccess()) {
365 ATH_MSG_ERROR
366 ("Could not retrieve [" << m_imetaStore.typeAndName() << "] !!");
367 return StatusCode::FAILURE;
368 }
369
370 // ditto for (output) meta data store
371 if (!m_ometaStore.retrieve().isSuccess()) {
372 ATH_MSG_ERROR
373 ("Could not retrieve [" << m_ometaStore.typeAndName() << "] !!");
374 return StatusCode::FAILURE;
375 }
376 */
377
378 //ensure the Athena::NtupleCnvSvc is in the EventPersistencySvc
379 ServiceHandle<IProperty> epSvc("EventPersistencySvc",name());
380 std::vector<std::string> propVal;
381 CHECK( Gaudi::Parsers::parse( propVal , epSvc->getProperty("CnvServices").toString() ) );
382 bool foundSvc(false);
383 for(const std::string& s : propVal) {
384 if(s=="Athena::xAODCnvSvc") { foundSvc=true; break; }
385 }
386 if(!foundSvc) {
387 propVal.push_back("Athena::NtupleCnvSvc");
388 CHECK( epSvc->setProperty("CnvServices", Gaudi::Utils::toString( propVal ) ));
389 }
390
391 //we should also add ourself as a proxy provider
392 ServiceHandle<IProxyProviderSvc> ppSvc("ProxyProviderSvc",name());
393 CHECK( ppSvc.retrieve() );
394 ppSvc->addProvider( this );
395
396
397
398 return StatusCode::SUCCESS;
399}
#define endmsg
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
int imax(int i, int j)
StatusCode do_init_io()
helper method to init the i/o components
std::vector< std::string > tokenize(std::string_view the_str, std::string_view delimiters)
Splits the string into smaller substrings.
StatusCode parse(std::tuple< Tup... > &tup, const Gaudi::Parsers::InputData &input)
bool allGood
Loop over the SDOs & Digits.

◆ io_reinit()

StatusCode Athena::RootNtupleEventSelector::io_reinit ( )
overridevirtual

Callback method to reinitialize the internal state of the component for I/O purposes (e.g.

upon fork(2))

Definition at line 760 of file RootNtupleEventSelector.cxx.

761{
762 ATH_MSG_INFO("I/O reinitialization...");
763
764 ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name());
765 if (!iomgr.retrieve().isSuccess()) {
766 ATH_MSG_FATAL("Could not retrieve IoComponentMgr !");
767 return StatusCode::FAILURE;
768 }
769 if (!iomgr->io_hasitem(this)) {
770 ATH_MSG_FATAL("IoComponentMgr does not know about myself !");
771 return StatusCode::FAILURE;
772 }
773 std::vector<std::string> inputCollections = m_inputCollectionsName.value();
774
775 for (std::size_t
776 i = 0,
777 imax = m_inputCollectionsName.value().size();
778 i < imax;
779 ++i) {
780 std::string &fname = inputCollections[i];
781 // std::cout << "--retrieve new name for [" << fname << "]...\n";
782 if (!iomgr->io_contains(this, fname)) {
783 ATH_MSG_ERROR("IoComponentMgr does not know about [" << fname << "] !");
784 return StatusCode::FAILURE;
785 }
786 if (!iomgr->io_retrieve(this, fname).isSuccess()) {
787 ATH_MSG_FATAL("Could not retrieve new value for [" << fname << "] !");
788 return StatusCode::FAILURE;
789 }
790 // std::cout << "--> [" << fname << "]\n" << std::flush;
791 }
792 // all good... copy over.
793 m_inputCollectionsName = inputCollections;
794
795 // remove our EventInfo if any...
796 // {
797 // const bool force_remove = true;
798 // if (!m_dataStore->clearStore(force_remove).isSuccess()) {
799 // ATH_MSG_ERROR("could not clear event store!");
800 // return StatusCode::FAILURE;
801 // } else {
802 // ATH_MSG_INFO("sgdump: \n" << m_dataStore->dump());
803 // }
804 // }
805
806 // std::cout << "--> do_init_io...\n" << std::flush;
807 if (!do_init_io().isSuccess()) {
808 return StatusCode::FAILURE;
809 }
810
811 ATH_MSG_INFO("I/O reinitialization... [done]");
812 return StatusCode::SUCCESS;
813}

◆ last()

StatusCode Athena::RootNtupleEventSelector::last ( Context & refContext) const
overridevirtual

Definition at line 647 of file RootNtupleEventSelector.cxx.

648{
649 ATH_MSG_ERROR ("............. Last Event Not Implemented .............");
650 return StatusCode::FAILURE;
651}

◆ loadAddresses()

StatusCode Athena::RootNtupleEventSelector::loadAddresses ( StoreID::type storeID,
tadList & list )
overridevirtual

get all new addresses from Provider for this Event.

Definition at line 831 of file RootNtupleEventSelector.cxx.

832{
833 if (m_needReload) {
834 return createRootBranchAddresses(storeID, tads);
835 }
836
837 return StatusCode::SUCCESS;
838}
StatusCode createRootBranchAddresses(StoreID::type storeID, tadList &tads)
helper method to create proxies

◆ next() [1/2]

virtual StatusCode Athena::RootNtupleEventSelector::next ( Context & refCtxt) const
overridevirtual

◆ next() [2/2]

StatusCode Athena::RootNtupleEventSelector::next ( Context & refCtxt,
int jump ) const
overridevirtual

Definition at line 624 of file RootNtupleEventSelector.cxx.

625{
626 ATH_MSG_DEBUG ("next(" << jump << ") : iEvt " << m_curEvt);
627
628 if (self()->seek(ctx, m_curEvt + jump).isSuccess()) {
629 return StatusCode::FAILURE;
630 }
631 return next(ctx);
632}
virtual StatusCode seek(Context &refCtxt, int evtnum) const override
Seek to a given event number.
virtual StatusCode next(Context &refCtxt) const override

◆ preLoadAddresses()

StatusCode Athena::RootNtupleEventSelector::preLoadAddresses ( StoreID::type storeID,
tadList & list )
overridevirtual

IAddressProvider interface get all addresses from Provider : Called before Begin Event

Definition at line 820 of file RootNtupleEventSelector.cxx.

822{
823 // std::cerr << "TTES::preLoadAddresses(" << int(storeID)
824 // << "," << tads.size()
825 // << ")...\n";
826 return StatusCode::SUCCESS;
827}

◆ previous() [1/2]

virtual StatusCode Athena::RootNtupleEventSelector::previous ( Context & refCtxt) const
overridevirtual

◆ previous() [2/2]

StatusCode Athena::RootNtupleEventSelector::previous ( Context & refCtxt,
int jump ) const
overridevirtual

Definition at line 641 of file RootNtupleEventSelector.cxx.

642{
643 return next( ctx, -jump );
644}

◆ releaseContext()

StatusCode Athena::RootNtupleEventSelector::releaseContext ( Context *& refCtxt) const
overridevirtual

Definition at line 677 of file RootNtupleEventSelector.cxx.

678{
679 RootNtupleEventContext *ctx = dynamic_cast<RootNtupleEventContext*>(refCtxt);
680 if ( ctx ) {
681 delete ctx; ctx = 0;
682 return StatusCode::SUCCESS;
683 }
684
685 return StatusCode::FAILURE;
686}

◆ resetCriteria()

StatusCode Athena::RootNtupleEventSelector::resetCriteria ( const std::string & cr,
Context & ctx ) const
overridevirtual

Definition at line 689 of file RootNtupleEventSelector.cxx.

690{
691 ATH_MSG_ERROR ("............. resetCriteria Not Implemented .............");
692 return StatusCode::FAILURE;
693}

◆ rewind()

StatusCode Athena::RootNtupleEventSelector::rewind ( Context & refCtxt) const
overridevirtual

Definition at line 655 of file RootNtupleEventSelector.cxx.

656{
657 return self()->seek(ctxt, 0);
658}

◆ seek()

StatusCode Athena::RootNtupleEventSelector::seek ( Context & ctx,
int evtnum ) const
overridevirtual

Seek to a given event number.

IEvtSelectorSeek interface

Parameters
evtnumThe event number to which to seek.
evtnumThe event number to which to seek.

Definition at line 704 of file RootNtupleEventSelector.cxx.

705{
706 RootNtupleEventContext* rctx = dynamic_cast<RootNtupleEventContext*>(&ctx);
707 if (!rctx) {
708 return StatusCode::FAILURE;
709 }
710
711 // std::cout << "::seek - evtnum=" << evtnum
712 // << " curevt=" << m_curEvt
713 // << " curcol=" << rctx->fileIndex()
714 // << std::endl;
715 long coll_idx, tuple_idx;
716 find_coll_idx(evtnum, coll_idx, tuple_idx);
717 // std::cout << "::seek - evtnum=" << evtnum
718 // << " curevt=" << m_curEvt
719 // << " curcol=" << rctx->fileIndex()
720 // << " colidx=" << coll_idx
721 // << std::endl;
722 if ((coll_idx == -1 || tuple_idx == -1) && evtnum < m_curEvt) {
723 coll_idx = rctx->fileIndex();
724 tuple_idx = rctx->tupleIndex();
725 }
726
727 if (coll_idx == -1 || tuple_idx == -1) {
728 ATH_MSG_INFO("seek: reached end of input.");
729 return StatusCode::RECOVERABLE;
730 }
731
732 if (coll_idx != static_cast<int>(rctx->fileIndex()) ||
733 tuple_idx != static_cast<int>(rctx->tupleIndex()))
734 {
735 // tell everyone we switched files...
736 m_tuple = NULL;
737 CHECK( endInputFile (rctx) );
738 }
739
740 rctx->setFileIndex (coll_idx);
741 rctx->setTupleIndex (tuple_idx);
742 m_curEvt = evtnum;
743
744 return StatusCode::SUCCESS;
745}
StatusCode endInputFile(RootNtupleEventContext *rctx) const
find_coll_idx(-1, coll_idx, tuple_idx)

◆ setupInputCollection()

void Athena::RootNtupleEventSelector::setupInputCollection ( Gaudi::Details::PropertyBase & inputCollectionsName)
private

callback to synchronize the list of input files

Definition at line 862 of file RootNtupleEventSelector.cxx.

863{
864 // nothing ?
865 return;
866}

◆ size()

virtual int Athena::RootNtupleEventSelector::size ( Context & refCtxt) const
overridevirtual

ICollectionSize interface

◆ stop()

StatusCode Athena::RootNtupleEventSelector::stop ( )
overridevirtual

Definition at line 401 of file RootNtupleEventSelector.cxx.

402{
403 // Fire EndInputFile for any file still open (the event loop may end
404 // before the file is fully read).
405 m_inputFileGuard.reset();
406 m_fireBIF = false;
407 return StatusCode::SUCCESS;
408}

◆ updateAddress()

StatusCode Athena::RootNtupleEventSelector::updateAddress ( StoreID::type storeID,
SG::TransientAddress * tad,
const EventContext & ctx )
overridevirtual

update a transient Address

Definition at line 842 of file RootNtupleEventSelector.cxx.

844{
845 if (tad) {
846 if (m_dataStore->proxy_exact (tad->sgkey())) {
847 return StatusCode::SUCCESS;
848 }
849 return StatusCode::FAILURE;
850 }
851 // do nothing.
852 return StatusCode::SUCCESS;
853}
sgkey_t sgkey() const
Set the primary (hashed) SG key.

◆ Athena::RootNtupleEventContext

friend class Athena::RootNtupleEventContext
friend

Definition at line 53 of file RootNtupleEventSelector.h.

Member Data Documentation

◆ m_collEvts

std::vector<std::vector<CollMetaData> > Athena::RootNtupleEventSelector::m_collEvts
mutableprivate

helper method to get the collection index (into m_inputCollectionsName) and tuple index (into m_tupleNames') for a given event index evtidx`.

returns -1 if not found. */ void find_coll_idx(int evtidx, long& coll_idx, long& tuple_idx) const;

/ non-const access to self (b/c ::next() is const) RootNtupleEventSelector self() const { return const_cast<RootNtupleEventSelector>(this); }

///////////////////////////////////////////////////////////////// Private data: ///////////////////////////////////////////////////////////////// private:

typedef ServiceHandle<StoreGateSvc> StoreGateSvc_t; / Pointer to the StoreGateSvc event store StoreGateSvc_t m_dataStore;

/ Pointer to the StoreGateSvc input metadata store StoreGateSvc_t m_imetaStore;

/ Pointer to the StoreGateSvc output metadata store StoreGateSvc_t m_ometaStore;

typedef ServiceHandle<IClassIDSvc> ICLIDSvc_t; / Pointer to the IClassIDSvc ICLIDSvc_t m_clidsvc;

typedef ServiceHandle<IDictLoaderSvc> IDictSvc_t; / Pointer to the IDictLoaderSvc IDictSvc_t m_dictsvc;

typedef ServiceHandle<IIncidentSvc> IIncSvc_t; / Handle to the incident service IIncSvc_t m_incsvc;

/ List of input files containing TTree StringArrayProperty m_inputCollectionsName;

/ Name of TTree to load from collection of input files StringProperty m_tupleName;

/ List of branches to activate in the TTree StringArrayProperty m_activeBranchNames;

/ optional event number variable to propagate to EventInfo. StringProperty m_eventNumberVar { this, "EventNumberVar", "", "Optional event number variable to propagate to EventInfo" }; / optional run number variable to propagate to EventInfo. StringProperty m_runNumberVar { this, "RunNumberVar", "", "Optional run number variable to propagate to EventInfo" }; / optional LBN variable to propagate to EventInfo. StringProperty m_lbnVar { this, "LBNVar", "", "Optional LBN variable to propagate to EventInfo" };

/ Number of events to skip at the beginning long m_skipEvts;

/ Names of all trees over which to iterate. std::vector<std::string> m_tupleNames;

/ Number of Events read so far. mutable long m_nbrEvts;

/ current event index mutable long m_curEvt;

struct CollMetaData { / number of entries up to this collection long min_entries; / number of entries after this collection long max_entries; / number of entries in this collection. long entries; }; /** cache of the number of entries for each collection Indexed like [tuple][collection]

Definition at line 252 of file RootNtupleEventSelector.h.

◆ m_files

std::vector<TFile*> Athena::RootNtupleEventSelector::m_files
mutableprivate

Definition at line 278 of file RootNtupleEventSelector.h.

◆ m_fireBIF

bool Athena::RootNtupleEventSelector::m_fireBIF {true}
mutableprivate

Flag to fire BeginInputFile on the next BeginEvent incident.

Definition at line 269 of file RootNtupleEventSelector.h.

269{true};

◆ m_inputFileGuard

std::optional<InputFileIncidentGuard> Athena::RootNtupleEventSelector::m_inputFileGuard
mutableprivate

RAII guard: guarantees a matching EndInputFile for every BeginInputFile.

BeginInputFile is deferred to the next BeginEvent (data must be loaded in the store first), so the guard is created in handle(), not immediately.

Definition at line 267 of file RootNtupleEventSelector.h.

◆ m_needReload

bool Athena::RootNtupleEventSelector::m_needReload
mutableprivate

The (python) selection function to apply on the TChain we are reading.

Definition at line 262 of file RootNtupleEventSelector.h.

◆ m_tuple

TTree* Athena::RootNtupleEventSelector::m_tuple
mutableprivate

current tree being read

Definition at line 255 of file RootNtupleEventSelector.h.


The documentation for this class was generated from the following files: