Gaudi Framework, version v23r5

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

Generated at Wed Nov 28 2012 12:17:10 for Gaudi Framework, version v23r5 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004