![]() |
|
|
Generated: 18 Jul 2008 |
00001 //==================================================================== 00002 // Random Generator service implementation 00003 //-------------------------------------------------------------------- 00004 // 00005 // Package : Gaudi/RndmGen ( The LHCb Offline System) 00006 // Author : M.Frank 00007 // History : 00008 // +---------+----------------------------------------------+--------- 00009 // | Date | Comment | Who 00010 // +---------+----------------------------------------------+--------- 00011 // | 29/10/99| Initial version | MF 00012 // +---------+----------------------------------------------+--------- 00013 // 00014 //==================================================================== 00015 #define GAUDI_RANDOMGENSVC_RNDMGENSVC_CPP 00016 00017 // STL include files 00018 #include <cfloat> 00019 00020 // Framework include files 00021 #include "GaudiKernel/SmartIF.h" 00022 #include "GaudiKernel/SvcFactory.h" 00023 #include "GaudiKernel/ISvcManager.h" 00024 #include "GaudiKernel/IRndmEngine.h" 00025 00026 #include "GaudiKernel/MsgStream.h" 00027 00028 #include "RndmGen.h" 00029 #include "RndmGenSvc.h" 00030 00031 using ROOT::Reflex::PluginService; 00032 00033 // Instantiation of a static factory class used by clients to create 00034 // instances of this service 00035 DECLARE_SERVICE_FACTORY(RndmGenSvc) 00036 00037 00038 RndmGenSvc::RndmGenSvc(const std::string& nam, ISvcLocator* svc) 00039 : Service(nam, svc), m_engine(0), m_serialize(0) 00040 { 00041 declareProperty("Engine", m_engineName = "HepRndm::Engine<CLHEP::RanluxEngine>"); 00042 } 00043 00045 RndmGenSvc::~RndmGenSvc() { 00046 } 00047 00049 StatusCode RndmGenSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) { 00050 if ( IID_IRndmGenSvc == riid ) { 00051 *ppvInterface = (IRndmGenSvc*)this; 00052 } 00053 else if ( IID_IRndmEngine == riid ) { 00054 *ppvInterface = (IRndmEngine*)this; 00055 } 00056 else if ( IID_ISerialize == riid ) { 00057 *ppvInterface = (ISerialize*)this; 00058 } 00059 else { 00060 return Service::queryInterface(riid, ppvInterface); 00061 } 00062 addRef(); 00063 return StatusCode::SUCCESS; 00064 } 00065 00067 StatusCode RndmGenSvc::initialize() { 00068 StatusCode status = Service::initialize(); 00069 MsgStream log(msgSvc(), name()); 00070 std::string machName = name()+".Engine"; 00071 SmartIF<IRndmEngine> engine(IID_IRndmEngine); 00072 SmartIF<ISvcManager> mgr(IID_ISvcManager, serviceLocator()); 00073 00074 if ( status.isSuccess() ) { 00075 status = setProperties(); 00076 if ( status.isSuccess() ) { // Check if the Engine service exists: 00077 // FIXME: (MCl) why RndmGenSvc cannot create the engine service in a standard way? 00078 status = serviceLocator()->getService(machName, IID_IRndmEngine, (IInterface*&)engine.pRef()); 00079 if ( !status.isSuccess() && mgr.isValid( ) ) { 00080 IService* service = 0; 00081 // Engine does not exist: We have to create one! 00082 status = mgr->createService(m_engineName,machName,service); 00083 if (status.isSuccess()) { 00084 engine = service; 00085 service->release(); 00086 } 00087 } 00088 if ( status.isSuccess() ) { 00089 SmartIF<ISerialize> serial(IID_ISerialize, engine); 00090 SmartIF<IService> service(IID_IService, engine); 00091 if ( serial.isValid( ) && service.isValid( ) ) { 00092 status = service->sysInitialize(); 00093 if ( status.isSuccess() ) { 00094 m_engine = engine; 00095 m_serialize = serial; 00096 m_engine->addRef(); 00097 m_serialize->addRef(); 00098 log << MSG::INFO << "Using Random engine:" << m_engineName << endreq; 00099 return status; 00100 } 00101 } 00102 } 00103 } 00104 } 00105 return status; 00106 } 00107 00109 StatusCode RndmGenSvc::finalize() { 00110 StatusCode status = Service::finalize(); 00111 if ( m_serialize ) m_serialize->release(); 00112 m_serialize = 0; 00113 if ( m_engine ) { 00114 SmartIF<IService> service(IID_IService, m_engine); 00115 service->finalize().ignore(); 00116 m_engine->release(); 00117 } 00118 m_engine = 0; 00119 return status; 00120 } 00121 00123 00124 StreamBuffer& RndmGenSvc::serialize(StreamBuffer& str) { 00125 if ( 0 != m_serialize ) { 00126 return m_serialize->serialize(str); 00127 } 00128 MsgStream log(msgSvc(), name()); 00129 log << MSG::ERROR << "Cannot input serialize Generator settings!" << endreq; 00130 return str; 00131 } 00132 00134 StreamBuffer& RndmGenSvc::serialize(StreamBuffer& str) const { 00135 if ( 0 != m_serialize ) { 00136 return m_serialize->serialize(str); 00137 } 00138 MsgStream log(msgSvc(), name()); 00139 log << MSG::ERROR << "Cannot output serialize Generator settings!" << endreq; 00140 return str; 00141 } 00142 00144 IRndmEngine* RndmGenSvc::engine() { 00145 return m_engine; 00146 } 00147 00149 StatusCode RndmGenSvc::generator(const IRndmGen::Param& par, IRndmGen*& refpGen) { 00150 StatusCode status = StatusCode::FAILURE; 00151 IInterface* iface = PluginService::CreateWithId<IInterface*>(par.type(),(IInterface*)m_engine); 00152 if ( iface ) { 00153 // query requested interface (adds ref count) 00154 status = iface->queryInterface(IID_IRndmGen, (void**)& refpGen); 00155 if ( status.isSuccess() ) { 00156 status = refpGen->initialize(par); 00157 } 00158 else { 00159 iface->release(); 00160 } 00161 } 00162 // Error! 00163 return status; 00164 } 00165 00166 // Single shot returning single random number 00167 double RndmGenSvc::rndm() const { 00168 if ( 0 != m_engine ) { 00169 return m_engine->rndm(); 00170 } 00171 return -1; 00172 } 00173 00174 /* Multiple shots returning vector with flat random numbers. 00175 @param array Array containing random numbers 00176 @param howmany fill 'howmany' random numbers into array 00177 @param start ... starting at position start 00178 @return StatusCode indicating failure or success. 00179 */ 00180 StatusCode RndmGenSvc::rndmArray( std::vector<double>& array, long howmany, long start) const { 00181 if ( 0 != m_engine ) { 00182 return m_engine->rndmArray(array, howmany, start); 00183 } 00184 return StatusCode::FAILURE; 00185 } 00186 00187 // Allow to set new seeds 00188 StatusCode RndmGenSvc::setSeeds(const std::vector<long>& seeds) { 00189 if ( 0 != m_engine ) { 00190 return m_engine->setSeeds(seeds); 00191 } 00192 return StatusCode::FAILURE; 00193 } 00194 00195 // Allow to get the seeds 00196 StatusCode RndmGenSvc::seeds(std::vector<long>& seeds) const { 00197 if ( 0 != m_engine ) { 00198 return m_engine->seeds(seeds); 00199 } 00200 return StatusCode::FAILURE; 00201 } 00202