All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
DataOnDemandSvc.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // STD & STL
5 // ============================================================================
6 #include <map>
7 #include <math.h>
8 #include <set>
9 #include <string>
10 // ============================================================================
11 // GaudiKernel
12 // ============================================================================
14 #include "GaudiKernel/Chrono.h"
16 #include "GaudiKernel/DataObject.h"
18 #include "GaudiKernel/IAlgorithm.h"
22 #include "GaudiKernel/IToolSvc.h"
24 #include "GaudiKernel/MsgStream.h"
25 #include "GaudiKernel/Property.h"
26 #include "GaudiKernel/ToStream.h"
28 // ============================================================================
29 // Local
30 // ============================================================================
31 #include "DataOnDemandSvc.h"
32 // ============================================================================
33 // Boost
34 // ============================================================================
35 #include "boost/algorithm/string/predicate.hpp"
36 #include "boost/format.hpp"
37 // ============================================================================
38 // Constructors and Destructor
39 // ============================================================================
41 {
42  m_dump.declareUpdateHandler( [this]( Gaudi::Details::PropertyBase& ) {
44  dump( MSG::ALWAYS );
45  }
46  } );
47 
48  auto force_update = [this]( Gaudi::Details::PropertyBase& p ) {
49  verbose() << "updated property " << p.name() << ", forcig update" << endmsg;
50  m_updateRequired = true;
51  };
52  m_algMap.declareUpdateHandler( force_update );
53  m_nodeMap.declareUpdateHandler( force_update );
54 
55  auto deprecated_property = [this, force_update]( Gaudi::Details::PropertyBase& p ) {
56  warning() << p.name() << " " << p.documentation() << endmsg;
57  force_update( p );
58  };
59  m_algMapping.declareUpdateHandler( deprecated_property );
60  m_nodeMapping.declareUpdateHandler( deprecated_property );
61  // ==========================================================================
62 }
63 // ============================================================================
64 // anonymous namespace to hide few local functions
65 // ============================================================================
66 namespace
67 {
68  // ==========================================================================
74  inline std::string no_prefix( const std::string& value, const std::string& prefix )
75  {
76  return boost::algorithm::starts_with( value, prefix ) ? value.substr( prefix.size() ) : value;
77  }
78  // ==========================================================================
85  template <class MAP>
86  inline size_t add_prefix( MAP& _map, const std::string& prefix )
87  {
88  // empty prefix
89  if ( prefix.empty() ) {
90  return 0;
91  } // RETURN
93  auto it = std::find_if_not( _map.begin(), _map.end(), [&]( typename MAP::ValueType::const_reference i ) {
94  return boost::algorithm::starts_with( i.first, prefix );
95  } );
96  if ( it == _map.end() ) return 0;
97  std::string key = prefix + it->first;
98  std::string value = std::move( it->second ); // steal the value we're about to erase..
99  _map.erase( it );
100  _map[key] = std::move( value ); // and move it into its new location
101  return 1 + add_prefix( _map, prefix ); // RETURN, recursion
102  //
103  }
104  // ==========================================================================
110  template <class SET>
111  inline size_t get_dir( const std::string& object, SET& _set )
112  {
113  std::string::size_type ifind = object.rfind( '/' );
114  // stop recursion
115  if ( std::string::npos == ifind ) {
116  return 0;
117  } // RETURN
118  if ( 0 == ifind ) {
119  return 0;
120  }
121  //
122  const std::string top = std::string( object, 0, ifind );
123  _set.insert( top );
124  return 1 + get_dir( top, _set ); // RETURN, recursion
125  }
126  // ==========================================================================
132  template <class MAP, class SET>
133  inline size_t get_dirs( const MAP& _map, SET& _set )
134  {
135  size_t size = _set.size();
136  for ( const auto& item : _map ) {
137  get_dir( item.first, _set );
138  }
139  return _set.size() - size;
140  }
141  // ==========================================================================
142 } // end of anonymous namespace
143 
145 {
146  ClassH cl = TClass::GetClass( type.c_str() );
147  if ( !cl ) {
148  warning() << "Failed to access dictionary class for " << name << " of type:" << type << endmsg;
149  }
150  m_nodes[name] = Node( cl, false, type );
151 }
152 
154 {
155  Leaf leaf( alg.type(), alg.name() );
156  if ( m_init ) {
157  StatusCode sc = configureHandler( leaf );
158  if ( sc.isFailure() ) {
159  if ( m_allowInitFailure ) {
160  // re-store the content of the leaf object to try again to initialize
161  // the algorithm later (on demand)
162  leaf = Leaf( alg.type(), alg.name() );
163  } else
164  return sc;
165  }
166  }
167  m_algs[name] = leaf;
168  return StatusCode::SUCCESS;
169 }
170 
171 // ============================================================================
172 // update the content of Data-On-Demand actions
173 // ============================================================================
175 {
176  if ( !m_updateRequired ) {
177  return StatusCode::SUCCESS;
178  }
179 
181  StatusCode sc = setupNodeHandlers(); // convert "Nodes" new "NodeMap"
182  if ( sc.isFailure() ) {
183  error() << "Failed to setup old \"Nodes\"" << endmsg;
184  return sc;
185  }
187  sc = setupAlgHandlers(); // convert "Algorithms" into "AlgMap"
188  if ( sc.isFailure() ) {
189  error() << "Failed to setup old \"Algorithms\"" << endmsg;
190  return sc;
191  }
193  add_prefix( m_algMap, m_prefix );
195  add_prefix( m_nodeMap, m_prefix );
198  if ( m_partialPath ) {
199  get_dirs( m_algMap, dirs );
200  }
201  if ( m_partialPath ) {
202  get_dirs( m_nodeMap, dirs );
203  }
204  //
205  auto _e = dirs.find( "/Event" );
206  if ( dirs.end() != _e ) {
207  dirs.erase( _e );
208  }
209  // add all directories as nodes
210  for ( const auto& dir : dirs ) {
211  if ( m_algMap.end() == m_algMap.find( dir ) && m_nodeMap.end() == m_nodeMap.find( dir ) )
212  m_nodeMap[dir] = "DataObject";
213  }
214  //
215  m_algs.clear();
216  m_nodes.clear();
217  //
219  for ( const auto& alg : m_algMap ) {
220  if ( i_setAlgHandler( alg.first, alg.second ).isFailure() ) return StatusCode::FAILURE;
221  }
223  for ( const auto& node : m_nodeMap ) {
224  i_setNodeHandler( node.first, node.second );
225  }
227  m_updateRequired = false;
228  //
229  return StatusCode::SUCCESS;
230 }
231 //=============================================================================
232 // Inherited Service overrides:
233 //=============================================================================
235 {
236  // initialize the Service Base class
238  if ( sc.isFailure() ) {
239  return sc;
240  }
241  sc = setup();
242  if ( sc.isFailure() ) {
243  return sc;
244  }
245  //
246  if ( m_dump ) {
247  dump( MSG::INFO );
248  } else if ( msgLevel( MSG::DEBUG ) ) {
249  dump( MSG::DEBUG );
250  }
251  //
252  if ( m_init ) {
253  return update();
254  }
255  //
256  return StatusCode::SUCCESS;
257 }
258 // ============================================================================
259 // finalization of the service
260 // ============================================================================
262 {
263  //
264  info() << "Handled \"" << m_trapType.value() << "\" incidents: " << m_statAlg << "/" << m_statNode << "/" << m_stat
265  << "(Alg/Node/Total)." << endmsg;
266  if ( m_dump || msgLevel( MSG::DEBUG ) ) {
267  info() << m_total.outputUserTime( "Algorithm timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] ",
269  << m_total.outputUserTime( "Total:%2%[s]", System::Sec ) << endmsg;
270  info() << m_timer_nodes.outputUserTime( "Nodes timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] ",
272  << m_timer_nodes.outputUserTime( "Total:%2%[s]", System::Sec ) << endmsg;
273  info() << m_timer_algs.outputUserTime( "Algs timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] ",
275  << m_timer_algs.outputUserTime( "Total:%2%[s]", System::Sec ) << endmsg;
276  info() << m_timer_all.outputUserTime( "All timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] ",
278  << m_timer_all.outputUserTime( "Total:%2%[s]", System::Sec ) << endmsg;
279  }
280  // dump it!
281  if ( m_dump ) {
282  dump( MSG::INFO, false );
283  } else if ( msgLevel( MSG::DEBUG ) ) {
284  dump( MSG::DEBUG, false );
285  }
286  //
287  if ( m_incSvc ) {
289  m_incSvc.reset();
290  }
291  m_algMgr.reset();
292  m_dataSvc.reset();
293  if ( m_toolSvc ) { // we may not have retrieved the ToolSvc
294  // Do not call releaseTool if the ToolSvc was already finalized.
296  for ( const auto& i : m_nodeMappers ) m_toolSvc->releaseTool( i ).ignore();
297  for ( const auto& i : m_algMappers ) m_toolSvc->releaseTool( i ).ignore();
298  } else {
299  warning() << "ToolSvc already finalized: cannot release tools. Check options." << endmsg;
300  }
303  m_toolSvc.reset();
304  }
305  return Service::finalize();
306 }
307 // ============================================================================
309 // ============================================================================
311 {
312  // reinitialize the Service Base class
313  if ( m_incSvc ) {
315  m_incSvc.reset();
316  }
317  m_algMgr.reset();
318  m_dataSvc.reset();
319  for ( const auto& i : m_nodeMappers ) m_toolSvc->releaseTool( i ).ignore();
320  m_nodeMappers.clear();
321  for ( const auto& i : m_algMappers ) m_toolSvc->releaseTool( i ).ignore();
322  m_algMappers.clear();
323  m_toolSvc.reset();
324  //
326  if ( sc.isFailure() ) {
327  return sc;
328  }
329  //
330  sc = setup();
331  if ( sc.isFailure() ) {
332  return sc;
333  }
334  //
335  if ( m_dump ) {
336  dump( MSG::INFO );
337  } else if ( msgLevel( MSG::DEBUG ) ) {
338  dump( MSG::DEBUG );
339  }
340  //
341  return StatusCode::SUCCESS;
342 }
343 // ============================================================================
344 // setup service
345 // ============================================================================
347 {
348  if ( !( m_algMgr = serviceLocator() ) ) // assignment meant
349  {
350  error() << "Failed to retrieve the IAlgManager interface." << endmsg;
351  return StatusCode::FAILURE;
352  }
353 
354  if ( !( m_incSvc = serviceLocator()->service( "IncidentSvc" ) ) ) // assignment meant
355  {
356  error() << "Failed to retrieve Incident service." << endmsg;
357  return StatusCode::FAILURE;
358  }
359  m_incSvc->addListener( this, m_trapType );
360 
361  if ( !( m_dataSvc = serviceLocator()->service( m_dataSvcName ) ) ) // assignment meant
362  {
363  error() << "Failed to retrieve the data provider interface of " << m_dataSvcName << endmsg;
364  return StatusCode::FAILURE;
365  }
366 
367  // No need to get the ToolSvc if we are not using tools
368  if ( !( m_nodeMapTools.empty() && m_algMapTools.empty() ) ) {
369  if ( !( m_toolSvc = serviceLocator()->service( "ToolSvc" ) ) ) // assignment meant
370  {
371  error() << "Failed to retrieve ToolSvc" << endmsg;
372  return StatusCode::FAILURE;
373  }
374 
375  // load the node mapping tools
376  IDODNodeMapper* nodetool = nullptr;
377  for ( const auto& i : m_nodeMapTools ) {
378  const StatusCode sc = m_toolSvc->retrieveTool( i, nodetool );
379  if ( sc.isFailure() ) return sc;
380  m_nodeMappers.push_back( nodetool );
381  }
382  IDODAlgMapper* algtool = nullptr;
383  for ( const auto& i : m_algMapTools ) {
384  const StatusCode sc = m_toolSvc->retrieveTool( i, algtool );
385  if ( sc.isFailure() ) return sc;
386  m_algMappers.push_back( algtool );
387  }
388  }
389  return update();
390 }
391 // ============================================================================
392 // setup node handlers
393 // ============================================================================
395 {
396  std::string nam, typ, tag;
398  // Setup for node leafs, where simply a constructor is called...
399  for ( auto node : m_nodeMapping ) {
400  using Parser = Gaudi::Utils::AttribStringParser;
401  for ( auto attrib : Parser( node ) ) {
402  switch (::toupper( attrib.tag[0] ) ) {
403  case 'D':
404  tag = std::move( attrib.value );
405  break;
406  case 'T':
407  nam = std::move( attrib.value );
408  break;
409  }
410  }
411  if ( m_algMap.end() != m_algMap.find( tag ) || m_nodeMap.end() != m_nodeMap.find( tag ) ) {
412  warning() << "The obsolete property 'Nodes' redefines the action for '" + tag + "' to be '" + nam + "'" << endmsg;
413  }
414  m_nodeMap[tag] = nam;
415  }
416  //
417  m_updateRequired = true;
418  //
419  return sc;
420 }
421 // ============================================================================
422 // setup algorithm handlers
423 // ============================================================================
425 {
426  std::string typ, tag;
427 
428  for ( auto alg : m_algMapping ) {
429  using Parser = Gaudi::Utils::AttribStringParser;
430  for ( auto attrib : Parser( alg ) ) {
431  switch (::toupper( attrib.tag[0] ) ) {
432  case 'D':
433  tag = std::move( attrib.value );
434  break;
435  case 'T':
436  typ = std::move( attrib.value );
437  break;
438  }
439  }
440  Gaudi::Utils::TypeNameString item( typ );
441  if ( m_algMap.end() != m_algMap.find( tag ) || m_nodeMap.end() != m_nodeMap.find( tag ) ) {
442  warning() << "The obsolete property 'Algorithms' redefines the action for '" + tag + "' to be '" + item.type() +
443  "/" + item.name() + "'"
444  << endmsg;
445  }
446  m_algMap[tag] = item.type() + "/" + item.name();
447  }
448  m_updateRequired = true;
449  return StatusCode::SUCCESS;
450 }
451 // ============================================================================
453 // ============================================================================
455 {
456  if ( l.algorithm ) {
457  return StatusCode::SUCCESS;
458  }
459  if ( !m_algMgr ) {
460  return StatusCode::FAILURE;
461  }
462  l.algorithm = m_algMgr->algorithm( l.name, false );
463  if ( l.algorithm ) {
464  return StatusCode::SUCCESS;
465  }
466  // create it!
467  StatusCode sc = m_algMgr->createAlgorithm( l.type, l.name, l.algorithm, true );
468  if ( sc.isFailure() ) {
469  error() << "Failed to create algorithm " << l.type << "('" << l.name << "')" << endmsg;
470  l.algorithm = nullptr;
471  return sc; // RETURN
472  }
473  if ( l.algorithm->isInitialized() ) {
474  return StatusCode::SUCCESS;
475  }
476  // initialize it!
477  sc = l.algorithm->sysInitialize();
478  if ( sc.isFailure() ) {
479  error() << "Failed to initialize algorithm " << l.type << "('" << l.name << "')" << endmsg;
480  l.algorithm = nullptr;
481  return sc; // RETURN
482  }
483  if ( Gaudi::StateMachine::RUNNING == l.algorithm->FSMState() ) {
484  return StatusCode::SUCCESS;
485  }
486  // run it!
487  sc = l.algorithm->sysStart();
488  if ( sc.isFailure() ) {
489  error() << "Failed to 'run' algorithm " << l.type << "('" << l.name << "')" << endmsg;
490  l.algorithm = nullptr;
491  return sc; // RETURN
492  }
493  return StatusCode::SUCCESS;
494 }
495 
496 // local algorithms
497 namespace
498 {
501  struct ToolGetter {
505  ToolGetter( std::string _path ) : path( std::move( _path ) ) {}
507  inline std::string operator()( IDODNodeMapper* t ) const { return t->nodeTypeForPath( path ); }
509  inline Gaudi::Utils::TypeNameString operator()( IDODAlgMapper* t ) const { return t->algorithmForPath( path ); }
510  };
511 
514  inline bool isGood( const std::string& r ) { return !r.empty(); }
515  inline bool isGood( const Gaudi::Utils::TypeNameString& r ) { return !r.name().empty(); }
517 
520  class Finder
521  {
522  const ToolGetter getter;
523  const std::vector<IDODNodeMapper*>& nodes;
524  const std::vector<IDODAlgMapper*>& algs;
526  template <class R, class C>
527  R find( const C& l ) const
528  {
529  for ( auto& i : l ) {
530  auto result = getter( i );
531  if ( isGood( result ) ) return result;
532  }
533  return R{""};
534  }
535 
536  public:
538  Finder( std::string _path, const std::vector<IDODNodeMapper*>& _nodes, const std::vector<IDODAlgMapper*>& _algs )
539  : getter( std::move( _path ) ), nodes( _nodes ), algs( _algs )
540  {
541  }
543  inline std::string node() const { return find<std::string>( nodes ); }
545  inline Gaudi::Utils::TypeNameString alg() const { return find<Gaudi::Utils::TypeNameString>( algs ); }
546  };
547 }
548 
549 // ===========================================================================
550 // IIncidentListener interfaces overrides: incident handling
551 // ===========================================================================
552 void DataOnDemandSvc::handle( const Incident& incident )
553 {
554 
556 
557  ++m_stat;
558  // proper incident type?
559  if ( incident.type() != m_trapType ) {
560  return;
561  } // RETURN
562  const DataIncident* inc = dynamic_cast<const DataIncident*>( &incident );
563  if ( !inc ) {
564  return;
565  } // RETURN
566  // update if needed!
567  if ( m_updateRequired ) {
568  update();
569  }
570 
571  if ( msgLevel( MSG::VERBOSE ) ) {
572  verbose() << "Incident: [" << incident.type() << "] "
573  << " = " << incident.source() << " Location:" << inc->tag() << endmsg;
574  }
575  // ==========================================================================
576  Gaudi::StringKey tag( inc->tag() );
577  // ==========================================================================
578  auto icl = m_nodes.find( tag );
579  if ( icl != m_nodes.end() ) {
580  StatusCode sc = execHandler( tag, icl->second );
581  if ( sc.isSuccess() ) {
582  ++m_statNode;
583  }
584  return; // RETURN
585  }
586  // ==========================================================================
587  auto ialg = m_algs.find( tag );
588  if ( ialg != m_algs.end() ) {
589  StatusCode sc = execHandler( tag, ialg->second );
590  if ( sc.isSuccess() ) {
591  ++m_statAlg;
592  }
593  return; // RETURN
594  }
595  // ==========================================================================
596  // Fall back on the tools
597  if ( m_toolSvc ) {
598  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "Try to find mapping with mapping tools" << endmsg;
599  Finder finder( no_prefix( inc->tag(), m_prefix ), m_nodeMappers, m_algMappers );
600  // - try the node mappers
601  std::string node = finder.node();
602  if ( isGood( node ) ) {
603  // if one is found update the internal node mapping and try again.
604  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "Found Node handler: " << node << endmsg;
605  i_setNodeHandler( inc->tag(), node );
606  handle( incident );
607  --m_stat; // avoid double counting because of recursion
608  return;
609  }
610  // - try alg mappings
611  Gaudi::Utils::TypeNameString alg = finder.alg();
612  if ( isGood( alg ) ) {
613  // we got an algorithm, update alg map and try to handle again
614  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "Found Algorithm handler: " << alg << endmsg;
615  i_setAlgHandler( inc->tag(), alg ).ignore();
616  handle( incident );
617  --m_stat; // avoid double counting because of recursion
618  return;
619  }
620  }
621 }
622 // ===========================================================================
623 // execute the handler
624 // ===========================================================================
626 {
627 
629 
630  if ( n.executing ) {
631  return StatusCode::FAILURE;
632  } // RETURN
633 
634  Protection p( n.executing );
635 
637 
638  if ( n.dataObject ) {
639  object.reset( new DataObject() );
640  } else {
641  // try to recover the handler
642  if ( !n.clazz ) {
643  n.clazz = TClass::GetClass( n.name.c_str() );
644  }
645  if ( !n.clazz ) {
646  error() << "Failed to get dictionary for class '" << n.name << "' for location:" << tag << endmsg;
647  return StatusCode::FAILURE; // RETURN
648  }
649 
650  object.reset( reinterpret_cast<DataObject*>( n.clazz->New() ) );
651 
652  if ( !object ) {
653  error() << "Failed to create an object of type:" << n.clazz->GetName() << " for location:" << tag << endmsg;
654  return StatusCode::FAILURE; // RETURN
655  }
656  }
657  //
658  StatusCode sc = m_dataSvc->registerObject( tag, object.release() );
659  if ( sc.isFailure() ) {
660  error() << "Failed to register an object of type:" << n.name << " at location:" << tag << endmsg;
661  return sc; // RETURN
662  }
663  ++n.num;
664  //
665  return StatusCode::SUCCESS;
666 }
667 // ===========================================================================
668 // execute the handler
669 // ===========================================================================
671 {
673  //
674  if ( l.executing ) {
675  return StatusCode::FAILURE;
676  } // RETURN
677  //
678  if ( !l.algorithm ) {
679  StatusCode sc = configureHandler( l );
680  if ( sc.isFailure() ) {
681  error() << "Failed to configure handler for: " << l.name << "[" << l.type << "] " << tag << endmsg;
682  return sc; // RETURN
683  }
684  }
685  //
686  Chrono atimer( m_total );
687  //
688  Protection p( l.executing );
689  // FIXME: this will cause problems for Hive, as we need to set
690  // the EventContext of the called Algorithm.
691  // if (!l.algorithm->getContext()) {
692  // l.algorithm->setContext( &Gaudi::Hive::currentContext() );
693  // }
694  StatusCode sc = l.algorithm->sysExecute();
695  if ( sc.isFailure() ) {
696  error() << "Failed to execute the algorithm:" << l.algorithm->name() << " for location:" << tag << endmsg;
697  return sc; // RETURN
698  }
699  ++l.num;
700  //
701  return StatusCode::SUCCESS;
702 }
703 // ============================================================================
704 /* dump the content of DataOnDemand service
705  * @param level the printout level
706  * @param mode the printout mode
707  */
708 // ============================================================================
709 void DataOnDemandSvc::dump( const MSG::Level level, const bool mode ) const
710 {
711  if ( m_algs.empty() && m_nodes.empty() ) {
712  return;
713  }
714 
717  for ( auto& alg : m_algs ) {
718  auto check = _m.find( alg.first );
719  if ( _m.end() != check ) {
720  warning() << " The data item is activated for '" << check->first << "' as '" << check->second.first << "'"
721  << endmsg;
722  }
723  const Leaf& l = alg.second;
724  std::string nam = ( l.name == l.type ? l.type : ( l.type + "/" + l.name ) );
725  //
726  if ( !mode && 0 == l.num ) {
727  continue;
728  }
729  //
730  std::string val;
731  if ( mode ) {
732  val = ( !l.algorithm ) ? "F" : "T";
733  } else {
734  val = std::to_string( l.num );
735  }
736  //
737  _m[no_prefix( alg.first, m_prefix )] = {nam, val};
738  }
739  // nodes:
740  for ( const auto& node : m_nodes ) {
741  auto check = _m.find( node.first );
742  if ( _m.end() != check ) {
743  warning() << " The data item is already activated for '" << check->first << "' as '" << check->second.first << "'"
744  << endmsg;
745  }
746  const Node& n = node.second;
747  std::string nam = "'" + n.name + "'";
748  //
749  std::string val;
750 
751  if ( !mode && 0 == n.num ) {
752  continue;
753  }
754 
755  if ( mode ) {
756  val = ( 0 == n.clazz ) ? "F" : "T";
757  } else {
758  val = std::to_string( n.num );
759  }
760  //
761  _m[no_prefix( node.first, m_prefix )] = {nam, val};
762  }
763  //
764  if ( _m.empty() ) {
765  return;
766  }
767 
768  // find the correct formats
769  size_t n1 = 0;
770  size_t n2 = 0;
771  size_t n3 = 0;
772  for ( const auto& i : _m ) {
773  n1 = std::max( n1, i.first.size() );
774  n2 = std::max( n2, i.second.first.size() );
775  n3 = std::max( n3, i.second.second.size() );
776  }
777  if ( 10 > n1 ) {
778  n1 = 10;
779  }
780  if ( 10 > n2 ) {
781  n2 = 10;
782  }
783  if ( 60 < n1 ) {
784  n1 = 60;
785  }
786  if ( 60 < n2 ) {
787  n2 = 60;
788  }
789  //
790 
791  const std::string _f = " | %%1$-%1%.%1%s | %%2$-%2%.%2%s | %%3$%3%.%3%s |";
792  boost::format _ff( _f );
793  _ff % n1 % n2 % n3;
794 
795  const std::string _format = _ff.str();
796 
797  auto& msg = msgStream( level );
798 
799  if ( mode ) {
800  msg << "Data-On-Demand Actions enabled for:";
801  } else {
802  msg << "Data-On-Demand Actions has been used for:";
803  }
804 
805  boost::format fmt1( _format );
806  fmt1 % "Address" % "Creator" % ( mode ? "S" : "#" );
807  //
808  const std::string header = fmt1.str();
809  std::string line = std::string( header.size(), '-' );
810  line[0] = ' ';
811 
812  msg << '\n' << line << '\n' << header << '\n' << line;
813 
814  // make the actual printout:
815  for ( const auto& item : _m ) {
816  boost::format fmt( _format );
817  msg << '\n' << ( fmt % item.first % item.second.first % item.second.second );
818  }
819 
820  msg << '\n' << line << endmsg;
821 }
822 // ============================================================================
827 // ============================================================================
828 
829 // ============================================================================
830 // The END
831 // ============================================================================
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.
ChronoEntity m_timer_all
StatusCode initialize() override
Definition: Service.cpp:64
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
T empty(T...args)
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:289
const std::string & type() const
Access to the incident type.
Definition: Incident.h:41
The DataOnDemandSvc listens to incidents typically triggered by the data service of the configurable ...
StatusCode finalize() override
Definition: Service.cpp:174
virtual StatusCode sysStart()=0
Startup method invoked by the framework.
ChronoEntity m_timer_algs
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
const std::string & source() const
Access to the source of the incident.
Definition: Incident.h:47
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:74
virtual bool isInitialized() const =0
check if the algorithm is initialized properly
SmartIF< IIncidentSvc > m_incSvc
Incident service.
void handle(const Incident &incident) override
IIncidentListener interfaces overrides: incident handling.
T to_string(T...args)
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
virtual StatusCode createAlgorithm(const std::string &algtype, const 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...
Gaudi::Property< std::string > m_trapType
Gaudi::Property< Map > m_nodeMap
T end(T...args)
Gaudi::Property< bool > m_init
A small utility class for chronometry of user codes.
Definition: Chrono.h:25
#define SET(x)
StatusCode initialize() override
Inherited Service overrides: Service initialization.
STL class.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:84
GAUDI_API std::string header(const int ID=Default)
get the recommended header by enum
StatusCode retrieveTool(const std::string &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:145
The helper class to represent the efficient "key" for access.
Definition: StringKey.h:35
virtual StatusCode sysInitialize()=0
Initialization method invoked by the framework.
virtual StatusCode sysExecute()=0
System execution. This method invokes the execute() method of a concrete algorithm.
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
STL class.
SmartIF< IDataProviderSvc > m_dataSvc
Data provider reference.
ulonglong m_statNode
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:78
Gaudi::Property< std::vector< std::string > > m_algMapTools
ClassH clazz
the actual class
T push_back(T...args)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
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
Gaudi::Property< std::vector< std::string > > m_nodeMapTools
iterator end()
Definition: Map.h:132
Helper class to parse a string of format "type/name".
Gaudi::Property< Map > m_algMap
StatusCode setup()
Setup routine (called by (re-) initialize.
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
StatusCode execHandler(const std::string &tag, Leaf &leaf)
Execute leaf handler (algorithm)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
bool empty() const
Definition: Map.h:184
StatusCode setupNodeHandlers()
Initialize node handlers.
T erase(T...args)
iterator find(const key_type &key)
Definition: Map.h:149
Helper class of the DataOnDemandSvc.
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...
NodeMap m_nodes
Map of "empty" objects to be placed as intermediate nodes.
T reset(T...args)
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: Property.h:32
StatusCode reinitialize() override
Definition: Service.cpp:250
void dump(const MSG::Level level, const bool mode=true) const
dump the content of DataOnDemand service
T clear(T...args)
T max(T...args)
T move(T...args)
dictionary l
Definition: gaudirun.py:421
Gaudi::Property< bool > m_partialPath
std::vector< IDODNodeMapper * > m_nodeMappers
std::string outputUserTime() const
print the chrono ;
T find_if_not(T...args)
T size(T...args)
Interface of tools used by the DataOnDemandSvc to choose the algorithm to be run to produce the data ...
Definition: IDODAlgMapper.h:17
SmartIF< IAlgManager > m_algMgr
Algorithm manager.
STL class.
SmartIF< IToolSvc > m_toolSvc
Data provider reference.
Helper object, useful for measurement of CPU-performance of highly-recursive structures, e.g.
Definition: LockedChrono.h:52
AlgMap m_algs
Map of algorithms to handle incidents.
Gaudi::Property< Setup > m_nodeMapping
const std::string & type() const
ChronoEntity m_timer_nodes
Gaudi::Property< std::string > m_dataSvcName
T c_str(T...args)
Base class for all Incidents (computing events).
Definition: Incident.h:17
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
bool dataObject
trivial object? DataObject?
DataOnDemandSvc(const std::string &name, ISvcLocator *svc)
Standard initializing service constructor.
StatusCode finalize() override
Inherited Service overrides: Service finalization.
MsgStream & msgStream() const
Return an uninitialized MsgStream.
Gaudi::StateMachine::State FSMState() const override
Definition: Service.h:54
T substr(T...args)
void clear()
Definition: Map.h:178
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn&#39;t already exist.
Definition: Service.h:85
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:88
virtual void removeListener(IIncidentListener *lis, const std::string &type="")=0
Remove listener.
Data service incident class.
const std::string & name() const
implementation of various functions for streaming.
void ignore() const
Definition: StatusCode.h:106
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.
virtual StatusCode registerObject(const std::string &fullPath, DataObject *pObject)=0
Register object with the data store.
MSG::Level msgLevel() const
get the output level from the embedded MsgStream
StatusCode i_setAlgHandler(const std::string &name, const Gaudi::Utils::TypeNameString &alg)
Internal method to initialize an algorithm handler.
Gaudi::Property< bool > m_dump
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: Service.cpp:292
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:244
StatusCode reinitialize() override
Inherited Service overrides: Service reinitialization.
StatusCode update()
update the handlers