| The Gaudi Framework v32r1 (f65d50dc)

THistSvc.icc
Go to the documentation of this file.
1 #ifndef GAUDISVC_THISTSVC_ICC
2 #define GAUDISVC_THISTSVC_ICC
3
4 #include <map>
5 #include <string>
6
7 #include "TFile.h"
8 #include "TObject.h"
9
10 #ifndef GAUDIKERNEL_MSGSTREAM_H
11 # include "GaudiKernel/MsgStream.h"
12 #endif
13
14 #include "GaudiKernel/System.h"
15
16 template <typename T>
17 StatusCode THistSvc::regHist_i( std::unique_ptr<T> hist, const std::string& id, bool shared ) {
18 THistID* hid = nullptr;
19 return regHist_i( std::move( hist ), id, shared, hid );
20 }
21
22 template <typename T>
23 StatusCode THistSvc::regHist_i( std::unique_ptr<T> hist_unique, const std::string& id, bool shared, THistID*& phid ) {
24 GlobalDirectoryRestore restore( m_svcMut );
25 phid = nullptr;
26
27 // It is sad that we lose propper memory management here
28 T* hist = nullptr;
29 if ( hist_unique.get() != nullptr ) { hist = hist_unique.release(); }
30 debug() << "regHist_i obj: " << hist << " id: " << id << " s: " << shared << endmsg;
31
32 std::string idr( id );
33 removeDoubleSlash( idr );
34
35 if ( idr.find( "/" ) == idr.length() ) {
36 error() << "Badly formed identifier \"" << idr << "\": "
37 << "Must not end with a /" << endmsg;
38 delete hist;
39 return StatusCode::FAILURE;
40 }
41
42 TFile* f = nullptr;
43 std::string stream, name;
44 if ( !findStream( idr, stream, name, f ) ) {
45 error() << "Could not register id: \"" << idr << "\"" << endmsg;
46 delete hist;
47 return StatusCode::FAILURE;
48 }
49
50 std::string uid = "/" + stream + "/" + name;
51
52 uidMap_t::iterator uitr = m_uids.find( uid );
53 bool exists( false );
54 if ( uitr != m_uids.end() ) {
55 exists = true;
56 TObject* t1 = uitr->second->at( 0 ).obj;
57 if ( hist->Compare( t1 ) != 0 ) {
58 error() << "previously registered object with identifier \"" << uid << "\" does not compare to this one"
59 << endmsg;
60 delete hist;
61 return StatusCode::FAILURE;
62 } else {
63 debug() << "previously registered id \"" << uid << "\": num " << uitr->second->size() << endmsg;
64 }
65 }
66
67 bool temp = false;
68 if ( !f ) {
69 temp = true;
70 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Historgram with id \"" << idr << "\" is temporary" << endmsg; }
71 }
72
73 TObject* to = nullptr;
74 THistID hid;
75 // check to see if this hist is to be read in;
76 if ( !temp && m_files.find( stream )->second.second == READ ) {
77 if ( hist != 0 ) { warning() << "Registering id: \"" << idr << "\" with non zero pointer!" << endmsg; }
78
79 hist = readHist_i<T>( idr );
80 if ( hist == nullptr ) {
81 error() << "Unable to read in hist" << endmsg;
82 delete hist;
83 return StatusCode::FAILURE;
84 }
85 to = dynamic_cast<TObject*>( hist );
86 hid = THistID( uid, temp, to, f, m_files.find( stream )->second.second );
87 } else if ( !hist ) {
88 error() << "Unable to read in hist with id: \"" << idr << "\"" << endmsg;
89 delete hist;
90 return StatusCode::FAILURE;
91 } else {
92 to = dynamic_cast<TObject*>( hist );
93 if ( to == nullptr ) {
94 error() << "Could not dcast to TObject. id: \"" << idr << "\"" << endmsg;
95 delete hist;
96 return StatusCode::FAILURE;
97 }
98
99 auto oitr = m_tobjs.find( to );
100 if ( oitr != m_tobjs.end() ) {
101 error() << "already registered id: \"" << idr << "\" with identifier \""
102 << oitr->second.first->at( oitr->second.second ).id << "\"" << endmsg;
103 delete hist;
104 return StatusCode::FAILURE;
105 }
106
107 const auto findF = m_files.find( stream );
108 hid = ( findF != m_files.end() ? THistID( uid, temp, to, f, findF->second.second ) : THistID( uid, temp, to, f ) );
109
110 hid.shared = shared;
111 TDirectory* dir = changeDir( hid );
112
113 if ( dynamic_cast<TTree*>( hist ) ) {
114 dynamic_cast<TTree*>( hist )->SetDirectory( dir );
115 } else if ( dynamic_cast<TH1*>( hist ) ) {
116 dynamic_cast<TH1*>( hist )->SetDirectory( dir );
117 } else if ( dynamic_cast<TGraph*>( hist ) ) {
118 dir->Append( hist );
119 } else {
120 error() << "id: \"" << idr << "\" is not a TH, TTree, or TGraph. Attaching it to current dir." << endmsg;
121 dir->Append( hist );
122 }
123 }
124
125 std::string fname;
126 if ( !f ) {
127 fname = "none";
128 } else {
129 fname = f->GetName();
130 }
131
132 debug() << "Registering" << ( shared ? " shared " : " " ) << System::typeinfoName( typeid( *hist ) ) << " title: \""
133 << hist->GetTitle() << "\" id: \"" << uid
134 << "\" dir: "
135 // << hist->GetDirectory()->GetPath() << " "
136 << changeDir( hid )->GetPath() << " file: " << fname << endmsg;
137
138 // create a mutex for all shared histograms
139 if ( shared ) { hid.mutex = new histMut_t; }
140
141 if ( exists ) {
142 vhid_t* vi = uitr->second;
143 vi->push_back( hid );
144 phid = &( vi->back() );
145
146 m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, vi->size() - 1 ) );
147 } else {
148 vhid_t* vi = new vhid_t{hid};
149 m_hlist.emplace( m_hlist.end(), vi );
150
151 phid = &( vi->back() );
152 m_uids.emplace( uid, vi );
153 m_ids.emplace( name, vi );
154
155 m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, 0 ) );
156 }
157
158 debug() << "regHist_i THistID: " << hid << endmsg;
159
160 return StatusCode::SUCCESS;
161 }
162
163 template <typename T>
164 T* THistSvc::getHist_i( const std::string& id, const size_t& ind, bool quiet ) const {
165 // id starts with "/": unique
166
167 GlobalDirectoryRestore restore( m_svcMut );
168
169 T* hist = nullptr;
170 const THistID* hid = nullptr;
171 size_t num = findHistID( id, hid, ind );
172 if ( num == 0 ) {
173 // no matches found
174 if ( !quiet ) { error() << "could not locate Hist with id \"" << id << "\"" << endmsg; }
175 return nullptr;
176 } else if ( num > 1 ) {
177 if ( !quiet ) {
178 // return failure if trying to GET a single hist
179 error() << "Multiple matches with id \"" << id << "\"."
180 << " Further specifications required." << endmsg;
181 return nullptr;
182 } else {
183 info() << "Found multiple matches with id \"" << id << "\"" << endmsg;
184 // return first match if just INQUIRING (i.e. != nullptr)
185 hist = dynamic_cast<T*>( hid->obj );
186 if ( hist == nullptr ) {
187 error() << "dcast failed, Hist id: \"" << id << "\"" << endmsg;
188 return nullptr;
189 }
190 }
191 } else {
192 hist = dynamic_cast<T*>( hid->obj );
193 if ( hist == nullptr ) {
194 error() << "dcast failed, Hist id: \"" << id << "\"" << endmsg;
195 return nullptr;
196 }
197 verbose() << "found unique Hist title: \"" << hist->GetTitle() << "\" id: \"" << id << "\"" << endmsg;
198 }
199
200 return hist;
201 }
202
203 template <typename T>
204 T* THistSvc::readHist_i( const std::string& id ) const {
205 GlobalDirectoryRestore restore( m_svcMut );
206
207 std::string idr( id );
208 removeDoubleSlash( idr );
209
210 std::string stream, rem, dir, fdir, bdir, fdir2;
211 TFile* file = nullptr;
212
213 if ( !findStream( idr, stream, rem, file ) ) { return nullptr; }
214
215 if ( !file ) {
216 error() << "no associated file found" << endmsg;
217 return nullptr;
218 }
219
220 file->cd( "/" );
221
222 fdir = idr;
223 bdir = stripDirectoryName( fdir );
224 fdir2 = fdir;
225 while ( ( dir = stripDirectoryName( fdir ) ) != "" ) {
226 if ( !gDirectory->GetKey( dir.c_str() ) ) {
227 error() << "Directory \"" << fdir2 << "\" doesnt exist in " << file->GetName() << endmsg;
228 return nullptr;
229 }
230 gDirectory->cd( dir.c_str() );
231 }
232
233 TObject* to = nullptr;
234 gDirectory->GetObject( fdir.c_str(), to );
235
236 if ( !to ) {
237 error() << "Could not get obj \"" << fdir << "\" in " << gDirectory->GetPath() << endmsg;
238 return nullptr;
239 }
240
241 T* hist = dynamic_cast<T*>( to );
242 if ( hist == nullptr ) {
243 error() << "Could not convert \"" << idr << "\" to a " << System::typeinfoName( typeid( *hist ) ) << " as is a "
244 << to->IsA()->GetName() << endmsg;
245 return nullptr;
246 }
247
248 if ( msgLevel( MSG::DEBUG ) ) {
249 debug() << "Read in " << hist->IsA()->GetName() << " \"" << hist->GetName() << "\" from file " << file->GetName()
250 << endmsg;
251 hist->Print();
252 }
253
254 return hist;
255 }
256
257 template <typename T>
258 LockedHandle<T> THistSvc::regShared_i( const std::string& id, std::unique_ptr<T> hist ) {
259 LockedHandle<T> lh( nullptr, nullptr );
260 const THistID* hid = nullptr;
261 if ( findHistID( id, hid ) == 0 ) {
262 T* phist = hist.get();
263 THistID* phid = nullptr;
264 if ( regHist_i( std::move( hist ), id, true, phid ).isSuccess() ) {
265 lh.set( phist, phid->mutex );
266
267 } else {
268 error() << "regSharedHist: unable to register shared hist with id \"" << id << "\"" << endmsg;
269 }
270 } else {
271 if ( !hid->shared ) {
272 error() << "regSharedHist: previously register Hist with id \"" << id << "\" was not marked shared" << endmsg;
273 }
274
275 if ( hist->Compare( hid->obj ) != 0 ) {
276 error() << "regSharedHist: Histogram " << id << " does not compare with " << hid << endmsg;
277 } else {
278 T* phist = dynamic_cast<T*>( hid->obj );
279 if ( phist == 0 ) {
280 error() << "regSharedHist: unable to dcast retrieved shared hist \"" << id << "\" of type "
281 << hid->obj->IsA()->GetName() << " to requested type " << System::typeinfoName( typeid( T ) ) << endmsg;
282 } else {
283 lh.set( phist, hid->mutex );
284 delete hist.release();
285 }
286 }
287 }
288 return lh;
289 }
290
291 template <typename T>
292 LockedHandle<T> THistSvc::getShared_i( const std::string& name ) const {
293 GlobalDirectoryRestore restore( m_svcMut );
294
295 const THistID* hid = nullptr;
296 size_t i = findHistID( name, hid );
297
298 LockedHandle<T> hist( nullptr, nullptr );
299
300 if ( i == 1 ) {
301 if ( !hid->shared ) {
302 error() << "getSharedHist: found Hist with id \"" << name << "\", but it's not marked as shared" << endmsg;
303 return hist;
304 }
305 T* h1 = dynamic_cast<T*>( hid->obj );
306 hist = LockedHandle<T>( h1, hid->mutex );
307
308 debug() << "getSharedHist: found THistID: " << *hid << endmsg;
309 } else if ( i == 0 ) {
310 error() << "no histograms matching id \"" << name << "\" found" << endmsg;
311 } else {
312 info() << "multiple matches for id \"" << name << "\" found [" << i << "], probably from different streams"
313 << endmsg;
314 }
315 return hist;
316 }
317
318 #endif // GAUDISVC_THISTSVC_ICC
System.h
THistSvc::THistID
Helper struct that bundles the histogram ID with a mutex, TFile and TObject*.
Definition: THistSvc.h:200
THistSvc::regShared_i
LockedHandle< T > regShared_i(const std::string &id, std::unique_ptr< T > hist)
Definition: THistSvc.icc:258
gaudiComponentHelp.name
name
Definition: gaudiComponentHelp.py:41
MsgStream.h
CommonMessagingBase::warning
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
Definition: CommonMessaging.h:101
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
THistSvc::histMut_t
std::mutex histMut_t
Definition: THistSvc.h:165
THistSvc::readHist_i
T * readHist_i(const std::string &name) const
Definition: THistSvc.icc:204
THistSvc::THistID::mutex
histMut_t * mutex
Definition: THistSvc.h:206
MSG::DEBUG
Definition: IMessageSvc.h:15
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
std::unordered_map::end
T end(T... args)
CommonMessagingBase::info
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
Definition: CommonMessaging.h:104
THistSvc::stripDirectoryName
std::string stripDirectoryName(std::string &dir) const
Definition: THistSvc.cpp:1475
THistSvc::findStream
bool findStream(const std::string &name, std::string &root, std::string &rem, TFile *&file) const
Definition: THistSvc.cpp:1542
THistSvc::m_tobjs
objMap_t m_tobjs
Definition: THistSvc.h:263
std::unique_ptr::release
T release(T... args)
THistSvc::THistID::shared
bool shared
Definition: THistSvc.h:207
THistSvc::getShared_i
LockedHandle< T > getShared_i(const std::string &name) const
Definition: THistSvc.icc:292
CommonMessaging< implements< IService, IProperty, IStateful > >::msgLevel
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
Definition: CommonMessaging.h:138
std::string
STL class.
std::string::at
T at(T... args)
THistSvc::m_hlist
hlist_t m_hlist
Definition: THistSvc.h:258
THistSvc::m_ids
idMap_t m_ids
Definition: THistSvc.h:260
Service::name
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:274
std::vector::push_back
T push_back(T... args)
CommonMessagingBase::error
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Definition: CommonMessaging.h:98
LockedHandle::set
void set(T *ptr, MutexType *mut)
Definition: LockedHandle.h:35
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
LockedHandle
Provides automatic lock/unlock access to a class upon deref of ptr.
Definition: LockedHandle.h:28
CommonMessagingBase::verbose
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
Definition: CommonMessaging.h:110
CommonMessagingBase::debug
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Definition: CommonMessaging.h:107
THistSvc::changeDir
TDirectory * changeDir(const THistSvc::THistID &hid) const
Definition: THistSvc.cpp:1453
std::move
T move(T... args)
THistSvc::regHist_i
StatusCode regHist_i(std::unique_ptr< T > hist, const std::string &name, bool shared)
Definition: THistSvc.icc:17
std::pair< vhid_t *, size_t >
std::unique_ptr::get
T get(T... args)
std::string::find
T find(T... args)
std::string::length
T length(T... args)
THistSvc::THistID::obj
TObject * obj
Definition: THistSvc.h:203
std::vector
STL class.
std::unique_ptr
STL class.
THistSvc::removeDoubleSlash
void removeDoubleSlash(std::string &) const
Definition: THistSvc.cpp:1491
std::string::c_str
T c_str(T... args)
THistSvc::m_uids
uidMap_t m_uids
Definition: THistSvc.h:259
THistSvc::m_files
std::map< std::string, std::pair< TFile *, Mode > > m_files
Definition: THistSvc.h:265
std::unordered_map::emplace
T emplace(T... args)
std::vector::back
T back(T... args)
THistSvc::READ
Definition: THistSvc.h:181
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:86
THistSvc::getHist_i
T * getHist_i(const std::string &name, const size_t &ind=0, bool quiet=false) const
Definition: THistSvc.icc:164
THistSvc::exists
bool exists(const std::string &name) const override
Check if object with given name is managed by THistSvcMT.
Definition: THistSvc.cpp:604
THistSvc::m_svcMut
THistSvcMutex_t m_svcMut
Definition: THistSvc.h:365
THistSvc::findHistID
size_t findHistID(const std::string &id, const THistID *&hid, const size_t &index=0) const
Definition: THistSvc.cpp:1666
THistSvc::GlobalDirectoryRestore
Helper class that manages ROOts global directory and file.
Definition: THistSvc.h:168
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192