Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

RndmGenSvc.cpp

Go to the documentation of this file.
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/IObjManager.h"
00024 #include "GaudiKernel/ISvcManager.h"
00025 #include "GaudiKernel/IRndmEngine.h"
00026 #include "GaudiKernel/IRndmGenFactory.h"
00027 
00028 #include "GaudiKernel/MsgStream.h"
00029 
00030 #include "RndmGen.h"
00031 #include "RndmGenSvc.h"
00032 
00033 // Instantiation of a static factory class used by clients to create
00034 // instances of this service
00035 static const SvcFactory<RndmGenSvc> s_factory;
00036 const ISvcFactory& RndmGenSvcFactory = s_factory;
00037 
00039 RndmGenSvc::RndmGenSvc(const std::string& nam, ISvcLocator* svc)
00040 : Service(nam, svc), m_engine(0), m_serialize(0)
00041 {
00042   declareProperty("Engine", m_engineName = "HepRndm::Engine<RanluxEngine>");
00043 }
00044 
00046 RndmGenSvc::~RndmGenSvc()   {
00047 }
00048 
00050 StatusCode RndmGenSvc::queryInterface(const IID& riid, void** ppvInterface)  {
00051   if ( IID_IRndmGenSvc == riid )   {
00052     *ppvInterface = (IRndmGenSvc*)this;
00053   }
00054   else if ( IID_IRndmEngine == riid )   {
00055     *ppvInterface = (IRndmEngine*)this;
00056   }
00057   else if ( IID_ISerialize == riid )   {
00058     *ppvInterface = (ISerialize*)this;
00059   }
00060   else  {
00061     return Service::queryInterface(riid, ppvInterface);
00062   }
00063   addRef();
00064   return StatusCode::SUCCESS;
00065 }
00066 
00068 StatusCode RndmGenSvc::initialize()   {
00069   StatusCode status = Service::initialize();
00070   MsgStream log(msgSvc(), name());
00071   std::string machName = name()+".Engine";
00072   SmartIF<IRndmEngine> engine(IID_IRndmEngine);
00073   SmartIF<ISvcManager> mgr(IID_ISvcManager, serviceLocator());
00074 
00075   if ( status.isSuccess() )   {
00076     status = setProperties();
00077     if ( status.isSuccess() )   {  // Check if the Engine service exists:
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         engine = service;
00084       }
00085       if ( status.isSuccess() )   {
00086         SmartIF<ISerialize> serial(IID_ISerialize, engine);
00087         SmartIF<IService>   service(IID_IService,  engine);
00088         if ( serial.isValid( ) && service.isValid( ) )  {
00089           status = service->initialize();
00090           if ( status.isSuccess() )   {
00091             m_engine = engine;
00092             m_serialize = serial;
00093             m_engine->addRef();
00094             m_serialize->addRef();
00095             log << MSG::INFO << "Using Random engine:" << m_engineName << endreq;
00096             return status;
00097           }
00098         }
00099       }
00100     }
00101   }
00102   return status;
00103 }
00104 
00106 StatusCode RndmGenSvc::finalize()   {
00107   StatusCode status = Service::finalize();
00108   for ( FactoryContainer::iterator i = m_factories.begin(); i != m_factories.end(); i++ ) {
00109     (*i)->release();
00110   }
00111   m_factories.erase(m_factories.begin(), m_factories.end());
00112   if ( m_serialize ) m_serialize->release();
00113   m_serialize = 0;
00114   if ( m_engine )  m_engine->release();
00115   m_engine = 0;
00116   return status;
00117 }
00118 
00120 
00121 StreamBuffer& RndmGenSvc::serialize(StreamBuffer& str)    {
00122   if ( 0 != m_serialize )    {
00123     return m_serialize->serialize(str);
00124   }
00125   MsgStream log(msgSvc(), name());
00126   log << MSG::ERROR << "Cannot input serialize Generator settings!" << endreq;
00127   return str;
00128 }
00129 
00131 StreamBuffer& RndmGenSvc::serialize(StreamBuffer& str) const    {
00132   if ( 0 != m_serialize )    {
00133     return m_serialize->serialize(str);
00134   }
00135   MsgStream log(msgSvc(), name());
00136   log << MSG::ERROR << "Cannot output serialize Generator settings!" << endreq;
00137   return str;
00138 }
00139 
00141 IRndmEngine* RndmGenSvc::engine()     {
00142   return m_engine;
00143 }
00144 
00146 StatusCode RndmGenSvc::addFactory(const IRndmGenFactory* fac)    {
00147   if ( 0 != fac )  {
00148     for ( FactoryContainer::iterator i = m_factories.begin(); i != m_factories.end(); i++ ) {
00149       if ( (*i)->type() == fac->type() )   {
00150         (*i)->release();
00151         (*i) = fac;
00152         return StatusCode::SUCCESS;
00153       }
00154     }
00155     m_factories.push_back(fac);
00156     return StatusCode::SUCCESS;
00157   }
00158   return StatusCode::FAILURE;
00159 }
00160 
00162 StatusCode RndmGenSvc::removeFactory(const IID& type)   {
00163   for ( FactoryContainer::iterator i = m_factories.begin(); i != m_factories.end(); i++ ) {
00164     if ( (*i)->type() == type )   {
00165       m_factories.erase(i);
00166       return StatusCode::SUCCESS;
00167     }
00168   }
00169   return StatusCode::FAILURE;
00170 }
00171 
00173 StatusCode RndmGenSvc::generator(const IRndmGen::Param& par, IRndmGen*& refpGen)   {
00174   StatusCode status = StatusCode::FAILURE;
00175   const IRndmGenFactory* fac = factory(par.type());
00176   // If the factory is not present, ask for it.... 
00177   if ( 0 == fac )   {
00178     status = requestFactory( par.type(), fac);
00179     if ( status.isSuccess() )   {
00180       // Add factory now: for the next time.
00181       status = addFactory( fac );
00182       if ( status.isSuccess() )   {
00183         // Factory found and added: now create generator
00184         return createGenerator(fac, par, refpGen);
00185       }
00186     }
00187     // Error!
00188     return status;
00189   }
00190   // Factory found: create generator
00191   return createGenerator(fac, par, refpGen);
00192 }
00193 
00194 // Check the list of known factories for the requested type
00195 const IRndmGenFactory* RndmGenSvc::factory(const IID& type)   {
00196   for ( FactoryContainer::iterator i = m_factories.begin(); i != m_factories.end(); i++ ) {
00197     if ( (*i)->type() == type )   {
00198       return *i;
00199     }
00200   }
00201   return 0;
00202 }
00203 
00204 // Request a new factory from the object manager
00205 StatusCode RndmGenSvc::requestFactory(const IID& type, const IRndmGenFactory*& refpFactory)    {
00206   IObjManager* objManager = 0;
00207   StatusCode status = serviceLocator()->queryInterface(IID_IObjManager, (void**)&objManager);
00208   refpFactory = 0;
00209   if ( status.isSuccess() )   {
00210     StatusCode iret;
00211     IObjManager::ObjIterator i, stop;
00212     const IRndmGenFactory* fac;
00213     for ( i = objManager->objBegin(), stop = objManager->objEnd(); i != stop; i++ )    {
00214       IFactory* f = const_cast<IFactory*>(*i);
00215       iret = f->queryInterface(IID_IRndmGenFactory, (void**)&fac);
00216       if ( iret.isSuccess() )   {
00217         if ( fac->type() == type )    {
00218           refpFactory = fac;
00219           return StatusCode::SUCCESS;
00220         }
00221         fac->release();   // Unused interface must be released
00222       }
00223     }
00224     objManager->release(); // Must release interface after use!
00225   }
00226   return StatusCode::FAILURE;
00227 }
00228 
00229 // Create new Generator from known factory
00230 StatusCode RndmGenSvc::createGenerator(const IRndmGenFactory* pFactory, const IRndmGen::Param& par, IRndmGen*& refpGen)    {
00231   StatusCode status = StatusCode::FAILURE;
00232   refpGen = 0;
00233   if ( 0 != pFactory )    {
00234     IInterface *iface = pFactory->instantiate(m_engine);
00235     if ( iface )    {
00236       // query requested interface (adds ref count)
00237       status = iface->queryInterface(IID_IRndmGen, (void**)& refpGen);
00238       if ( status.isSuccess() )   {
00239         status = refpGen->initialize(par);
00240       }
00241       else  {
00242         iface->release();
00243       }
00244     }
00245   }
00246   return status;
00247 }
00248 
00249 // Single shot returning single random number
00250 double RndmGenSvc::rndm() const   {
00251   if ( 0 != m_engine )    {
00252     return m_engine->rndm();
00253   }
00254   return -1;
00255 }
00256 
00257 /*  Multiple shots returning vector with flat random numbers.
00258     @param  array    Array containing random numbers 
00259     @param  howmany  fill 'howmany' random numbers into array
00260     @param  start    ... starting at position start
00261     @return StatusCode indicating failure or success.
00262 */
00263 StatusCode RndmGenSvc::rndmArray( std::vector<double>& array, long howmany, long start) const   {
00264   if ( 0 != m_engine )    {
00265     return m_engine->rndmArray(array, howmany, start);
00266   }
00267   return StatusCode::FAILURE;
00268 }
00269 
00270 // Allow to set new seeds
00271 StatusCode RndmGenSvc::setSeeds(const std::vector<long>& seeds)   {
00272   if ( 0 != m_engine )    {
00273     return m_engine->setSeeds(seeds);
00274   }
00275   return StatusCode::FAILURE;
00276 }
00277 
00278 // Allow to get the seeds
00279 StatusCode RndmGenSvc::seeds(std::vector<long>& seeds)  const  {
00280   if ( 0 != m_engine )    {
00281     return m_engine->seeds(seeds);
00282   }
00283   return StatusCode::FAILURE;
00284 }
00285 

Generated at Wed Nov 21 12:22:31 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000