The Gaudi Framework  v29r0 (ff2e7097)
THistSvc.icc
Go to the documentation of this file.
1 #ifndef GAUDISVC_THISTSVC_ICC
2 #define GAUDISVC_THISTSVC_ICC
3 
4 #ifndef GAUDIKERNEL_MSGSTREAM_H
5  #include "GaudiKernel/MsgStream.h"
6 #endif
7 
8 #include "GaudiKernel/System.h"
9 
10 #include <string>
11 #include <map>
12 
13 #include "TObject.h"
14 #include "TFile.h"
15 
16 template <typename T>
18 
19  GlobalDirectoryRestore restore;
20 
21  std::string idr(id);
22  removeDoubleSlash( idr );
23 
24  if (idr.find("/") == idr.length()) {
25  error() << "Badly formed identifier \"" << idr << "\": "
26  << "Must not end with a /" << endmsg;
27  return StatusCode::FAILURE;
28  }
29 
30 
31  TFile *f = nullptr;
32  std::string stream,rem;
33  if (!findStream(idr, stream, rem, f)) {
34  error() << "Could not register id: \"" << idr << "\""
35  << endmsg;
36  return StatusCode::FAILURE;
37  }
38 
39  std::string uid = "/" + stream + "/" + rem;
40  auto itr = m_uids.find(uid);
41  if (itr != m_uids.end()) {
42  error() << "already registered an object with identifier \""
43  << idr << "\"" << endmsg;
44  return StatusCode::FAILURE;
45  }
46 
47 
48  bool temp = false;
49  if ( !f ) {
50  temp = true;
51  if (msgLevel(MSG::DEBUG))
52  debug() << "Historgram with id \"" << idr << "\" is temporary"
53  << endmsg;
54  }
55 
56 
57  TObject *to = nullptr;
58  THistID hid;
59 
60  // check to see if this hist is to be read in;
61  if (!temp && m_files.find(stream)->second.second == READ) {
62 
63  if (hist != 0) {
64  warning() << "Registering id: \"" << idr
65  << "\" with non zero pointer!" << endmsg;
66  }
67 
68  if (readHist_i(idr,hist).isFailure()) {
69  error() << "Unable to read in hist" << endmsg;
70  return StatusCode::FAILURE;
71  }
72  to = dynamic_cast<TObject*>(hist);
73  hid = THistID(uid,temp,to,f,m_files.find(stream)->second.second);
74 
75  } else if (hist == 0) {
76  error() << "Unable to read in hist with id: \""
77  << idr << "\"" << endmsg;
78  return StatusCode::FAILURE;
79 
80  } else {
81 
82  to = dynamic_cast<TObject*>(hist);
83  if (to == 0) {
84  error() << "Could not dcast to TObject. id: \"" << idr
85  << "\"" << endmsg;
86  return StatusCode::FAILURE;
87  }
88 
89  auto oitr = m_tobjs.find(to);
90  if (oitr != m_tobjs.end()) {
91  error() << "already registered id: \"" << idr
92  << "\" with identifier \"" << oitr->second.id << "\"" << endmsg;
93  return StatusCode::FAILURE;
94  }
95 
96  hid = THistID(uid,temp,to,f,m_files.find(stream)->second.second);
97  TDirectory* dir = changeDir(hid);
98 
99  if ( dynamic_cast<TTree*>(hist) ) {
100  dynamic_cast<TTree*>(hist)->SetDirectory(dir);
101  } else if ( dynamic_cast<TH1*>(hist) ) {
102  dynamic_cast<TH1*>(hist)->SetDirectory(dir);
103  } else if ( dynamic_cast<TGraph*>(hist) ) {
104  dir->Append(hist);
105  } else {
106  error() << "id: \"" << idr
107  << "\" is not a TH, TTree, or TGraph. Attaching it to current dir."
108  << endmsg;
109  dir->Append(hist);
110  }
111 
112  }
113 
114  std::string fname;
115  if ( !f ) {
116  fname = "none";
117  } else {
118  fname = f->GetName();
119  }
120 
121  if (msgLevel(MSG::DEBUG))
122  debug() << "Registering " << System::typeinfoName(typeid(*hist))
123  << " title: \"" << hist->GetTitle()
124  << "\" id: \"" << uid << "\" dir: "
125  // << hist->GetDirectory()->GetPath() << " "
126  << changeDir(hid)->GetPath()
127  << " file: " << fname
128  << endmsg;
129 
130  m_ids.emplace(rem, hid);
131  m_uids[uid] = hid;
132  m_tobjs[to] = hid;
133 
134  return StatusCode::SUCCESS;
135 
136 }
137 
138 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
139 
140 template <typename T>
142 THistSvc::getHist_i(const std::string& id, T*& hist, bool quiet) const {
143  // id starts with "/": unique
144 
145  GlobalDirectoryRestore restore;
146 
147  std::string idr(id);
148  removeDoubleSlash( idr );
149 
150  if (idr.find("/") == 0) {
151  auto itr = m_uids.find(id);
152  if (itr == m_uids.end()) {
153  if (!quiet) {
154  error() << "Could not locate Hist with id \"" << idr << "\""
155  << endmsg;
156  }
157  hist = nullptr;
158  return StatusCode::FAILURE;
159  }
160 
161  THistID hid = itr->second;
162  if (!quiet) {
163  hist = dynamic_cast<T*>(hid.obj);
164  if ( !hist ) {
165  error() << "dcast failed, Hist id: \"" << idr << "\""
166  << endmsg;
167  return StatusCode::FAILURE;
168  }
169  if (msgLevel(MSG::VERBOSE)) {
170  verbose() << "found unique Hist title: \""
171  << hist->GetTitle()
172  << "\" id: \"" << idr << "\"" << endmsg;
173  }
174  } else {
175  if (msgLevel(MSG::VERBOSE)) {
176  verbose() << "found unique Hist id: \"" << idr
177  << "\" type: \"" << hid.obj->IsA()->GetName() << "\""
178  << endmsg;
179  }
180  }
181 
182  return StatusCode::SUCCESS;
183 
184 
185  // not necessarily unique
186  } else {
187 
188  auto mitr = m_ids.equal_range(idr);
189 
190 
191  if (mitr.first == mitr.second) {
192  error() << "Could not locate Hist with id \"" << idr << "\""
193  << endmsg;
194  hist = nullptr;
195  return StatusCode::FAILURE;
196  } else {
197 
198  if (distance(mitr.first,mitr.second) == 1) {
199  THistID hid = mitr.first->second;
200  if (!quiet) {
201  hist = dynamic_cast<T*>(hid.obj);
202  if (hist == 0) {
203  error() << "dcast failed" << endmsg;
204  return StatusCode::FAILURE;
205  }
206  if (msgLevel(MSG::VERBOSE)) {
207  verbose() << "found Hist title: \"" << hist->GetTitle()
208  << "\" id: \"" << idr << "\"" << endmsg;
209  }
210  } else {
211  if (msgLevel(MSG::VERBOSE)) {
212  verbose() << "found Hist id: \"" << idr << "\" type: \""
213  << hid.obj->IsA()->GetName() << "\""
214  << endmsg;
215  }
216  }
217  return StatusCode::SUCCESS;
218  } else {
219  if (!quiet) {
220  // return failure if trying to GET a single hist
221  error() << "Multiple matches with id \"" << idr << "\"."
222  << " Further specifications required."
223  << endmsg;
224  hist = nullptr;
225  return StatusCode::FAILURE;
226  } else {
227  // return a SUCCESS if just INQUIRING
228  info() << "Found multiple matches with id \"" << idr
229  << "\"" << endmsg;
230  hist = nullptr;
231  return StatusCode::SUCCESS;
232  }
233  }
234  }
235  }
236 }
237 
238 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
239 
240 template <typename T>
242 THistSvc::readHist_i(const std::string& id, T*& hist) const {
243 
244  GlobalDirectoryRestore restore;
245 
246  std::string idr(id);
247  removeDoubleSlash( idr );
248 
249  std::string stream, rem, dir, fdir, bdir, fdir2;
250  TFile *file;
251 
252  if (!findStream(idr, stream, rem, file) ) {
253  return StatusCode::FAILURE;
254  }
255 
256  if ( !file ) {
257  error() << "no associated file found" << endmsg;
258  return StatusCode::FAILURE;
259  }
260 
261  file->cd("/");
262 
263  fdir = idr;
264  bdir = dirname(fdir);
265  fdir2 = fdir;
266  while ( (dir=dirname(fdir)) != "" ) {
267  if (! gDirectory->GetKey(dir.c_str())) {
268  error() << "Directory \"" << fdir2 << "\" doesnt exist in "
269  << file->GetName() << endmsg;
270  return StatusCode::FAILURE;
271  }
272  gDirectory->cd(dir.c_str());
273  }
274 
275  TObject *to=nullptr;
276  gDirectory->GetObject(fdir.c_str(), to);
277 
278  if ( !to ) {
279  error() << "Could not get obj \"" << fdir << "\" in "
280  << gDirectory->GetPath() << endmsg;
281  return StatusCode::FAILURE;
282  }
283 
284 
285 
286  hist = dynamic_cast<T*>(to);
287  if ( !hist ) {
288  error() << "Could not convert \"" << idr << "\" to a "
289  << System::typeinfoName(typeid(*hist)) << " as is a "
290  << to->IsA()->GetName()
291  << endmsg;
292  return StatusCode::FAILURE;
293  }
294 
295 
296  if (msgLevel(MSG::DEBUG)) {
297  debug() << "Read in " << hist->IsA()->GetName() << " \""
298  << hist->GetName() << "\" from file "
299  << file->GetName() << endmsg;
300  hist->Print();
301  }
302 
303  return StatusCode::SUCCESS;
304 
305 }
306 
307 #endif
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:329
bool findStream(const std::string &name, std::string &root, std::string &rem, TFile *&file) const
Definition: THistSvc.cpp:985
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
T end(T...args)
TDirectory * changeDir(const THistSvc::THistID &hid) const
Definition: THistSvc.cpp:1411
objMap m_tobjs
Definition: THistSvc.h:180
STL class.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
std::string dirname(std::string &dir) const
Definition: THistSvc.cpp:1439
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
StatusCode getHist_i(const std::string &name, T *&hist, bool quiet=false) const
Definition: THistSvc.icc:142
T find(T...args)
T length(T...args)
TObject * obj
Definition: THistSvc.h:99
StatusCode regHist_i(T *hist, const std::string &name)
Definition: THistSvc.icc:17
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
uidMap m_uids
Definition: THistSvc.h:178
StatusCode readHist_i(const std::string &name, T *&hist) const
Definition: THistSvc.icc:242
T c_str(T...args)
std::map< std::string, std::pair< TFile *, Mode > > m_files
Definition: THistSvc.h:182
T emplace(T...args)
idMap m_ids
Definition: THistSvc.h:179
MSG::Level msgLevel() const
get the output level from the embedded MsgStream
T equal_range(T...args)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
void removeDoubleSlash(std::string &) const
Definition: THistSvc.cpp:1475