| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
HistogramSvc.cpp
Go to the documentation of this file.
1 // $Id: HistogramSvc.cpp,v 1.28 2007/09/26 16:14:47 marcocle Exp $
2 #ifdef __ICC
3 // disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
4 // TODO: To be removed, since it comes from ROOT TMathBase.h
5 #pragma warning(disable:2259)
6 #endif
7 #ifdef WIN32
8 // Disable warning
9 // warning C4996: 'sprintf': This function or variable may be unsafe.
10 // coming from TString.h
11 #pragma warning(disable:4996)
12 #endif
13 // ============================================================================
14 // Include files
15 // ============================================================================
16 // STD&STL
17 // ============================================================================
18 #include <cstdlib>
19 #include <stdexcept>
20 #include <sstream>
21 // ============================================================================
22 // GaudiKernel
23 // ============================================================================
24 #include "GaudiKernel/xtoa.h"
25 #include "GaudiKernel/Property.h"
26 #include "GaudiKernel/Tokenizer.h"
27 #include "GaudiKernel/MsgStream.h"
28 #include "GaudiKernel/DataObject.h"
29 #include "GaudiKernel/IConversionSvc.h"
30 #include "GaudiKernel/GenericAddress.h"
31 // ============================================================================
32 // Local
33 // ============================================================================
34 #include "HistogramSvc.h"
35 // ============================================================================
36 // Instantiation of a factory class used by clients
37 DECLARE_COMPONENT(HistogramSvc)
38 // ============================================================================
39 using namespace AIDA;
40 // ============================================================================
41 namespace
42 {
43 // ==========================================================================
44 inline std::string histoAddr
45 ( const std::string& name)
46 {
47 if ( 0 == name.find ( "/stat/" ) ){ return std::string( name , 6 ) ; }
48 return name ;
49 }
50 // ==========================================================================
51 inline std::string histoAddr
52 ( const DataObject* obj ,
53 const std::string& rel )
54 {
55 if ( 0 == obj ) { return rel ; }
56 IRegistry* reg = obj->registry() ;
57 if ( 0 == reg ) { return rel ; }
58 const std::string& name = reg->identifier() ;
59 //
60 if ( rel .empty() ) { return histoAddr ( name ) ; }
61 if ( '/' == name[name.size()-1] ||
62 '/' == rel[0] ) { return histoAddr ( name + rel ) ; }
63 return histoAddr ( name + "/" + rel ) ;
64 }
65 // ==========================================================================
66 }
67 //------------------------------------------------------------------------------
68 std::string HistogramSvc::_STR(int i) {
69 std::ostringstream txt; txt << i;
70 return txt.str();
71 }
72 //------------------------------------------------------------------------------
73 StatusCode HistogramSvc::registerObject(CSTR full, IBaseHistogram* obj) {
74 std::pair<std::string,std::string> split=i_splitPath(full);
75 return registerObject(split.first, split.second, obj);
76 }
77 //------------------------------------------------------------------------------
78 StatusCode HistogramSvc::registerObject
79 (DataObject* pPar,CSTR obj,IBaseHistogram* hObj) {
80 // Set the histogram id
81 if (obj[0] == SEPARATOR) {
82 // hObj->setTitle(obj.substr(1) + "|" + hObj->title());
83 if (!hObj->annotation().addItem("id", obj.substr(1)))
84 hObj->annotation().setValue("id", obj.substr(1));
85 }
86 else {
87 // hObj->setTitle(obj + "|" + hObj->title());
88 if (!hObj->annotation().addItem("id", obj))
89 hObj->annotation().setValue("id", obj);
90 }
91 // Register the histogram in the histogram data store
92 return DataSvc::registerObject(pPar,obj,__cast(hObj));
93 }
94
95 // Helper for 2D projections
96 AIDA::IHistogram2D*
97 HistogramSvc::i_project(CSTR nameAndTitle,const IHistogram3D& h, CSTR dir) {
98 TH3D *h3d = Gaudi::getRepresentation<IHistogram3D,TH3D>(h);
99 if ( h3d ) {
100 TH2D *h2d = dynamic_cast<TH2D*>(h3d->Project3D(dir.c_str()));
101 if ( h2d ) {
102 std::pair<DataObject*,H2D*> r=Gaudi::createH2D(h2d);
103 if ( r.second && registerObject(nameAndTitle,r.second).isSuccess() ) {
104 return r.second;
105 }
106 }
107 }
108 return 0;
109 }
110
111 //------------------------------------------------------------------------------
112 // ASCII output
113 //------------------------------------------------------------------------------
114 std::ostream& HistogramSvc::print(IBaseHistogram* h, std::ostream& s) const {
115 Gaudi::HistogramBase* b = dynamic_cast<Gaudi::HistogramBase*>(h);
116 if(0 != b) return b->print(s);
117 MsgStream log(msgSvc(), name());
118 log << MSG::ERROR << "Unknown histogram type: Cannot cast to Gaudi::HistogramBase."
119 << endmsg;
120 return s;
121 }
122 //------------------------------------------------------------------------------
123 std::ostream& HistogramSvc::write(IBaseHistogram* h, std::ostream& s) const {
124 Gaudi::HistogramBase* b = dynamic_cast<Gaudi::HistogramBase*>(h);
125 if(0 != b) return b->write(s);
126 MsgStream log(msgSvc(), name());
127 log << MSG::ERROR << "Unknown histogram type: Cannot cast to Gaudi::HistogramBase."
128 << endmsg;
129 return s;
130 }
131 //------------------------------------------------------------------------------
132 int HistogramSvc::write(IBaseHistogram* h, const char* file_name) const {
133 Gaudi::HistogramBase* b = dynamic_cast<Gaudi::HistogramBase*>(h);
134 if(0 != b) return b->write(file_name);
135 MsgStream log(msgSvc(), name());
136 log << MSG::ERROR << "Unknown histogram type: Cannot cast to Gaudi::HistogramBase."
137 << endmsg;
138 return 0;
139 }
140 //------------------------------------------------------------------------------
141 std::pair<std::string,std::string> HistogramSvc::i_splitPath(CSTR full) {
142 std::string tmp = full;
143 if (tmp[0] != SEPARATOR) {
144 tmp.insert(tmp.begin(), SEPARATOR);
145 tmp.insert(tmp.begin(), m_rootName.begin(), m_rootName.end());
146 }
147 // Remove trailing "/" from newPath if it exists
148 if (tmp.rfind(SEPARATOR) == tmp.length()-1) {
149 tmp.erase(tmp.rfind(SEPARATOR),1);
150 }
151 int sep = tmp.rfind(SEPARATOR);
152 return std::pair<std::string,std::string>
153 (tmp.substr(0,sep),tmp.substr(sep,tmp.length()-sep));
154 }
155 //------------------------------------------------------------------------------
156 DataObject* HistogramSvc::createPath(CSTR newPath) {
157 std::string tmpPath = newPath;
158 if (tmpPath[0] != SEPARATOR) {
159 tmpPath.insert(tmpPath.begin(), SEPARATOR);
160 tmpPath.insert(tmpPath.begin(), m_rootName.begin(), m_rootName.end());
161 }
162 // Remove trailing "/" from newPath if it exists
163 if (tmpPath.rfind(SEPARATOR) == tmpPath.length()-1) {
164 tmpPath.erase(tmpPath.rfind(SEPARATOR),1);
165 }
166 DataObject* pObject = 0;
167 StatusCode sc = DataSvc::findObject(tmpPath, pObject);
168 if(sc.isSuccess()) {
169 return pObject;
170 }
171 int sep = tmpPath.rfind(SEPARATOR);
172 std::string rest(tmpPath, sep+1, tmpPath.length()-sep);
173 std::string subPath(tmpPath, 0, sep);
174 if(0 != sep) {
175 createPath(subPath);
176 }
177 else {
178 MsgStream log(msgSvc(), name());
179 log << MSG::ERROR << "Unable to create the histogram path" << endmsg;
180 return 0;
181 }
182 pObject = createDirectory(subPath, rest);
183 return pObject;
184 }
185 //------------------------------------------------------------------------------
186 DataObject* HistogramSvc::createDirectory(CSTR parentDir,CSTR subDir) {
187 DataObject* directory = new DataObject();
188 if (0 != directory) {
189 DataObject* pnode;
190 StatusCode status = DataSvc::retrieveObject(parentDir, pnode);
191 if(status.isSuccess()) {
192 status = DataSvc::registerObject(pnode, subDir, directory);
193 if (!status.isSuccess()) {
194 MsgStream log(msgSvc(), name());
195 log << MSG::ERROR << "Unable to create the histogram directory: "
196 << parentDir << "/" << subDir << endmsg;
197 delete directory;
198 return 0;
199 }
200 }
201 else {
202 MsgStream log(msgSvc(), name());
203 log << MSG::ERROR << "Unable to create the histogram directory: "
204 << parentDir << "/" << subDir << endmsg;
205 delete directory;
206 return 0;
207 }
208 }
209 return directory;
210 }
211 //------------------------------------------------------------------------------
212 HistogramSvc::~HistogramSvc() {
213 setDataLoader( 0 ).ignore();
214 clearStore().ignore();
215 }
216 //------------------------------------------------------------------------------
217 StatusCode HistogramSvc::connectInput(CSTR ident) {
218 MsgStream log (msgSvc(), name());
219 DataObject* pO = 0;
220 StatusCode status = this->findObject(m_rootName, pO);
221 if (status.isSuccess()) {
222 Tokenizer tok(true);
223 std::string::size_type loc = ident.find(" ");
224 std::string filename, auth, svc = "", typ = "";
225 std::string logname = ident.substr(0,loc);
226 tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'");
227 for (Tokenizer::Items::iterator i = tok.items().begin();
228 i != tok.items().end(); i++) {
229 CSTR tag = (*i).tag();
230 switch(::toupper(tag[0])) {
231 case 'F': // FILE='<file name>'
232 case 'D': // DATAFILE='<file name>'
233 filename = (*i).value();
234 break;
235 case 'T': // TYP='<HBOOK,ROOT,OBJY,...>'
236 typ = (*i).value();
237 break;
238 default:
239 break;
240 }
241 }
242 if (typ.length() > 0) {
243 // Now add the registry entry to the store
244 std::string entryname = m_rootName;
245 entryname += '/';
246 entryname += logname;
247 GenericAddress* pA = 0;
248 switch(::toupper(typ[0])) {
249 case 'H':
250 pA=new GenericAddress(HBOOK_StorageType,CLID_StatisticsFile,
251 filename,entryname,0,'O');
252 break;
253 case 'R':
254 pA=new GenericAddress(ROOT_StorageType,CLID_StatisticsFile,
255 filename,entryname,0,'O');
256 break;
257 }
258 if (0 != pA) {
259 status = registerAddress(pO, logname, pA);
260 if (status.isSuccess()) {
261 log << MSG::INFO << "Added stream file:" << filename
262 << " as " << logname << endmsg;
263 return status;
264 }
265 pA->release();
266 }
267 }
268 }
269 log << MSG::ERROR << "Cannot add " << ident << " invalid filename!" << endmsg;
270 return StatusCode::FAILURE;
271 }
272 //------------------------------------------------------------------------------
273 StatusCode HistogramSvc::initialize() {
274 MsgStream log(msgSvc(), name());
275 StatusCode status = DataSvc::initialize();
276 // Set root object
277 if (status.isSuccess()) {
278 DataObject* rootObj = new DataObject();
279 status = setRoot("/stat", rootObj);
280 if (!status.isSuccess()) {
281 log << MSG::ERROR << "Unable to set hstogram data store root." << endmsg;
282 delete rootObj;
283 return status;
284 }
285 IConversionSvc* svc = 0;
286 status = service("HistogramPersistencySvc",svc,true);
287 if ( status.isSuccess() ) {
288 setDataLoader( svc ).ignore();
289 svc->release();
290 }
291 else {
292 log << MSG::ERROR << "Could not find HistogramPersistencySvc." << endmsg;
293 return status;
294 }
295 // Connect all input streams (if any)
296 for (DBaseEntries::iterator j = m_input.begin(); j != m_input.end(); j++) {
297 status = connectInput(*j);
298 if (!status.isSuccess()) {
299 return status;
300 }
301 }
302 }
303 if ( !m_defs1D.empty() )
304 {
305 log << MSG::INFO << " Predefined 1D-Histograms: " << endmsg ;
306 for ( Histo1DMap::const_iterator ih = m_defs1D.begin() ;
307 m_defs1D.end() != ih ; ++ih )
308 {
309 log << MSG::INFO
310 << " Path='" << ih->first << "'"
311 << " Description " << ih->second << endmsg ;
312 }
313 }
314 return status;
315 }
316 //------------------------------------------------------------------------------
317 StatusCode HistogramSvc::reinitialize() {
318 return StatusCode::SUCCESS;
319 }
320 //------------------------------------------------------------------------------
321 IHistogram1D* HistogramSvc::sliceX
322 (CSTR name,const IHistogram2D& h,int idxY1,int idxY2) {
323 std::pair<DataObject*,IHistogram1D*> o(0,0);
324 try {
325 int firstbin = Gaudi::Axis::toRootIndex(idxY1,h.yAxis().bins());
326 int lastbin = Gaudi::Axis::toRootIndex(idxY2,h.yAxis().bins());
327 o = Gaudi::slice1DX(name, h, firstbin, lastbin);
328 }
329 catch ( ... ) {
330 throw GaudiException("Cannot cast 2D histogram to H2D to create sliceX `"
331 + name + "'!", "HistogramSvc", StatusCode::FAILURE);
332 }
333 if ( o.first && registerObject(name,(IBaseHistogram*)o.second).isSuccess() ) {
334 return o.second;
335 }
336 delete o.first;
337 throw GaudiException("Cannot create sliceX `" + name + "' of 2D histogram!",
338 "HistogramSvc", StatusCode::FAILURE);
339 }
340 //------------------------------------------------------------------------------
341 IHistogram1D*
342 HistogramSvc::sliceY(CSTR name,const IHistogram2D& h,int indexX1,int indexX2) {
343 std::pair<DataObject*,IHistogram1D*> o(0,0);
344 try {
345 int firstbin = Gaudi::Axis::toRootIndex( indexX1, h.xAxis().bins() );
346 int lastbin = Gaudi::Axis::toRootIndex( indexX2, h.xAxis().bins() );
347 o = Gaudi::slice1DY(name, h, firstbin, lastbin);
348 }
349 catch ( ... ) {
350 throw GaudiException("Cannot create sliceY `"+name+"'!",
351 "HistogramSvc",StatusCode::FAILURE);
352 }
353 // name stands here for the fullPath of the histogram
354 if ( o.first && registerObject(name,(IBaseHistogram*)o.second).isSuccess() ) {
355 return o.second;
356 }
357 delete o.first;
358 throw GaudiException("Cannot create sliceY `"+name+"' of 2D histogram!",
359 "HistogramSvc", StatusCode::FAILURE);
360 }
361 //------------------------------------------------------------------------------
362 bool HistogramSvc::destroy( IBaseHistogram* hist ) {
363 StatusCode sc = unregisterObject( dynamic_cast<IHistogram*>(hist) );
364 if ( !sc.isSuccess() ) return false;
365 if ( hist ) delete hist;
366 return true;
367 }
368 // ============================================================================
369 AIDA::IHistogram1D* HistogramSvc::book
370 (DataObject* pPar, CSTR rel, CSTR title, DBINS(x))
371 {
372 if ( m_defs1D.empty () )
373 { return i_book(pPar,rel,title,Gaudi::createH1D(title, BINS(x))); }
374 std::string hn = histoAddr ( pPar , rel ) ;
375 Histo1DMap::const_iterator ifound = m_defs1D.find( hn ) ;
376 if ( m_defs1D.end() == ifound )
377 { return i_book(pPar,rel,title,Gaudi::createH1D(title, BINS(x))); }
378 if (msgLevel(MSG::DEBUG)) {
379 MsgStream log ( msgSvc() , name() ) ;
380 log << MSG::DEBUG
381 << " Redefine the parameters for the histogram '" + hn + "' to be "
382 << ifound->second
383 << endmsg;
384 }
385 m_mods1D.insert ( hn ) ;
386 return i_book ( pPar , rel , ifound -> second.title () ,
387 Gaudi::createH1D
388 ( ifound -> second.title () ,
389 ifound -> second.bins () ,
390 ifound -> second.lowEdge () ,
391 ifound -> second.lowEdge () ) ) ;
392 }
393 // ============================================================================
394 // constructor
395 // ============================================================================
396 HistogramSvc::HistogramSvc(CSTR nam, ISvcLocator* svc)
397 : base_class(nam, svc)
398 , m_defs1D ()
399 , m_mods1D ()
400 {
401 // Properties can be declared here
402 m_rootName = "/stat";
403 m_rootCLID = CLID_DataObject;
404 declareProperty ( "Input", m_input);
405 declareProperty ( "Predefined1DHistos" , m_defs1D ,
406 "Histograms with predefined parameters" ) ;
407 // update handler
408 Property* p = Gaudi::Utils::getProperty ( this , "Predefined1DHistos" ) ;
409 p->declareUpdateHandler ( &HistogramSvc::update1Ddefs , this ) ;
410
411 }
412 // ============================================================================
413 // handler to be invoked for updating property m_defs1D
414 // ============================================================================
415 namespace
416 {
417 inline size_t removeLeading
418 ( HistogramSvc::Histo1DMap& m , const std::string& lead = "/stat/")
419 {
420 for ( HistogramSvc::Histo1DMap::iterator it = m.begin() ;
421 m.end() != it ; ++it )
422 {
423 if ( 0 == it->first.find ( lead ) )
424 {
425 std::string addr = std::string( it->first , lead.size() ) ;
426 Gaudi::Histo1DDef hdef = it->second ;
427 m.erase ( it ) ; // remove
428 m[addr] = hdef ; // insert
429 return 1 + removeLeading ( m , lead ) ; // return
430 }
431 }
432 return 0 ;
433 }
434 }
435 // ============================================================================
436 void HistogramSvc::update1Ddefs ( Property& )
437 {
438 // check and remove the leading '/stat/'
439 removeLeading ( m_defs1D , "/stat/" ) ;
440 }
441 // ============================================================================
442 // finalize the service
443 StatusCode HistogramSvc::finalize ()
444 {
445 if ( !m_mods1D.empty() )
446 {
447 MsgStream log ( msgSvc () , name () ) ;
448 if (msgLevel(MSG::DEBUG))
449 log << MSG::DEBUG
450 << " Substituted histograms #" << m_mods1D.size() << " : " << endmsg;
451 for ( std::set<std::string>::const_iterator ih = m_mods1D.begin() ;
452 m_mods1D.end() != ih ; ++ih )
453 {
454 if (msgLevel(MSG::DEBUG))
455 log << MSG::DEBUG << " Path='" << (*ih) << "'" ;
456 Histo1DMap::const_iterator im = m_defs1D.find( *ih ) ;
457 if ( m_defs1D.end() != im ) { log << " " << im->second ; }
458 }
459 m_mods1D.clear() ;
460 }
461 return DataSvc::finalize () ;
462 }
463 // ============================================================================
464 // The END
465 // ============================================================================