The Gaudi Framework  v33r1 (b1225454)
DataOnDemandSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 // ============================================================================
12 // Include files
13 // ============================================================================
14 // STD & STL
15 // ============================================================================
16 #include <map>
17 #include <math.h>
18 #include <set>
19 #include <string>
20 // ============================================================================
21 // GaudiKernel
22 // ============================================================================
24 #include "GaudiKernel/Chrono.h"
26 #include "GaudiKernel/DataObject.h"
28 #include "GaudiKernel/IAlgorithm.h"
32 #include "GaudiKernel/IToolSvc.h"
34 #include "GaudiKernel/MsgStream.h"
35 #include "GaudiKernel/Property.h"
37 #include "GaudiKernel/ToStream.h"
39 // ============================================================================
40 // Local
41 // ============================================================================
42 #include "DataOnDemandSvc.h"
43 // ============================================================================
44 // Boost
45 // ============================================================================
46 #include "boost/algorithm/string/predicate.hpp"
47 #include "boost/format.hpp"
48 // ============================================================================
49 // anonymous namespace to hide few local functions
50 // ============================================================================
51 namespace {
52  // ==========================================================================
58  inline std::string no_prefix( const std::string& value, const std::string& prefix ) {
59  return boost::algorithm::starts_with( value, prefix ) ? value.substr( prefix.size() ) : value;
60  }
61  // ==========================================================================
68  template <class MAP>
69  inline size_t add_prefix( MAP& _map, const std::string& prefix ) {
70  // empty prefix
71  if ( prefix.empty() ) { return 0; } // RETURN
73  auto it = std::find_if_not( _map.begin(), _map.end(), [&]( typename MAP::ValueType::const_reference i ) {
74  return boost::algorithm::starts_with( i.first, prefix );
75  } );
76  if ( it == _map.end() ) return 0;
77  std::string key = prefix + it->first;
78  std::string value = std::move( it->second ); // steal the value we're about to erase..
79  _map.erase( it );
80  _map[key] = std::move( value ); // and move it into its new location
81  return 1 + add_prefix( _map, prefix ); // RETURN, recursion
82  //
83  }
84  // ==========================================================================
90  template <class SET>
91  inline size_t get_dir( const std::string& object, SET& _set ) {
92  std::string::size_type ifind = object.rfind( '/' );
93  // stop recursion
94  if ( std::string::npos == ifind ) { return 0; } // RETURN
95  if ( 0 == ifind ) { return 0; }
96  //
97  const std::string top = std::string( object, 0, ifind );
98  _set.insert( top );
99  return 1 + get_dir( top, _set ); // RETURN, recursion
100  }
101  // ==========================================================================
107  template <class MAP, class SET>
108  inline size_t get_dirs( const MAP& _map, SET& _set ) {
109  size_t size = _set.size();
110  for ( const auto& item : _map ) { get_dir( item.first, _set ); }
111  return _set.size() - size;
112  }
113  // ==========================================================================
114 } // end of anonymous namespace
115 
117  ClassH cl = TClass::GetClass( type.c_str() );
118  if ( !cl ) { warning() << "Failed to access dictionary class for " << name << " of type:" << type << endmsg; }
119  m_nodes[name] = Node( cl, false, type );
120 }
121 
123  Leaf leaf( alg.type(), alg.name() );
124  if ( m_init ) {
125  StatusCode sc = configureHandler( leaf );
126  if ( sc.isFailure() ) {
127  if ( m_allowInitFailure ) {
128  // re-store the content of the leaf object to try again to initialize
129  // the algorithm later (on demand)
130  leaf = Leaf( alg.type(), alg.name() );
131  } else
132  return sc;
133  }
134  }
135  m_algs[name] = leaf;
136  return StatusCode::SUCCESS;
137 }
138 
139 // ============================================================================
140 // update the content of Data-On-Demand actions
141 // ============================================================================
143  if ( !m_updateRequired ) { return StatusCode::SUCCESS; }
144 
146  StatusCode sc = setupNodeHandlers(); // convert "Nodes" new "NodeMap"
147  if ( sc.isFailure() ) {
148  error() << "Failed to setup old \"Nodes\"" << endmsg;
149  return sc;
150  }
152  sc = setupAlgHandlers(); // convert "Algorithms" into "AlgMap"
153  if ( sc.isFailure() ) {
154  error() << "Failed to setup old \"Algorithms\"" << endmsg;
155  return sc;
156  }
158  add_prefix( m_algMap, m_prefix );
160  add_prefix( m_nodeMap, m_prefix );
163  if ( m_partialPath ) { get_dirs( m_algMap, dirs ); }
164  if ( m_partialPath ) { get_dirs( m_nodeMap, dirs ); }
165  //
166  auto _e = dirs.find( "/Event" );
167  if ( dirs.end() != _e ) { dirs.erase( _e ); }
168  // add all directories as nodes
169  for ( const auto& dir : dirs ) {
170  if ( m_algMap.end() == m_algMap.find( dir ) && m_nodeMap.end() == m_nodeMap.find( dir ) )
171  m_nodeMap[dir] = "DataObject";
172  }
173  //
174  m_algs.clear();
175  m_nodes.clear();
176  //
178  for ( const auto& alg : m_algMap ) {
179  if ( i_setAlgHandler( alg.first, alg.second ).isFailure() ) return StatusCode::FAILURE;
180  }
182  for ( const auto& node : m_nodeMap ) { i_setNodeHandler( node.first, node.second ); }
184  m_updateRequired = false;
185  //
186  return StatusCode::SUCCESS;
187 }
188 //=============================================================================
189 // Inherited Service overrides:
190 //=============================================================================
192  // initialize the Service Base class
194  if ( sc.isFailure() ) { return sc; }
195  sc = setup();
196  if ( sc.isFailure() ) { return sc; }
197  //
198  if ( m_dump ) {
199  dump( MSG::INFO );
200  } else if ( msgLevel( MSG::DEBUG ) ) {
201  dump( MSG::DEBUG );
202  }
203  //
204  if ( m_init ) { return update(); }
205  //
206  return StatusCode::SUCCESS;
207 }
208 // ============================================================================
209 // finalization of the service
210 // ============================================================================
212  //
213  info() << "Handled \"" << m_trapType.value() << "\" incidents: " << m_statAlg << "/" << m_statNode << "/" << m_stat
214  << "(Alg/Node/Total)." << endmsg;
215  if ( m_dump || msgLevel( MSG::DEBUG ) ) {
216  info() << m_total.outputUserTime( "Algorithm timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] ",
218  << m_total.outputUserTime( "Total:%2%[s]", System::Sec ) << endmsg;
219  info() << m_timer_nodes.outputUserTime( "Nodes timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] ",
221  << m_timer_nodes.outputUserTime( "Total:%2%[s]", System::Sec ) << endmsg;
222  info() << m_timer_algs.outputUserTime( "Algs timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] ",
224  << m_timer_algs.outputUserTime( "Total:%2%[s]", System::Sec ) << endmsg;
225  info() << m_timer_all.outputUserTime( "All timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] ",
227  << m_timer_all.outputUserTime( "Total:%2%[s]", System::Sec ) << endmsg;
228  }
229  // dump it!
230  if ( m_dump ) {
231  dump( MSG::INFO, false );
232  } else if ( msgLevel( MSG::DEBUG ) ) {
233  dump( MSG::DEBUG, false );
234  }
235  //
236  if ( m_incSvc ) {
238  m_incSvc.reset();
239  }
240  m_algMgr.reset();
241  m_dataSvc.reset();
242  if ( m_toolSvc ) { // we may not have retrieved the ToolSvc
243  // Do not call releaseTool if the ToolSvc was already finalized.
245  for ( const auto& i : m_nodeMappers ) m_toolSvc->releaseTool( i ).ignore();
246  for ( const auto& i : m_algMappers ) m_toolSvc->releaseTool( i ).ignore();
247  } else {
248  warning() << "ToolSvc already finalized: cannot release tools. Check options." << endmsg;
249  }
252  m_toolSvc.reset();
253  }
254  return Service::finalize();
255 }
256 // ============================================================================
258 // ============================================================================
260  // reinitialize the Service Base class
261  if ( m_incSvc ) {
263  m_incSvc.reset();
264  }
265  m_algMgr.reset();
266  m_dataSvc.reset();
267  for ( const auto& i : m_nodeMappers ) m_toolSvc->releaseTool( i ).ignore();
269  for ( const auto& i : m_algMappers ) m_toolSvc->releaseTool( i ).ignore();
271  m_toolSvc.reset();
272  //
274  if ( sc.isFailure() ) { return sc; }
275  //
276  sc = setup();
277  if ( sc.isFailure() ) { return sc; }
278  //
279  if ( m_dump ) {
280  dump( MSG::INFO );
281  } else if ( msgLevel( MSG::DEBUG ) ) {
282  dump( MSG::DEBUG );
283  }
284  //
285  return StatusCode::SUCCESS;
286 }
287 // ============================================================================
288 // setup service
289 // ============================================================================
291  if ( !( m_algMgr = serviceLocator() ) ) // assignment meant
292  {
293  error() << "Failed to retrieve the IAlgManager interface." << endmsg;
294  return StatusCode::FAILURE;
295  }
296 
297  if ( !( m_incSvc = serviceLocator()->service( "IncidentSvc" ) ) ) // assignment meant
298  {
299  error() << "Failed to retrieve Incident service." << endmsg;
300  return StatusCode::FAILURE;
301  }
302  m_incSvc->addListener( this, m_trapType );
303 
304  if ( !( m_dataSvc = serviceLocator()->service( m_dataSvcName ) ) ) // assignment meant
305  {
306  error() << "Failed to retrieve the data provider interface of " << m_dataSvcName << endmsg;
307  return StatusCode::FAILURE;
308  }
309 
310  // No need to get the ToolSvc if we are not using tools
311  if ( !( m_nodeMapTools.empty() && m_algMapTools.empty() ) ) {
312  if ( !( m_toolSvc = serviceLocator()->service( "ToolSvc" ) ) ) // assignment meant
313  {
314  error() << "Failed to retrieve ToolSvc" << endmsg;
315  return StatusCode::FAILURE;
316  }
317 
318  // load the node mapping tools
319  IDODNodeMapper* nodetool = nullptr;
320  for ( const auto& i : m_nodeMapTools ) {
321  const StatusCode sc = m_toolSvc->retrieveTool( i, nodetool );
322  if ( sc.isFailure() ) return sc;
323  m_nodeMappers.push_back( nodetool );
324  }
325  IDODAlgMapper* algtool = nullptr;
326  for ( const auto& i : m_algMapTools ) {
327  const StatusCode sc = m_toolSvc->retrieveTool( i, algtool );
328  if ( sc.isFailure() ) return sc;
329  m_algMappers.push_back( algtool );
330  }
331  }
332  return update();
333 }
334 // ============================================================================
335 // setup node handlers
336 // ============================================================================
338  std::string nam, typ, tag;
340  // Setup for node leafs, where simply a constructor is called...
341  for ( auto node : m_nodeMapping ) {
342  using Parser = Gaudi::Utils::AttribStringParser;
343  for ( auto attrib : Parser( node ) ) {
344  switch ( ::toupper( attrib.tag[0] ) ) {
345  case 'D':
346  tag = std::move( attrib.value );
347  break;
348  case 'T':
349  nam = std::move( attrib.value );
350  break;
351  }
352  }
353  if ( m_algMap.end() != m_algMap.find( tag ) || m_nodeMap.end() != m_nodeMap.find( tag ) ) {
354  warning() << "The obsolete property 'Nodes' redefines the action for '" + tag + "' to be '" + nam + "'" << endmsg;
355  }
356  m_nodeMap[tag] = nam;
357  }
358  //
359  m_updateRequired = true;
360  //
361  return sc;
362 }
363 // ============================================================================
364 // setup algorithm handlers
365 // ============================================================================
367  std::string typ, tag;
368 
369  for ( auto alg : m_algMapping ) {
370  using Parser = Gaudi::Utils::AttribStringParser;
371  for ( auto attrib : Parser( alg ) ) {
372  switch ( ::toupper( attrib.tag[0] ) ) {
373  case 'D':
374  tag = std::move( attrib.value );
375  break;
376  case 'T':
377  typ = std::move( attrib.value );
378  break;
379  }
380  }
381  Gaudi::Utils::TypeNameString item( typ );
382  if ( m_algMap.end() != m_algMap.find( tag ) || m_nodeMap.end() != m_nodeMap.find( tag ) ) {
383  warning() << "The obsolete property 'Algorithms' redefines the action for '" + tag + "' to be '" + item.type() +
384  "/" + item.name() + "'"
385  << endmsg;
386  }
387  m_algMap[tag] = item.type() + "/" + item.name();
388  }
389  m_updateRequired = true;
390  return StatusCode::SUCCESS;
391 }
392 // ============================================================================
394 // ============================================================================
396  if ( l.algorithm ) { return StatusCode::SUCCESS; }
397  if ( !m_algMgr ) { return StatusCode::FAILURE; }
398  l.algorithm = m_algMgr->algorithm( l.name, false );
399  if ( l.algorithm ) { return StatusCode::SUCCESS; }
400  // create it!
401  StatusCode sc = m_algMgr->createAlgorithm( l.type, l.name, l.algorithm, true );
402  if ( sc.isFailure() ) {
403  error() << "Failed to create algorithm " << l.type << "('" << l.name << "')" << endmsg;
404  l.algorithm = nullptr;
405  return sc; // RETURN
406  }
407  if ( l.algorithm->isInitialized() ) { return StatusCode::SUCCESS; }
408  // initialize it!
409  sc = l.algorithm->sysInitialize();
410  if ( sc.isFailure() ) {
411  error() << "Failed to initialize algorithm " << l.type << "('" << l.name << "')" << endmsg;
412  l.algorithm = nullptr;
413  return sc; // RETURN
414  }
415  if ( Gaudi::StateMachine::RUNNING == l.algorithm->FSMState() ) { return StatusCode::SUCCESS; }
416  // run it!
417  sc = l.algorithm->sysStart();
418  if ( sc.isFailure() ) {
419  error() << "Failed to 'run' algorithm " << l.type << "('" << l.name << "')" << endmsg;
420  l.algorithm = nullptr;
421  return sc; // RETURN
422  }
423  return StatusCode::SUCCESS;
424 }
425 
426 // local algorithms
427 namespace {
430  struct ToolGetter {
434  ToolGetter( std::string _path ) : path( std::move( _path ) ) {}
436  inline std::string operator()( IDODNodeMapper* t ) const { return t->nodeTypeForPath( path ); }
438  inline Gaudi::Utils::TypeNameString operator()( IDODAlgMapper* t ) const { return t->algorithmForPath( path ); }
439  };
440 
443  inline bool isGood( const std::string& r ) { return !r.empty(); }
444  inline bool isGood( const Gaudi::Utils::TypeNameString& r ) { return !r.name().empty(); }
446 
449  class Finder {
450  const ToolGetter getter;
451  const std::vector<IDODNodeMapper*>& nodes;
452  const std::vector<IDODAlgMapper*>& algs;
454  template <class R, class C>
455  R find( const C& l ) const {
456  for ( auto& i : l ) {
457  auto result = getter( i );
458  if ( isGood( result ) ) return result;
459  }
460  return R{""};
461  }
462 
463  public:
465  Finder( std::string _path, const std::vector<IDODNodeMapper*>& _nodes, const std::vector<IDODAlgMapper*>& _algs )
466  : getter( std::move( _path ) ), nodes( _nodes ), algs( _algs ) {}
468  inline std::string node() const { return find<std::string>( nodes ); }
470  inline Gaudi::Utils::TypeNameString alg() const { return find<Gaudi::Utils::TypeNameString>( algs ); }
471  };
472 } // namespace
473 
474 // ===========================================================================
475 // IIncidentListener interfaces overrides: incident handling
476 // ===========================================================================
477 void DataOnDemandSvc::handle( const Incident& incident ) {
478 
480 
481  ++m_stat;
482  // proper incident type?
483  if ( incident.type() != m_trapType ) { return; } // RETURN
484  const DataIncident* inc = dynamic_cast<const DataIncident*>( &incident );
485  if ( !inc ) { return; } // RETURN
486  // update if needed!
487  if ( m_updateRequired ) {
488  if ( !update() ) throw GaudiException( "Failed to update", name(), StatusCode::FAILURE );
489  }
490 
491  if ( msgLevel( MSG::VERBOSE ) ) {
492  verbose() << "Incident: [" << incident.type() << "] "
493  << " = " << incident.source() << " Location:" << inc->tag() << endmsg;
494  }
495  // ==========================================================================
496  Gaudi::StringKey tag( inc->tag() );
497  // ==========================================================================
498  auto icl = m_nodes.find( tag );
499  if ( icl != m_nodes.end() ) {
500  StatusCode sc = execHandler( tag, icl->second );
501  if ( sc.isSuccess() ) { ++m_statNode; }
502  return; // RETURN
503  }
504  // ==========================================================================
505  auto ialg = m_algs.find( tag );
506  if ( ialg != m_algs.end() ) {
507  StatusCode sc = execHandler( tag, ialg->second );
508  if ( sc.isSuccess() ) { ++m_statAlg; }
509  return; // RETURN
510  }
511  // ==========================================================================
512  // Fall back on the tools
513  if ( m_toolSvc ) {
514  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "Try to find mapping with mapping tools" << endmsg;
515  Finder finder( no_prefix( inc->tag(), m_prefix ), m_nodeMappers, m_algMappers );
516  // - try the node mappers
517  std::string node = finder.node();
518  if ( isGood( node ) ) {
519  // if one is found update the internal node mapping and try again.
520  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "Found Node handler: " << node << endmsg;
521  i_setNodeHandler( inc->tag(), node );
522  handle( incident );
523  --m_stat; // avoid double counting because of recursion
524  return;
525  }
526  // - try alg mappings
527  Gaudi::Utils::TypeNameString alg = finder.alg();
528  if ( isGood( alg ) ) {
529  // we got an algorithm, update alg map and try to handle again
530  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "Found Algorithm handler: " << alg << endmsg;
531  i_setAlgHandler( inc->tag(), alg ).ignore();
532  handle( incident );
533  --m_stat; // avoid double counting because of recursion
534  return;
535  }
536  }
537 }
538 // ===========================================================================
539 // execute the handler
540 // ===========================================================================
542 
544 
545  if ( n.executing ) { return StatusCode::FAILURE; } // RETURN
546 
547  Protection p( n.executing );
548 
550 
551  if ( n.dataObject ) {
552  object.reset( new DataObject() );
553  } else {
554  // try to recover the handler
555  if ( !n.clazz ) { n.clazz = TClass::GetClass( n.name.c_str() ); }
556  if ( !n.clazz ) {
557  error() << "Failed to get dictionary for class '" << n.name << "' for location:" << tag << endmsg;
558  return StatusCode::FAILURE; // RETURN
559  }
560 
561  object.reset( reinterpret_cast<DataObject*>( n.clazz->New() ) );
562 
563  if ( !object ) {
564  error() << "Failed to create an object of type:" << n.clazz->GetName() << " for location:" << tag << endmsg;
565  return StatusCode::FAILURE; // RETURN
566  }
567  }
568  //
569  StatusCode sc = m_dataSvc->registerObject( tag, object.release() );
570  if ( sc.isFailure() ) {
571  error() << "Failed to register an object of type:" << n.name << " at location:" << tag << endmsg;
572  return sc; // RETURN
573  }
574  ++n.num;
575  //
576  return StatusCode::SUCCESS;
577 }
578 // ===========================================================================
579 // execute the handler
580 // ===========================================================================
583  //
584  if ( l.executing ) { return StatusCode::FAILURE; } // RETURN
585  //
586  if ( !l.algorithm ) {
587  StatusCode sc = configureHandler( l );
588  if ( sc.isFailure() ) {
589  error() << "Failed to configure handler for: " << l.name << "[" << l.type << "] " << tag << endmsg;
590  return sc; // RETURN
591  }
592  }
593  //
594  Chrono atimer( m_total );
595  //
596  Protection p( l.executing );
597  // FIXME: this will cause problems for Hive, as we need to set
598  // the EventContext of the called Algorithm.
599  // if (!l.algorithm->getContext()) {
600  // l.algorithm->setContext( &Gaudi::Hive::currentContext() );
601  // }
602  StatusCode sc = l.algorithm->sysExecute( Gaudi::Hive::currentContext() );
603  if ( sc.isFailure() ) {
604  error() << "Failed to execute the algorithm:" << l.algorithm->name() << " for location:" << tag << endmsg;
605  return sc; // RETURN
606  }
607  ++l.num;
608  //
609  return StatusCode::SUCCESS;
610 }
611 // ============================================================================
612 /* dump the content of DataOnDemand service
613  * @param level the printout level
614  * @param mode the printout mode
615  */
616 // ============================================================================
617 void DataOnDemandSvc::dump( const MSG::Level level, const bool mode ) const {
618  if ( m_algs.empty() && m_nodes.empty() ) { return; }
619 
622  for ( auto& alg : m_algs ) {
623  auto check = _m.find( alg.first );
624  if ( _m.end() != check ) {
625  warning() << " The data item is activated for '" << check->first << "' as '" << check->second.first << "'"
626  << endmsg;
627  }
628  const Leaf& l = alg.second;
629  std::string nam = ( l.name == l.type ? l.type : ( l.type + "/" + l.name ) );
630  //
631  if ( !mode && 0 == l.num ) { continue; }
632  //
633  std::string val;
634  if ( mode ) {
635  val = ( !l.algorithm ) ? "F" : "T";
636  } else {
637  val = std::to_string( l.num );
638  }
639  //
640  _m[no_prefix( alg.first, m_prefix )] = {nam, val};
641  }
642  // nodes:
643  for ( const auto& node : m_nodes ) {
644  auto check = _m.find( node.first );
645  if ( _m.end() != check ) {
646  warning() << " The data item is already activated for '" << check->first << "' as '" << check->second.first << "'"
647  << endmsg;
648  }
649  const Node& n = node.second;
650  std::string nam = "'" + n.name + "'";
651  //
652  std::string val;
653 
654  if ( !mode && 0 == n.num ) { continue; }
655 
656  if ( mode ) {
657  val = ( 0 == n.clazz ) ? "F" : "T";
658  } else {
659  val = std::to_string( n.num );
660  }
661  //
662  _m[no_prefix( node.first, m_prefix )] = {nam, val};
663  }
664  //
665  if ( _m.empty() ) { return; }
666 
667  // find the correct formats
668  size_t n1 = 0;
669  size_t n2 = 0;
670  size_t n3 = 0;
671  for ( const auto& i : _m ) {
672  n1 = std::max( n1, i.first.size() );
673  n2 = std::max( n2, i.second.first.size() );
674  n3 = std::max( n3, i.second.second.size() );
675  }
676  if ( 10 > n1 ) { n1 = 10; }
677  if ( 10 > n2 ) { n2 = 10; }
678  if ( 60 < n1 ) { n1 = 60; }
679  if ( 60 < n2 ) { n2 = 60; }
680  //
681 
682  const std::string _f = " | %%1$-%1%.%1%s | %%2$-%2%.%2%s | %%3$%3%.%3%s |";
683  boost::format _ff( _f );
684  _ff % n1 % n2 % n3;
685 
686  const std::string _format = _ff.str();
687 
688  auto& msg = msgStream( level );
689 
690  if ( mode ) {
691  msg << "Data-On-Demand Actions enabled for:";
692  } else {
693  msg << "Data-On-Demand Actions has been used for:";
694  }
695 
696  boost::format fmt1( _format );
697  fmt1 % "Address" % "Creator" % ( mode ? "S" : "#" );
698  //
699  const std::string header = fmt1.str();
700  std::string line = std::string( header.size(), '-' );
701  line[0] = ' ';
702 
703  msg << '\n' << line << '\n' << header << '\n' << line;
704 
705  // make the actual printout:
706  for ( const auto& item : _m ) {
707  boost::format fmt( _format );
708  msg << '\n' << ( fmt % item.first % item.second.first % item.second.second );
709  }
710 
711  msg << '\n' << line << endmsg;
712 }
713 // ============================================================================
718 // ============================================================================
719 
720 // ============================================================================
721 // The END
722 // ============================================================================
void i_setNodeHandler(const std::string &name, const std::string &type)
Internal method to initialize a node handler.
Parse attribute strings allowing iteration over the various attributes.
virtual SmartIF< IAlgorithm > & algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
constexpr auto size(const T &, Args &&...) noexcept
ChronoEntity m_timer_all
StatusCode initialize() override
Definition: Service.cpp:70
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: Service.cpp:287
T empty(T... args)
Define general base for Gaudi exception.
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
The DataOnDemandSvc listens to incidents typically triggered by the data service of the configurable ...
StatusCode finalize() override
Definition: Service.cpp:174
ChronoEntity m_timer_algs
Gaudi::StateMachine::State FSMState() const override
Definition: Service.h:62
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
const std::string & type() const
Access to the incident type.
Definition: Incident.h:48
SmartIF< IIncidentSvc > m_incSvc
Incident service.
void handle(const Incident &incident) override
IIncidentListener interfaces overrides: incident handling.
T to_string(T... args)
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
Gaudi::Property< std::string > m_trapType
STL namespace.
Gaudi::Property< Map > m_nodeMap
const std::string & type() const
T end(T... args)
Gaudi::Property< bool > m_init
A small utility class for chronometry of user codes.
Definition: Chrono.h:35
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
#define SET(x)
StatusCode initialize() override
Inherited Service overrides: Service initialization.
STL class.
GAUDI_API std::string header(const int ID=Default)
get the recommended header by enum
void dump(const MSG::Level level, const bool mode=true) const
dump the content of DataOnDemand service
The helper class to represent the efficient "key" for access.
Definition: StringKey.h:44
const std::string & source() const
Access to the source of the incident.
Definition: Incident.h:54
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
STL class.
#define DECLARE_COMPONENT(type)
SmartIF< IDataProviderSvc > m_dataSvc
Data provider reference.
Gaudi::Property< Setup > m_algMapping
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:86
Gaudi::Property< std::vector< std::string > > m_algMapTools
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:284
T push_back(T... args)
Interface of tools used by the DataOnDemandSvc to choose the type of node to be created at a path.
Gaudi::Property< std::string > m_prefix
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
unsigned long long m_stat
Gaudi::Property< std::vector< std::string > > m_nodeMapTools
iterator end()
Definition: Map.h:140
Helper class to parse a string of format "type/name".
Gaudi::Property< Map > m_algMap
StatusCode setup()
Setup routine (called by (re-) initialize.
StatusCode execHandler(const std::string &tag, Leaf &leaf)
Execute leaf handler (algorithm)
const std::string & name() const
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
StatusCode setupNodeHandlers()
Initialize node handlers.
T erase(T... args)
iterator find(const key_type &key)
Definition: Map.h:157
Helper class of the DataOnDemandSvc.
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
virtual Gaudi::Utils::TypeNameString algorithmForPath(const std::string &path)=0
For the given path, returns a TypeNameString object identifying the algorithm to be run to produce th...
GAUDI_API const EventContext & currentContext()
NodeMap m_nodes
Map of "empty" objects to be placed as intermediate nodes.
string prefix
Definition: gaudirun.py:343
StatusCode reinitialize() override
Definition: Service.cpp:247
T clear(T... args)
MsgStream & msgStream() const
Return an uninitialized MsgStream.
bool isSuccess() const
Definition: StatusCode.h:365
T max(T... args)
T move(T... args)
dictionary l
Definition: gaudirun.py:543
Gaudi::Property< bool > m_partialPath
std::vector< IDODNodeMapper * > m_nodeMappers
T find_if_not(T... args)
T size(T... args)
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:168
Interface of tools used by the DataOnDemandSvc to choose the algorithm to be run to produce the data ...
Definition: IDODAlgMapper.h:27
SmartIF< IAlgManager > m_algMgr
Algorithm manager.
STL class.
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
SmartIF< IToolSvc > m_toolSvc
Data provider reference.
StatusCode registerObject(std::string_view fullPath, DataObject *pObject)
Register object with the data store.
Helper object, useful for measurement of CPU-performance of highly-recursive structures,...
Definition: LockedChrono.h:60
AlgMap m_algs
Map of algorithms to handle incidents.
StatusCode retrieveTool(std::string_view type, T *&tool, const IInterface *parent=nullptr, bool createIf=true)
Retrieve specified tool sub-type with tool dependent part of the name automatically assigned.
Definition: IToolSvc.h:148
Gaudi::Property< Setup > m_nodeMapping
ChronoEntity m_timer_nodes
bool empty() const
Definition: Map.h:201
Gaudi::Property< std::string > m_dataSvcName
Base class for all Incidents (computing events).
Definition: Incident.h:27
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
StatusCode finalize() override
Inherited Service overrides: Service finalization.
constexpr static const auto FAILURE
Definition: StatusCode.h:101
virtual StatusCode createAlgorithm(std::string algtype, std::string algname, IAlgorithm *&alg, bool managed=false, bool checkIfExists=true)=0
Create an instance of a algorithm type that has been declared beforehand and assigns to it a name.
T substr(T... args)
void clear()
Definition: Map.h:195
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn't already exist.
Definition: Service.h:93
virtual StatusCode releaseTool(IAlgTool *tool)=0
Release the tool.
ChronoEntity m_total
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:96
virtual void removeListener(IIncidentListener *lis, const std::string &type="")=0
Remove listener.
bool isFailure() const
Definition: StatusCode.h:145
Data service incident class.
implementation of various functions for streaming.
StatusCode setupAlgHandlers()
Initialize leaf handlers.
Helper class of the DataOnDemandSvc.
virtual std::string nodeTypeForPath(const std::string &path)=0
For the given path, returns a the type name of the object to be created at the path.
StatusCode i_setAlgHandler(const std::string &name, const Gaudi::Utils::TypeNameString &alg)
Internal method to initialize an algorithm handler.
Gaudi::Property< bool > m_dump
StatusCode configureHandler(Leaf &leaf)
Configure handler for leaf.
void toupper(std::string &s)
Gaudi::Property< bool > m_allowInitFailure
std::vector< IDODAlgMapper * > m_algMappers
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
unsigned long long m_statNode
unsigned long long m_statAlg
StatusCode reinitialize() override
Inherited Service overrides: Service reinitialization.
StatusCode update()
update the handlers
std::string outputUserTime() const
print the chrono ;