ATLAS Offline Software
MuonTesterTree.cxx
Go to the documentation of this file.
1 /*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
7 #include <GaudiKernel/ConcurrencyFlags.h>
8 
9 namespace {
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...
14  vec.erase (itr, vec.end());
15  }
16 
17 } // namespace
18 namespace MuonVal {
19 
20 std::string MuonTesterTree::name() const { return m_tree->GetName(); }
21 
22 TTree* MuonTesterTree::tree() { return m_tree.get(); }
23 TTree* MuonTesterTree::operator->() { return m_tree.get(); }
24 const TTree* MuonTesterTree::tree() const { return m_tree.get(); }
25 const TTree* MuonTesterTree::operator->() const { return m_tree.get(); }
26 
27 
28 bool 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(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(branch);
59  return true;
60 }
61 bool MuonTesterTree::addBranch(std::shared_ptr<IMuonTesterBranch> branch) { return registerBranch(branch) && addBranch(branch.get()); }
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 
88 bool MuonTesterTree::initialized() const { return m_init; }
89 bool 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  });
150  std::sort(m_branches_to_init.begin(), m_branches_to_init.end(),
151  [](IMuonTesterBranch* a, IMuonTesterBranch* b) { return a->name() < b->name(); });
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 }
199 void MuonTesterTree::disableBranch(const std::string& b_name) {
200  if (!m_filled) m_excludedBranches.insert(b_name);
201 }
202 void MuonTesterTree::disableBranch(const std::vector<std::string>& br_names) {
203  if (!m_filled) m_excludedBranches.insert(br_names.begin(), br_names.end());
204 }
205 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 }
222 void MuonTesterTree::setPath(const std::string& new_path) { m_path = new_path; }
223 std::string MuonTesterTree::path() const { return m_path; }
224 
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 }
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 }
262 const std::vector<MuonTesterTree::FriendTreePtr>& MuonTesterTree::getFriends() const {
263  return m_friendLinks;
264 }
265 bool MuonTesterTree::isCommonTree() const {return !m_commonClients.empty(); }
266 
267 MuonTesterTree::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 
272  m_branches_to_init.clear();
273 }
274 }
MuonVal::MuonTesterTree::m_branches
std::vector< std::shared_ptr< IMuonTesterBranch > > m_branches
Definition: MuonTesterTree.h:145
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
MuonVal::MuonTesterTree::initialized
bool initialized() const
Has the init method been called and the tree is connected with the output file.
Definition: MuonTesterTree.cxx:88
MuonVal::MuonTesterTree::m_filled
bool m_filled
Definition: MuonTesterTree.h:152
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
MuonVal::MuonTesterTree::m_init
bool m_init
Flag to avoid double initialization with the StoreGate.
Definition: MuonTesterTree.h:131
MuonVal::MuonTesterTree::m_written
bool m_written
Flag to indicate whether the TTree is written to the file or not.
Definition: MuonTesterTree.h:133
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
MuonVal::MuonTesterTree::FriendTreePtr
std::shared_ptr< MuonTesterTree > FriendTreePtr
Appends the other tester Tree as friend to this instance.
Definition: MuonTesterTree.h:109
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
MuonVal::MuonTesterTree::init
StatusCode init(OWNER *instance)
Initialize method.
AthMsgStreamMacros.h
MuonVal::MuonTesterTree::MuonTesterTree
MuonTesterTree(const std::string &tree_name, const std::string &stream)
Definition: MuonTesterTree.cxx:267
MuonVal::MuonTesterTree::~MuonTesterTree
~MuonTesterTree()
Definition: MuonTesterTree.cxx:271
MuonVal::MuonTesterTree::isActive
bool isActive(const IMuonTesterBranch *branch) const
Returns a boolean whether the branch is already part of the tree or one of the deligated friends.
Definition: MuonTesterTree.cxx:206
MuonVal::MuonTesterTree::registerBranch
bool registerBranch(std::shared_ptr< IMuonTesterBranch > branch)
This method adds the branch to the tree and hands over the ownership to the MuonAnalysisTree instance...
Definition: MuonTesterTree.cxx:28
MuonVal::MuonTesterTree::operator->
TTree * operator->()
Operator to the TTree object.
Definition: MuonTesterTree.cxx:23
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
MuonTesterTree.h
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
MuonVal::MuonTesterTree::fileStream
std::string fileStream() const
file_stream of the analysis to which the tree belongs
Definition: MuonTesterTree.cxx:205
EventHashBranch.h
MuonVal::MuonTesterTree::addClient
bool addClient(MuonTesterTree *client)
Adds the other TTree as a Client and declares this instance as a Common Tree.
Definition: MuonTesterTree.cxx:225
MuonVal::MuonTesterTree::m_tree
std::unique_ptr< TTree > m_tree
Definition: MuonTesterTree.h:127
empty
bool empty(TH1 *h)
Definition: computils.cxx:294
AthenaPoolTestWrite.stream
string stream
Definition: AthenaPoolTestWrite.py:12
MuonVal::MuonTesterTree::m_directory
TDirectory * m_directory
Definition: MuonTesterTree.h:151
rerun_display.client
client
Definition: rerun_display.py:31
MuonVal::MuonTesterTree::m_branches_to_init
std::vector< IMuonTesterBranch * > m_branches_to_init
Definition: MuonTesterTree.h:143
MuonVal::MuonTesterTree::isCommonTree
bool isCommonTree() const
Returns Whether the Tree is a common tree or not.
Definition: MuonTesterTree.cxx:265
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
MuonVal::MuonTesterTree
Definition: MuonTesterTree.h:30
MuonVal::MuonTesterTree::disableBranch
void disableBranch(const std::string &br_name)
Skips the branch from being added to the tree.
Definition: MuonTesterTree.cxx:199
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MuonVal::MuonTesterTree::m_commonClients
std::set< MuonTesterTree * > m_commonClients
List of all other MuonTesterTree instances using this instance as a common Tree If the Tree has one c...
Definition: MuonTesterTree.h:160
MuonVal::MuonTesterTree::path
std::string path() const
sub directory in the TFile
Definition: MuonTesterTree.cxx:223
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
std::remove_if
std::reverse_iterator< DataModel_detail::iterator< DVL > > remove_if(typename std::reverse_iterator< DataModel_detail::iterator< DVL > > beg, typename std::reverse_iterator< DataModel_detail::iterator< DVL > > end, Predicate pred)
Specialization of remove_if for DataVector/List.
Definition: DVL_algorithms.h:114
MuonVal
Class to store array like branches into the n-tuples.
Definition: MuonTPMetaDataAlg.cxx:25
MuonVal::MuonTesterTree::name
std::string name() const
Name of the tree.
Definition: MuonTesterTree.cxx:20
MuonVal::MuonTesterTree::m_dependencies
std::vector< DataDependency > m_dependencies
Definition: MuonTesterTree.h:124
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
MuonVal::MuonTesterTree::setPath
void setPath(const std::string &new_path)
Save the TTree in a subfolder of the TFile.
Definition: MuonTesterTree.cxx:222
SG::VarHandleKey
A property holding a SG store/key/clid from which a VarHandle is made.
Definition: StoreGate/StoreGate/VarHandleKey.h:62
MuonVal::MuonTesterTree::m_hash_br
std::shared_ptr< EventHashBranch > m_hash_br
Definition: MuonTesterTree.h:162
MuonVal::MuonTesterTree::addCommonTree
bool addCommonTree(FriendTreePtr common_tree)
Definition: MuonTesterTree.cxx:237
RTTAlgmain.branch
branch
Definition: RTTAlgmain.py:61
MuonVal::MuonTesterTree::m_friendLinks
std::vector< FriendTreePtr > m_friendLinks
List of all other common instances that are acting as friends.
Definition: MuonTesterTree.h:156
MuonVal::MuonTesterTree::m_initialized_br
std::set< IMuonTesterBranch * > m_initialized_br
Set of branches that were already initialized.
Definition: MuonTesterTree.h:147
a
TList * a
Definition: liststreamerinfos.cxx:10
MuonVal::MuonTesterTree::m_hist_svc
ServiceHandle< ITHistSvc > m_hist_svc
Definition: MuonTesterTree.h:153
python.BackTrackingConfig.numThreads
int numThreads
Definition: BackTrackingConfig.py:61
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
known
Definition: TrigBStoxAODTool.cxx:107
MuonVal::MuonTesterTree::fill
bool fill(const EventContext &ctx)
Fills the tree per call.
Definition: MuonTesterTree.cxx:89
MuonVal::MuonTesterTree::write
StatusCode write()
Finally write the TTree objects.
Definition: MuonTesterTree.cxx:178
MuonVal::MuonTesterTree::getFriends
const std::vector< FriendTreePtr > & getFriends() const
Definition: MuonTesterTree.cxx:262
MuonVal::IMuonTesterBranch
Most basic interface class used by the MuonTester tree.
Definition: IMuonTesterBranch.h:20
MuonVal::MuonTesterTree::tree
TTree * tree()
TTree object.
Definition: MuonTesterTree.cxx:22
MuonVal::MuonTesterTree::m_stream
std::string m_stream
Definition: MuonTesterTree.h:128
MuonVal::MuonTesterTree::removeBranch
void removeBranch(IMuonTesterBranch *branch)
In case instances of a certain branch type are destroyed before hand.
Definition: MuonTesterTree.cxx:83
MuonVal::MuonTesterTree::m_excludedBranches
std::set< std::string > m_excludedBranches
Definition: MuonTesterTree.h:149
MuonVal::MuonTesterTree::m_path
std::string m_path
Definition: MuonTesterTree.h:129
MuonVal::MuonTesterTree::addBranch
bool addBranch(std::shared_ptr< IMuonTesterBranch > branch)
Branch is added to the tree without transferring the ownership.
Definition: MuonTesterTree.cxx:61
PlotCalibFromCool.br
br
Definition: PlotCalibFromCool.py:355
ServiceHandle< ITHistSvc >