ATLAS Offline Software
Loading...
Searching...
No Matches
MuonTesterTree.cxx
Go to the documentation of this file.
1/*
2Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
7#include <GaudiKernel/ConcurrencyFlags.h>
8
9namespace {
10 // Erase all objects from the branch vector
11 void Remove(std::vector<MuonVal::IMuonTesterBranch*>& vec, std::function<bool(const MuonVal::IMuonTesterBranch*)> remove_func) {
12 // Could use std::erase_if with C++20...
13 std::vector<MuonVal::IMuonTesterBranch*>::iterator itr = std::remove_if(vec.begin(), vec.end(), std::move(remove_func));
14 vec.erase (itr, vec.end());
15 }
16
17} // namespace
18namespace MuonVal {
19
20std::string MuonTesterTree::name() const { return m_tree->GetName(); }
21
22TTree* MuonTesterTree::tree() { return m_tree.get(); }
23TTree* MuonTesterTree::operator->() { return m_tree.get(); }
24const TTree* MuonTesterTree::tree() const { return m_tree.get(); }
25const TTree* MuonTesterTree::operator->() const { return m_tree.get(); }
26
27
28bool MuonTesterTree::registerBranch(std::shared_ptr<IMuonTesterBranch> branch) {
29 if (!branch) {
30 ATH_MSG_ERROR("Nullptr given");
31 return false;
32 }
34 if (branch->tree() != tree()) {
35 for (const FriendTreePtr& friend_tree : getFriends()){
36 if (friend_tree->registerBranch(branch)) {
37 m_branches.push_back(std::move(branch));
38 return true;
39 }
40 }
41 return false;
42 }
43 std::vector<std::shared_ptr<IMuonTesterBranch>>::const_iterator itr = std::find_if(
44 m_branches.begin(), m_branches.end(),
45 [&branch](const std::shared_ptr<IMuonTesterBranch>& known) {
46 return known == branch || known->name() == branch->name();
47 });
48 if (itr != m_branches.end()) {
49 if (typeid((*itr).get()) != typeid(branch.get())) {
50 ATH_MSG_FATAL("Different branches have been added here under " << branch->name());
51 return false;
52 }
53 return true;
54 } else if (m_filled) {
55 ATH_MSG_FATAL("Tree structure is already finalized");
56 return false;
57 }
58 m_branches.push_back(std::move(branch));
59 return true;
60}
61bool MuonTesterTree::addBranch(std::shared_ptr<IMuonTesterBranch> branch) { return registerBranch(branch) && addBranch(branch.get()); }
62bool MuonTesterTree::addBranch(IMuonTesterBranch& branch) { return addBranch(&branch); }
64 if (isActive(branch))
65 return true;
66 else if (!branch) {
67 ATH_MSG_ERROR("Nullptr given");
68 return false;
69 } else if (m_filled) {
70 ATH_MSG_ERROR("Tree structure is already finalized. Cannot add " << branch->name());
71 return false;
72 }
73 if (branch->tree() != tree()) {
74 for (const FriendTreePtr& friend_tree : getFriends()) {
75 if (friend_tree->addBranch(branch)) return true;
76 }
77 return false;
78 }
79 m_branches_to_init.push_back(branch);
80 return true;
81}
82
84 Remove(m_branches_to_init, [branch](const IMuonTesterBranch* br) { return br == branch; });
85}
87
88bool MuonTesterTree::initialized() const { return m_init; }
89bool MuonTesterTree::fill(const EventContext& ctx) {
90 if (!initialized()) {
91 ATH_MSG_ERROR("The TTree has not been initialized yet");
92 return false;
93 }
95 if (!m_filled) {
96 m_excludedBranches.clear();
97 m_initialized_br.clear();
98 m_dependencies.clear();
99 }
101 if (isCommonTree() && m_hash_br->is_dumped(ctx)) {
102 return true;
103 }
105 for (const FriendTreePtr& friend_tree : getFriends()){
106 if (!friend_tree->fill(ctx)) return false;
107 }
109 for (auto& branch : m_branches_to_init) {
110 ATH_MSG_VERBOSE("Try to fill "<<branch->name());
111 if (!branch->fill(ctx)) {
112 ATH_MSG_ERROR("fill() --- Failed to fill branch " << branch->name() << " in tree " << name() );
113 return false;
114 }
115 }
116 m_tree->Fill();
117 m_filled = true;
118 return true;
119}
121 if (fileStream().empty()) {
122 ATH_MSG_ERROR("The file stream of " << name() << " has not been set yet" );
123 return StatusCode::FAILURE;
124 }
125 if (!initialized()) {
126 if (!m_tree) {
127 ATH_MSG_FATAL("No TTree object");
128 return StatusCode::FAILURE;
129 }
131 std::stringstream full_path{};
132 full_path<<"/"<<fileStream()<<"/"<<path()<<(path().empty() ? "" : "/")<<name();
133 if (!hist_svc->regTree(full_path.str(), tree()).isSuccess()) { return StatusCode::FAILURE; }
134 m_directory = m_tree->GetDirectory();
135 if (!m_directory) {
136 ATH_MSG_ERROR("Where is my directory to write later?");
137 return StatusCode::FAILURE;
138 }
139 m_hist_svc = hist_svc;
140 m_init = true;
141 }
142 for (const FriendTreePtr& friend_tree : getFriends()){
143 if (!friend_tree->init(hist_svc).isSuccess()) return StatusCode::FAILURE;
144 }
145
146 Remove(m_branches_to_init, [this](const IMuonTesterBranch* br) {
147 return !br || m_excludedBranches.count(br->name());
148 });
151 [](IMuonTesterBranch* a, IMuonTesterBranch* b) { return a->name() < b->name(); });
152 for (IMuonTesterBranch* branch : m_branches_to_init) {
153 if (m_initialized_br.count(branch)) {
154 ATH_MSG_VERBOSE("Do not count the initialize function on "<<branch->name()<<" twice.");
155 continue;
156 }
157 if (!branch->init()) {
158 ATH_MSG_ERROR("Failed to initialize branch " << branch->name());
159 return StatusCode::FAILURE;
160 }
161 ATH_MSG_DEBUG(" Branch " << branch->name() << " has been initialized");
162 std::vector<DataDependency> data_dep = branch->data_dependencies();
163 for (const DataDependency& data : data_dep) {
164 m_dependencies.emplace_back(data);
165 }
166 m_initialized_br.insert(branch);
167 }
169 Remove(m_branches_to_init, [this](const IMuonTesterBranch* br) {
170 return std::find_if(m_branches.begin(), m_branches.end(),
171 [br](const std::shared_ptr<IMuonTesterBranch>& owned) {
172 return owned.get() == br; }) == m_branches.end();
173 });
174 ATH_MSG_INFO("Initialization of "<<name()<<" successfully completed");
175 return StatusCode::SUCCESS;
176}
177
179 if (!initialized() || !m_tree || m_written) { return StatusCode::SUCCESS; }
180 if (!m_hist_svc->deReg(tree()).isSuccess()) {
181 ATH_MSG_ERROR(__func__<<"() --- Failed to put the tree "<<name()<<" out of the HistService");
182 return StatusCode::FAILURE;
183 }
184 for (const FriendTreePtr& friend_tree : getFriends()) {
185 if (!friend_tree->write().isSuccess()) return StatusCode::FAILURE;
186 if (!tree()->AddFriend(friend_tree->tree())) {
187 ATH_MSG_ERROR("Failed to establish the Friendship between "<<name()<<" & "<<friend_tree->tree());
188 return StatusCode::FAILURE;
189 }
190 }
191 m_directory->WriteObject(tree(), tree()->GetName(), "overwrite");
192 if (!isCommonTree()) m_tree.reset();
193 m_branches_to_init.clear();
194 m_branches.clear();
195 m_friendLinks.clear();
196 m_written = true;
197 return StatusCode::SUCCESS;
198}
199void MuonTesterTree::disableBranch(const std::string& b_name) {
200 if (!m_filled) m_excludedBranches.insert(b_name);
201}
202void MuonTesterTree::disableBranch(const std::vector<std::string>& br_names) {
203 if (!m_filled) m_excludedBranches.insert(br_names.begin(), br_names.end());
204}
205const std::string& MuonTesterTree::fileStream() const { return m_stream; }
207 if (!branch) {
208 ATH_MSG_ERROR("Nullptr was given");
209 return false;
210 }
211 if (branch->tree() != tree()) {
212 for (const FriendTreePtr& friend_tree : getFriends()){
213 if (friend_tree->isActive(branch)) return true;
214 }
215 return false;
216 }
217 return std::find_if(m_branches_to_init.begin(), m_branches_to_init.end(),
218 [&branch](const IMuonTesterBranch* known) {
219 return known == branch || known->name() == branch->name();
220 }) != m_branches_to_init.end();
221}
222void MuonTesterTree::setPath(const std::string& new_path) { m_path = new_path; }
223const std::string& MuonTesterTree::path() const { return m_path; }
224
226 if (Gaudi::Concurrency::ConcurrencyFlags::numThreads() > 1) {
227 ATH_MSG_WARNING("Common TTree mechanism only supported in single thread environment");
228 return false;
229 }
230 if (!m_hash_br) {
231 m_hash_br = std::make_shared<EventHashBranch>(tree());
232 if (!addBranch(m_hash_br)) return false;
233 }
234 m_commonClients.insert(client);
235 return true;
236}
238 if (Gaudi::Concurrency::ConcurrencyFlags::numThreads() > 1) {
239 ATH_MSG_WARNING("Common TTree mechanism only supported in single thread environment");
240 return false;
241 }
242 if (!common_tree) {
243 ATH_MSG_ERROR("Nullptr given");
244 return false;
245 }
246 if (common_tree->fileStream() != fileStream()) {
247 ATH_MSG_ERROR("The common tree "<<common_tree->name()<<" and "<<name()<<" have to be written into the same file");
248 return false;
249 }
250 if (m_commonClients.count(common_tree.get())) {
251 ATH_MSG_ERROR(name()<<" is already a friend of "<<common_tree->name());
252 return false;
253 }
255 if (!m_hash_br) {
256 m_hash_br = std::make_shared<EventHashBranch>(tree());
257 if (!addBranch(m_hash_br)) return false;
258 }
259 m_friendLinks.push_back(common_tree);
260 return common_tree->addClient(this);
261}
262const std::vector<MuonTesterTree::FriendTreePtr>& MuonTesterTree::getFriends() const {
263 return m_friendLinks;
264}
265bool MuonTesterTree::isCommonTree() const {return !m_commonClients.empty(); }
266
267MuonTesterTree::MuonTesterTree(const std::string& tree_name, const std::string& stream) :
268 AthMessaging{"MuonTesterTree"},
269 m_tree{std::make_unique<TTree>(tree_name.c_str(), "MuonTesterTree")}, m_stream(stream) {}
270
274}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< size_t > vec
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t a
static const Attributes_t empty
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
Most basic interface class used by the MuonTester tree.
std::set< std::string > m_excludedBranches
bool m_init
Flag to avoid double initialization with the StoreGate.
IMuonTesterBranch::DataDependency DataDependency
const std::vector< FriendTreePtr > & getFriends() const
std::vector< std::shared_ptr< IMuonTesterBranch > > m_branches
std::set< MuonTesterTree * > m_commonClients
List of all other MuonTesterTree instances using this instance as a common Tree If the Tree has one c...
std::vector< IMuonTesterBranch * > m_branches_to_init
bool registerBranch(std::shared_ptr< IMuonTesterBranch > branch)
This method adds the branch to the tree and hands over the ownership to the MuonAnalysisTree instance...
MuonTesterTree(const std::string &tree_name, const std::string &stream)
bool fill(const EventContext &ctx)
Fills the tree per call.
bool addBranch(std::shared_ptr< IMuonTesterBranch > branch)
Branch is added to the tree without transferring the ownership.
TTree * operator->()
Operator to the TTree object.
StatusCode init(OWNER *instance)
Initialize method.
ServiceHandle< ITHistSvc > m_hist_svc
void removeBranch(IMuonTesterBranch *branch)
In case instances of a certain branch type are destroyed before hand.
void disableBranch(const std::string &br_name)
Skips the branch from being added to the tree.
bool addClient(MuonTesterTree *client)
Adds the other TTree as a Client and declares this instance as a Common Tree.
bool initialized() const
Has the init method been called and the tree is connected with the output file.
bool m_written
Flag to indicate whether the TTree is written to the file or not.
std::shared_ptr< MuonTesterTree > FriendTreePtr
Appends the other tester Tree as friend to this instance.
void setPath(const std::string &new_path)
Save the TTree in a subfolder of the TFile.
std::vector< FriendTreePtr > m_friendLinks
List of all other common instances that are acting as friends.
const std::string & path() const
sub directory in the TFile
bool addCommonTree(FriendTreePtr common_tree)
std::unique_ptr< TTree > m_tree
bool isActive(const IMuonTesterBranch *branch) const
Returns a boolean whether the branch is already part of the tree or one of the deligated friends.
std::vector< DataDependency > m_dependencies
std::string name() const
Name of the tree.
const std::string & fileStream() const
file_stream of the analysis to which the tree belongs
StatusCode write()
Finally write the TTree objects.
std::shared_ptr< EventHashBranch > m_hash_br
TTree * tree()
TTree object.
bool isCommonTree() const
Returns Whether the Tree is a common tree or not.
std::set< IMuonTesterBranch * > m_initialized_br
Set of branches that were already initialized.
Class to store array like branches into the n-tuples.
Definition HitValAlg.cxx:19
STL namespace.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.