All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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>
17 StatusCode THistSvc::regHist_i(T* hist, const std::string& id) {
18 
19  GlobalDirectoryRestore restore;
20 
21  std::string idr(id);
22  removeDoubleSlash( idr );
23 
24  if (idr.find("/") == idr.length()) {
25  m_log << MSG::ERROR << "Badly formed identifier \"" << idr << "\": "
26  << "Must not end with a /" << endmsg;
27  return StatusCode::FAILURE;
28  }
29 
30 
31  TFile *f(0);
32  std::string stream,rem;
33  if (!findStream(idr, stream, rem, f)) {
34  m_log << MSG::ERROR << "Could not register id: \"" << idr << "\""
35  << endmsg;
36  return StatusCode::FAILURE;
37  }
38 
39  std::string uid = "/" + stream + "/" + rem;
40  uidMap::const_iterator itr = m_uids.find(uid);
41  if (itr != m_uids.end()) {
42  m_log << MSG::ERROR << "already registered an object with identifier \""
43  << idr << "\"" << endmsg;
44  return StatusCode::FAILURE;
45  }
46 
47 
48  bool temp = false;
49  if (f == 0) {
50  temp = true;
51  if (m_log.level() <= MSG::DEBUG)
52  m_log << MSG::DEBUG << "Historgram with id \"" << idr << "\" is temporary"
53  << endmsg;
54  }
55 
56 
57  TObject *to;
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  m_log << MSG::WARNING << "Registering id: \"" << idr
65  << "\" with non zero pointer!" << endmsg;
66  }
67 
68  if (readHist_i(idr,hist).isFailure()) {
69  m_log << MSG::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  m_log << MSG::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  m_log << MSG::ERROR << "Could not dcast to TObject. id: \"" << idr
85  << "\"" << endmsg;
86  return StatusCode::FAILURE;
87  }
88 
89  objMap::const_iterator oitr = m_tobjs.find(to);
90  if (oitr != m_tobjs.end()) {
91  m_log << MSG::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) != 0 ) {
100  dynamic_cast<TTree*>(hist)->SetDirectory(dir);
101  } else if ( dynamic_cast<TH1*>(hist) != 0 ) {
102  dynamic_cast<TH1*>(hist)->SetDirectory(dir);
103  } else if ( dynamic_cast<TGraph*>(hist) != 0 ) {
104  dir->Append(hist);
105  } else {
106  m_log << MSG::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 == 0) {
116  fname = "none";
117  } else {
118  fname = f->GetName();
119  }
120 
121  if (m_log.level() <= MSG::DEBUG)
122  m_log << MSG::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.insert(std::pair<std::string,THistID>(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>
141 StatusCode
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  std::map<std::string, THistID>::const_iterator itr = m_uids.find(id);
152  if (itr == m_uids.end()) {
153  if (!quiet) {
154  m_log << MSG::ERROR << "Could not locate Hist with id \"" << idr << "\""
155  << endmsg;
156  }
157  hist = 0;
158  return StatusCode::FAILURE;
159  }
160 
161  THistID hid = itr->second;
162  if (!quiet) {
163  hist = dynamic_cast<T*>(hid.obj);
164  if (hist == 0) {
165  m_log << MSG::ERROR << "dcast failed, Hist id: \"" << idr << "\""
166  << endmsg;
167  return StatusCode::FAILURE;
168  }
169  if (m_log.level() <= MSG::VERBOSE) {
170  m_log << MSG::VERBOSE << "found unique Hist title: \""
171  << hist->GetTitle()
172  << "\" id: \"" << idr << "\"" << endmsg;
173  }
174  } else {
175  if (m_log.level() <= MSG::VERBOSE) {
176  m_log << MSG::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  std::pair< std::multimap<std::string,THistID>::const_iterator,
189  std::multimap<std::string,THistID>::const_iterator > mitr = m_ids.equal_range(idr);
190 
191 
192  if (mitr.first == mitr.second) {
193  m_log << MSG::ERROR << "Could not locate Hist with id \"" << idr << "\""
194  << endmsg;
195  hist = 0;
196  return StatusCode::FAILURE;
197  } else {
198 
199  if (distance(mitr.first,mitr.second) == 1) {
200  THistID hid = mitr.first->second;
201  if (!quiet) {
202  hist = dynamic_cast<T*>(hid.obj);
203  if (hist == 0) {
204  m_log << MSG::ERROR << "dcast failed" << endmsg;
205  return StatusCode::FAILURE;
206  }
207  if (m_log.level() <= MSG::VERBOSE) {
208  m_log << MSG::VERBOSE << "found Hist title: \"" << hist->GetTitle()
209  << "\" id: \"" << idr << "\"" << endmsg;
210  }
211  } else {
212  if (m_log.level() <= MSG::VERBOSE) {
213  m_log << MSG::VERBOSE << "found Hist id: \"" << idr << "\" type: \""
214  << hid.obj->IsA()->GetName() << "\""
215  << endmsg;
216  }
217  }
218  return StatusCode::SUCCESS;
219  } else {
220  if (!quiet) {
221  // return failure if trying to GET a single hist
222  m_log << MSG::ERROR << "Multiple matches with id \"" << idr << "\"."
223  << " Further specifications required."
224  << endmsg;
225  hist = 0;
226  return StatusCode::FAILURE;
227  } else {
228  // return a SUCCESS if just INQUIRING
229  m_log << MSG::INFO << "Found multiple matches with id \"" << idr
230  << "\"" << endmsg;
231  hist = 0;
232  return StatusCode::SUCCESS;
233  }
234  }
235  }
236  }
237 }
238 
239 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
240 
241 template <typename T>
243 THistSvc::readHist_i(const std::string& id, T*& hist) const {
244 
245  GlobalDirectoryRestore restore;
246 
247  std::string idr(id);
248  removeDoubleSlash( idr );
249 
250  std::string stream, rem, dir, fdir, bdir, fdir2;
251  TFile *file;
252 
253  if (!findStream(idr, stream, rem, file) ) {
254  return StatusCode::FAILURE;
255  }
256 
257  if (file == 0) {
258  m_log << MSG::ERROR << "no associated file found" << endmsg;
259  return StatusCode::FAILURE;
260  }
261 
262  file->cd("/");
263 
264  fdir = idr;
265  bdir = dirname(fdir);
266  fdir2 = fdir;
267  while ( (dir=dirname(fdir)) != "" ) {
268  if (! gDirectory->GetKey(dir.c_str())) {
269  m_log << MSG::ERROR << "Directory \"" << fdir2 << "\" doesnt exist in "
270  << file->GetName() << endmsg;
271  return StatusCode::FAILURE;
272  }
273  gDirectory->cd(dir.c_str());
274  }
275 
276  TObject *to;
277  gDirectory->GetObject(fdir.c_str(), to);
278 
279  if (to == 0) {
280  m_log << MSG::ERROR << "Could not get obj \"" << fdir << "\" in "
281  << gDirectory->GetPath() << endmsg;
282  return StatusCode::FAILURE;
283  }
284 
285 
286 
287  hist = dynamic_cast<T*>(to);
288  if (hist == 0) {
289  m_log << MSG::ERROR << "Could not convert \"" << idr << "\" to a "
290  << System::typeinfoName(typeid(*hist)) << " as is a "
291  << to->IsA()->GetName()
292  << endmsg;
293  return StatusCode::FAILURE;
294  }
295 
296 
297  if (m_log.level() <= MSG::DEBUG) {
298  m_log << MSG::DEBUG << "Read in " << hist->IsA()->GetName() << " \""
299  << hist->GetName() << "\" from file "
300  << file->GetName() << endmsg;
301  hist->Print();
302  }
303 
304  return StatusCode::SUCCESS;
305 
306 }
307 
308 #endif
MSG::Level level()
Retrieve output level.
Definition: MsgStream.h:111
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
bool findStream(const std::string &name, std::string &root, std::string &rem, TFile *&file) const
Definition: THistSvc.cpp:1210
TDirectory * changeDir(const THistSvc::THistID &hid) const
Definition: THistSvc.cpp:1746
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:72
objMap m_tobjs
Definition: THistSvc.h:201
std::string dirname(std::string &dir) const
Definition: THistSvc.cpp:1775
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:30
std::map< std::string, std::pair< TFile *, Mode > > m_files
Definition: THistSvc.h:203
list file
Definition: ana.py:160
StatusCode getHist_i(const std::string &name, T *&hist, bool quiet=false) const
Definition: THistSvc.icc:142
TObject * obj
Definition: THistSvc.h:117
StatusCode regHist_i(T *hist, const std::string &name)
Definition: THistSvc.icc:17
uidMap m_uids
Definition: THistSvc.h:199
StatusCode readHist_i(const std::string &name, T *&hist) const
Definition: THistSvc.icc:243
idMap m_ids
Definition: THistSvc.h:200
MsgStream m_log
Definition: THistSvc.h:178
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:243
void removeDoubleSlash(std::string &) const
Definition: THistSvc.cpp:1813