00001
00009 #include "GaudiKernel/SvcFactory.h"
00010 #include "GaudiKernel/MsgStream.h"
00011 #include "GaudiKernel/GaudiException.h"
00012
00013
00014 #include "GaudiKernel/IAlgManager.h"
00015 #include "GaudiKernel/Algorithm.h"
00016 #include "GaudiKernel/IAppMgrUI.h"
00017 #include "GaudiKernel/IIncidentSvc.h"
00018 #include "GaudiKernel/IIncidentListener.h"
00019
00020 #include "CLHEP/Random/Random.h"
00021
00022 #include <vector>
00023 #include <algorithm>
00024
00032
00033 #include "GaudiKernel/Service.h"
00034 #include "GaudiKernel/IRunable.h"
00035 #include "GaudiKernel/Property.h"
00036 #include "RootIO/IRootIoSvc.h"
00037 #include "TSystem.h"
00038
00039
00040 template <class TYPE> class SvcFactory;
00041 class IAppMgrUI;
00042
00043
00044 class RootIoSvc :
00045 virtual public Service,
00046 virtual public IIncidentListener,
00047 virtual public IRootIoSvc,
00048 virtual public IRunable
00049 {
00050 public:
00051
00052
00054 virtual StatusCode run();
00055
00056
00057
00058
00060 virtual StatusCode initialize ();
00061
00063 virtual StatusCode finalize ();
00064
00066 virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvUnknown );
00067
00069 virtual void handle(const Incident& inc);
00070
00071 virtual int getEvtMax() { return m_evtMax; };
00072
00073 virtual void setRootEvtMax(unsigned int max);
00074
00075 virtual void setRootTimeMax(unsigned int max);
00076
00077 virtual void registerRootTree(TChain *ch);
00078
00079 virtual bool setIndex(int i);
00080 virtual int index() { return m_index; };
00081
00082 virtual bool setRunEventPair(std::pair<int,int> ids);
00083 virtual std::pair<int,int> runEventPair() { return m_runEventPair; };
00084
00085 virtual int getAutoSaveInterval() { return m_autoSaveInterval; };
00086
00087 protected:
00088
00090 RootIoSvc ( const std::string& name, ISvcLocator* al );
00091
00093 virtual ~RootIoSvc();
00094
00095 private:
00096
00097 void beginEvent();
00098 void endEvent();
00099
00101 friend class SvcFactory<RootIoSvc>;
00102
00104 IAppMgrUI* m_appMgrUI;
00105 IntegerProperty m_evtMax;
00106 IntegerProperty m_autoSaveInterval;
00107
00108
00109 DoubleProperty m_startTime;
00110 DoubleProperty m_endTime;
00111
00112 unsigned int m_rootEvtMax;
00113 int m_index;
00114 std::pair<int, int> m_runEventPair;
00115 std::vector<TChain *> m_chainCol;
00116
00117 };
00118
00119
00120
00121
00122
00123
00124
00125
00127 RootIoSvc::RootIoSvc(const std::string& name,ISvcLocator* svc)
00128 : Service(name,svc)
00129 {
00130
00131 declareProperty("EvtMax" , m_evtMax=0);
00132 declareProperty("StartTime" , m_startTime=0);
00133 declareProperty("EndTime", m_endTime=0);
00134 declareProperty("AutoSaveInterval", m_autoSaveInterval=1000);
00135 declareProperty("StartingIndex", m_index=-1);
00136 m_rootEvtMax = 0;
00137
00138 m_runEventPair = std::pair<int,int>(-1,-1);
00139 m_chainCol.clear();
00140 }
00141
00142
00144 RootIoSvc::~RootIoSvc()
00145 {
00146 m_chainCol.clear();
00147 }
00148
00149
00150
00151 StatusCode RootIoSvc::initialize ()
00152 {
00153 StatusCode status = Service::initialize ();
00154
00155
00156 setProperties ();
00157
00158
00159 MsgStream log( msgSvc(), name() );
00160
00161 status = serviceLocator()->queryInterface(IAppMgrUI::interfaceID(), (void**)&m_appMgrUI);
00162
00163
00164 IIncidentSvc* incsvc = 0;
00165 status = service ("IncidentSvc", incsvc, true);
00166
00167 if( status.isFailure() ) return status;
00168
00169 incsvc->addListener(this, "BeginEvent", 100);
00170 incsvc->addListener(this, "EndEvent", 0);
00171
00172
00173 gSystem->ResetSignal(kSigBus);
00174 gSystem->ResetSignal(kSigSegmentationViolation);
00175 gSystem->ResetSignal(kSigIllegalInstruction);
00176 gSystem->ResetSignal(kSigFloatingException);
00177
00178 return StatusCode::SUCCESS;
00179 }
00180
00181
00182
00183 StatusCode RootIoSvc::finalize ()
00184 {
00185 StatusCode status = StatusCode::SUCCESS;
00186 return status;
00187 }
00188
00190 StatusCode RootIoSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) {
00191 if ( IID_IRootIoSvc.versionMatch(riid) ) {
00192 *ppvInterface = (IRootIoSvc*)this;
00193 }else if (IRunable::interfaceID().versionMatch(riid) ) {
00194 *ppvInterface = (IRunable*)this;
00195 } else if (IIncidentListener::interfaceID().versionMatch(riid) ) {
00196 *ppvInterface = (IIncidentListener*)this;
00197 } else {
00198 return Service::queryInterface(riid, ppvInterface);
00199 }
00200
00201 addRef();
00202 return SUCCESS;
00203 }
00204
00205
00206 void RootIoSvc::setRootEvtMax(unsigned int max) {
00207
00208
00209 if (m_rootEvtMax == 0) {
00210 m_rootEvtMax = max;
00211 return;
00212 }
00213
00214 if (m_rootEvtMax > max) m_rootEvtMax = max;
00215 }
00216
00217 void RootIoSvc::setRootTimeMax(unsigned int max) {
00218
00219 return;
00220 }
00221
00222 void RootIoSvc::registerRootTree(TChain *ch) {
00223 m_chainCol.push_back(ch);
00224 }
00225
00226 bool RootIoSvc::setIndex(int i) {
00227 if (i < 0) return false;
00228 std::vector<TChain*>::iterator it;
00229 for(it = m_chainCol.begin(); it != m_chainCol.end(); it++) {
00230 if (i >= (*it)->GetEntries()) return false;
00231 }
00232 m_index = i;
00233 m_runEventPair = std::pair<int, int>(-1,-1);
00234 return true;
00235 }
00236
00237
00238 bool RootIoSvc::setRunEventPair(std::pair<int, int> ids) {
00239 std::vector<TChain*>::iterator it;
00240 for(it = m_chainCol.begin(); it != m_chainCol.end(); it++) {
00241 int readInd = (*it)->GetEntryNumberWithIndex(ids.first, ids.second);
00242 if ( (readInd < 0) || (readInd >= (*it)->GetEntries()) ) return false;
00243 }
00244 m_runEventPair = ids;
00245 m_index=-1;
00246 return true;
00247 }
00248
00249
00250 void RootIoSvc::handle(const Incident &inc)
00251 {
00252 if( inc.type()=="BeginEvent")beginEvent();
00253 else if(inc.type()=="EndEvent")endEvent();
00254 }
00255
00256
00257 void RootIoSvc::beginEvent()
00258 {
00259 }
00260
00261 void RootIoSvc::endEvent()
00262 {
00263 m_index = -1;
00264 m_runEventPair = std::pair<int, int>(-1,-1);
00265 }
00266
00267 StatusCode RootIoSvc::run(){
00268
00269
00270 StatusCode status = StatusCode::FAILURE;
00271 MsgStream log( msgSvc(), name() );
00272
00273 if ( 0 == m_appMgrUI ) return status;
00274
00275 IProperty* propMgr=0;
00276 status = serviceLocator()->service("ApplicationMgr", propMgr );
00277 if( status.isFailure()) {
00278 log << MSG::ERROR << "Unable to locate PropertyManager Service" << endreq;
00279 return status;
00280 }
00281
00282 IntegerProperty evtMax("EvtMax",0);
00283 status = propMgr->getProperty( &evtMax );
00284 if (status.isFailure()) return status;
00285
00286
00287
00288 IntegerProperty rootEvtMax("EvtMax", m_rootEvtMax);
00289 if (rootEvtMax < evtMax) setProperty(rootEvtMax);
00290 else setProperty(evtMax);
00291
00292
00293
00294 IAlgManager* theAlgMgr;
00295 status = serviceLocator( )->getService( "ApplicationMgr",
00296 IAlgManager::interfaceID(),
00297 (IInterface*&)theAlgMgr );
00298 IAlgorithm* theIAlg;
00299 Algorithm* theAlgorithm=0;
00300 IntegerProperty errorProperty("ErrorCount",0);
00301
00302 status = theAlgMgr->getAlgorithm( "Top", theIAlg );
00303 if ( status.isSuccess( ) ) {
00304 try{
00305 theAlgorithm = dynamic_cast<Algorithm*>(theIAlg);
00306 } catch(...){
00307 status = StatusCode::FAILURE;
00308 }
00309 }
00310 if ( status.isFailure( ) ) {
00311 log << MSG::WARNING << "Could not find algorithm 'Top'; will not monitor errors" << endreq;
00312 }
00313
00314
00315
00316
00317 int eventNumber= 0;
00318 double currentTime=m_startTime;
00319
00320 { bool noend=true;
00321 log << MSG::INFO << "Runable interface starting event loop as :" ;
00322 if( m_evtMax>0) { log << " MaxEvt = " << m_evtMax; noend=false; }
00323 if( m_endTime>0) { log << " EndTime= " << m_endTime; noend=false; }
00324 log << endreq;
00325
00326 if(noend) {
00327 log << MSG::WARNING << "No end condition specified: will not process any events!" << endreq;
00328 }
00329 }
00330
00331 while( m_evtMax>0 && eventNumber < m_evtMax
00332 || m_endTime>0 && currentTime< m_endTime ) {
00333
00334 status = m_appMgrUI->nextEvent(1);
00335
00336
00337 if( theAlgorithm !=0) theAlgorithm->getProperty(&errorProperty);
00338 if( status.isFailure() || errorProperty.value() > 0){
00339 status = StatusCode::FAILURE;
00340 }
00341
00342 if( status.isFailure()) break;
00343
00344
00345
00346 eventNumber ++;
00347 }
00348 if( status.isFailure()){
00349 log << MSG::ERROR << "Terminating RootIoSvc loop due to error" << endreq;
00350
00351 }else if( m_endTime>0 && currentTime >= m_endTime ) {
00352 log << MSG::INFO << "Loop terminated by time " << endreq;
00353 }else {
00354 log << MSG::INFO << "Processing loop terminated by event count" << endreq;
00355 }
00356 return status;
00357 }
00358