| The Gaudi Framework v32r1 (f65d50dc)

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