| The Gaudi Framework v28r2p1 (f1a77ff4)

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

- File List
- File Members

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