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
9
10#include <ranges>
11namespace {
12 // Erase all objects from the branch vector
13 void Remove(std::vector<MuonVal::IMuonTesterBranch*>& vec, std::function<bool(const MuonVal::IMuonTesterBranch*)> remove_func) {
14 // Could use std::erase_if with C++20...
15 auto [begin, end] = std::ranges::remove_if(vec, std::move(remove_func));
16 vec.erase(begin, end);
17 }
18
19} // namespace
20namespace MuonVal {
21
22std::string MuonTesterTree::name() const { return m_tree->GetName(); }
23
24TTree* MuonTesterTree::tree() { return m_tree.get(); }
25TTree* MuonTesterTree::operator->() { return m_tree.get(); }
26const TTree* MuonTesterTree::tree() const { return m_tree.get(); }
27const TTree* MuonTesterTree::operator->() const { return m_tree.get(); }
28
29
30bool MuonTesterTree::registerBranch(std::shared_ptr<IMuonTesterBranch> branch) {
31 if (!branch) {
32 ATH_MSG_ERROR("Nullptr given");
33 return false;
34 }
36 if (branch->tree() != tree()) {
37 for (const FriendTreePtr& friend_tree : getFriends()){
38 if (friend_tree->registerBranch(branch)) {
39 m_branches.push_back(std::move(branch));
40 return true;
41 }
42 }
43 return false;
44 }
45 std::vector<std::shared_ptr<IMuonTesterBranch>>::const_iterator itr = std::find_if(
46 m_branches.begin(), m_branches.end(),
47 [&branch](const std::shared_ptr<IMuonTesterBranch>& known) {
48 return known == branch || known->name() == branch->name();
49 });
50 if (itr != m_branches.end()) {
51 if (typeid((*itr).get()) != typeid(branch.get())) {
52 ATH_MSG_FATAL("Different branches have been added here under " << branch->name());
53 return false;
54 }
55 return true;
56 } else if (m_filled) {
57 ATH_MSG_FATAL("Tree structure is already finalized");
58 return false;
59 }
60 m_branches.push_back(std::move(branch));
61 return true;
62}
63bool MuonTesterTree::addBranch(std::shared_ptr<IMuonTesterBranch> branch) { return registerBranch(branch) && addBranch(branch.get()); }
64bool MuonTesterTree::addBranch(IMuonTesterBranch& branch) { return addBranch(&branch); }
66 if (isActive(branch))
67 return true;
68 else if (!branch) {
69 ATH_MSG_ERROR("Nullptr given");
70 return false;
71 } else if (m_filled) {
72 ATH_MSG_ERROR("Tree structure is already finalized. Cannot add " << branch->name());
73 return false;
74 }
75 if (branch->tree() != tree()) {
76 for (const FriendTreePtr& friend_tree : getFriends()) {
77 if (friend_tree->addBranch(branch)) return true;
78 }
79 return false;
80 }
81 m_branches_to_init.push_back(branch);
82 return true;
83}
84
86 Remove(m_branches_to_init, [branch](const IMuonTesterBranch* br) { return br == branch; });
87}
89
90bool MuonTesterTree::initialized() const { return m_init; }
91bool MuonTesterTree::fill(const EventContext& ctx) {
92 if (!initialized()) {
93 ATH_MSG_ERROR("The TTree has not been initialized yet");
94 return false;
95 }
97 if (!m_filled) {
98 m_excludedBranches.clear();
99 m_initialized_br.clear();
100 m_dependencies.clear();
101 }
103 if (isCommonTree() && m_hash_br->is_dumped(ctx)) {
104 return true;
105 }
107 for (const FriendTreePtr& friend_tree : getFriends()){
108 if (!friend_tree->fill(ctx)) return false;
109 }
111 for (auto& branch : m_branches_to_init) {
112 ATH_MSG_VERBOSE("Try to fill "<<branch->name());
113 if (!branch->fill(ctx)) {
114 ATH_MSG_ERROR("fill() --- Failed to fill branch " << branch->name() << " in tree " << name() );
115 return false;
116 }
117 }
118 m_tree->Fill();
119 m_filled = true;
120 return true;
121}
122StatusCode MuonTesterTree::init(const ServiceHandle<ITHistSvc> & hist_svc) {
123 if (fileStream().empty()) {
124 ATH_MSG_ERROR("The file stream of " << name() << " has not been set yet" );
125 return StatusCode::FAILURE;
126 }
127 if (!initialized()) {
128 if (!m_tree) {
129 ATH_MSG_FATAL("No TTree object");
130 return StatusCode::FAILURE;
131 }
133 std::stringstream full_path{};
134 full_path<<"/"<<fileStream()<<"/"<<path()<<(path().empty() ? "" : "/")<<name();
135 if (!hist_svc->regTree(full_path.str(), tree()).isSuccess()) { return StatusCode::FAILURE; }
136 m_directory = m_tree->GetDirectory();
137 if (!m_directory) {
138 ATH_MSG_ERROR("Where is my directory to write later?");
139 return StatusCode::FAILURE;
140 }
141 m_hist_svc = hist_svc;
142 m_init = true;
143 }
144 for (const FriendTreePtr& friend_tree : getFriends()){
145 if (!friend_tree->init(hist_svc).isSuccess()) return StatusCode::FAILURE;
146 }
147
148 Remove(m_branches_to_init, [this](const IMuonTesterBranch* br) {
149 return !br || m_excludedBranches.count(br->name());
150 });
153 [](IMuonTesterBranch* a, IMuonTesterBranch* b) { return a->name() < b->name(); });
154 for (IMuonTesterBranch* branch : m_branches_to_init) {
155 if (m_initialized_br.count(branch)) {
156 ATH_MSG_VERBOSE("Do not count the initialize function on "<<branch->name()<<" twice.");
157 continue;
158 }
159 if (!branch->init()) {
160 ATH_MSG_ERROR("Failed to initialize branch " << branch->name());
161 return StatusCode::FAILURE;
162 }
163 ATH_MSG_DEBUG(" Branch " << branch->name() << " has been initialized");
164 std::vector<DataDependency> data_dep = branch->data_dependencies();
165 for (const DataDependency& data : data_dep) {
166 m_dependencies.emplace_back(data);
167 }
168 m_initialized_br.insert(branch);
169 }
171 Remove(m_branches_to_init, [this](const IMuonTesterBranch* br) {
172 return std::find_if(m_branches.begin(), m_branches.end(),
173 [br](const std::shared_ptr<IMuonTesterBranch>& owned) {
174 return owned.get() == br; }) == m_branches.end();
175 });
176 ATH_MSG_INFO("Initialization of "<<name()<<" successfully completed");
177 return StatusCode::SUCCESS;
178}
179
180void MuonTesterTree::setFileStream(const std::string& new_stream) {
181 if (isCommonTree() || initialized()) {
182 ATH_MSG_WARNING("Cannot change file stream");
183 return;
184 }
185 ATH_MSG_DEBUG("Update stream "<<m_stream<<" to "<<new_stream);
186 m_stream = new_stream;
187
188}
190 if (!initialized() || !m_tree || m_written) { return StatusCode::SUCCESS; }
191 if (!m_hist_svc->deReg(tree()).isSuccess()) {
192 ATH_MSG_ERROR(__func__<<"() --- Failed to put the tree "<<name()<<" out of the HistService");
193 return StatusCode::FAILURE;
194 }
195 for (const FriendTreePtr& friend_tree : getFriends()) {
196 if (!friend_tree->write().isSuccess()) return StatusCode::FAILURE;
197 if (!tree()->AddFriend(friend_tree->tree())) {
198 ATH_MSG_ERROR("Failed to establish the Friendship between "<<name()<<" & "<<friend_tree->tree());
199 return StatusCode::FAILURE;
200 }
201 }
202 m_directory->WriteObject(tree(), tree()->GetName(), "overwrite");
203 if (!isCommonTree()) m_tree.reset();
204 m_branches_to_init.clear();
205 m_branches.clear();
206 m_friendLinks.clear();
207 m_written = true;
208 return StatusCode::SUCCESS;
209}
210void MuonTesterTree::disableBranch(const std::string& b_name) {
211 if (!m_filled) m_excludedBranches.insert(b_name);
212}
213void MuonTesterTree::disableBranch(const std::vector<std::string>& br_names) {
214 if (!m_filled) m_excludedBranches.insert(br_names.begin(), br_names.end());
215}
216const std::string& MuonTesterTree::fileStream() const { return m_stream; }
218 if (!branch) {
219 ATH_MSG_ERROR("Nullptr was given");
220 return false;
221 }
222 if (branch->tree() != tree()) {
223 for (const FriendTreePtr& friend_tree : getFriends()){
224 if (friend_tree->isActive(branch)) return true;
225 }
226 return false;
227 }
228 return std::find_if(m_branches_to_init.begin(), m_branches_to_init.end(),
229 [&branch](const IMuonTesterBranch* known) {
230 return known == branch || known->name() == branch->name();
231 }) != m_branches_to_init.end();
232}
233void MuonTesterTree::setPath(const std::string& new_path) { m_path = new_path; }
234const std::string& MuonTesterTree::path() const { return m_path; }
235
237 if (Gaudi::Concurrency::ConcurrencyFlags::numThreads() > 1) {
238 ATH_MSG_WARNING("Common TTree mechanism only supported in single thread environment");
239 return false;
240 }
241 if (!m_hash_br) {
242 m_hash_br = std::make_shared<EventHashBranch>(tree());
243 if (!addBranch(m_hash_br)) return false;
244 }
245 m_commonClients.insert(client);
246 return true;
247}
249 if (Gaudi::Concurrency::ConcurrencyFlags::numThreads() > 1) {
250 ATH_MSG_WARNING("Common TTree mechanism only supported in single thread environment");
251 return false;
252 }
253 if (!common_tree) {
254 ATH_MSG_ERROR("Nullptr given");
255 return false;
256 }
257 if (common_tree->fileStream() != fileStream()) {
258 ATH_MSG_ERROR("The common tree "<<common_tree->name()<<" and "<<name()<<" have to be written into the same file");
259 return false;
260 }
261 if (m_commonClients.count(common_tree.get())) {
262 ATH_MSG_ERROR(name()<<" is already a friend of "<<common_tree->name());
263 return false;
264 }
266 if (!m_hash_br) {
267 m_hash_br = std::make_shared<EventHashBranch>(tree());
268 if (!addBranch(m_hash_br)) return false;
269 }
270 m_friendLinks.push_back(common_tree);
271 return common_tree->addClient(this);
272}
273const std::vector<MuonTesterTree::FriendTreePtr>& MuonTesterTree::getFriends() const {
274 return m_friendLinks;
275}
276bool MuonTesterTree::isCommonTree() const {return !m_commonClients.empty(); }
277
278MuonTesterTree::MuonTesterTree(const std::string& tree_name, const std::string& stream) :
279 AthMessaging{"MuonTesterTree"},
280 m_tree{std::make_unique<TTree>(tree_name.c_str(), "MuonTesterTree")}, m_stream(stream) {}
281
285}
#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
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.
virtual std::string name() const =0
Returns the name of the branch.
virtual TTree * tree()=0
Returns the pointer to the underlying TTree object.
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.
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.
void setFileStream(const std::string &new_stream)
Set the file stream post creation.
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.
StatusCode init(OWNER *instance)
Initialize method.
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.