CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10_patch1/src/CondTools/L1Trigger/interface/L1ConfigOnlineProdBase.h

Go to the documentation of this file.
00001 #ifndef CondTools_L1Trigger_L1ConfigOnlineProdBase_h
00002 #define CondTools_L1Trigger_L1ConfigOnlineProdBase_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     L1Trigger
00006 // Class  :     L1ConfigOnlineProdBase
00007 // 
00018 //
00019 // Original Author:  Werner Sun
00020 //         Created:  Tue Sep  2 22:48:15 CEST 2008
00021 // $Id: L1ConfigOnlineProdBase.h,v 1.10 2010/07/21 16:22:19 govi Exp $
00022 //
00023 
00024 // system include files
00025 #include <memory>
00026 #include "boost/shared_ptr.hpp"
00027 
00028 // user include files
00029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00030 
00031 #include "FWCore/Framework/interface/ModuleFactory.h"
00032 #include "FWCore/Framework/interface/ESProducer.h"
00033 #include "FWCore/Framework/interface/ESHandle.h"
00034 
00035 #include "CondFormats/L1TObjects/interface/L1TriggerKeyList.h"
00036 #include "CondFormats/DataRecord/interface/L1TriggerKeyListRcd.h"
00037 #include "CondFormats/L1TObjects/interface/L1TriggerKey.h"
00038 #include "CondFormats/DataRecord/interface/L1TriggerKeyRcd.h"
00039 
00040 #include "CondTools/L1Trigger/interface/OMDSReader.h"
00041 #include "CondTools/L1Trigger/interface/DataWriter.h"
00042 #include "CondTools/L1Trigger/interface/Exception.h"
00043 
00044 #include "FWCore/Utilities/interface/typelookup.h"
00045 #include "FWCore/Framework/interface/EventSetup.h"
00046 
00047 #include "CondCore/DBCommon/interface/DbSession.h"
00048 #include "CondCore/DBCommon/interface/DbConnection.h"
00049 #include "CondCore/DBCommon/interface/DbScopedTransaction.h"
00050 
00051 // forward declarations
00052 
00053 template< class TRcd, class TData >
00054 class L1ConfigOnlineProdBase : public edm::ESProducer {
00055    public:
00056       L1ConfigOnlineProdBase(const edm::ParameterSet&);
00057       ~L1ConfigOnlineProdBase();
00058 
00059       boost::shared_ptr< TData > produce(const TRcd& iRecord);
00060 
00061       virtual boost::shared_ptr< TData > newObject(
00062         const std::string& objectKey ) = 0 ;
00063 
00064    private:
00065       // ----------member data ---------------------------
00066 
00067  protected:
00068       l1t::OMDSReader m_omdsReader ;
00069       bool m_forceGeneration ;
00070 
00071       // Called from produce methods.
00072       // bool is true if the object data should be made.
00073       // If bool is false, produce method should throw
00074       // DataAlreadyPresentException.
00075       bool getObjectKey( const TRcd& record,
00076                          boost::shared_ptr< TData > data,
00077                          std::string& objectKey ) ;
00078 
00079       // For reading object directly from a CondDB w/o PoolDBOutputService
00080       cond::DbConnection m_dbConnection ;
00081       cond::DbSession m_dbSession ;
00082       bool m_copyFromCondDB ;
00083 };
00084 
00085 
00086 template< class TRcd, class TData >
00087 L1ConfigOnlineProdBase<TRcd, TData>::L1ConfigOnlineProdBase(const edm::ParameterSet& iConfig)
00088    : m_omdsReader(),
00089      m_forceGeneration( iConfig.getParameter< bool >( "forceGeneration" ) ),
00090      m_dbConnection(),
00091      m_dbSession(),
00092      m_copyFromCondDB( false )
00093 {
00094    //the following line is needed to tell the framework what
00095    // data is being produced
00096   setWhatProduced(this);
00097 
00098    //now do what ever other initialization is needed
00099 
00100   if( iConfig.exists( "copyFromCondDB" ) )
00101     {
00102       m_copyFromCondDB = iConfig.getParameter< bool >( "copyFromCondDB" ) ;
00103 
00104       if( m_copyFromCondDB )
00105         {
00106           // Connect DbSession
00107           m_dbConnection.configuration().setAuthenticationPath(
00108              iConfig.getParameter< std::string >( "onlineAuthentication" ) ) ;
00109           m_dbConnection.configure() ;
00110           m_dbSession = m_dbConnection.createSession() ;
00111           m_dbSession.open(
00112                            iConfig.getParameter< std::string >( "onlineDB" ),
00113                            true ); // read-only
00114         }
00115     }
00116   else
00117     {
00118       m_omdsReader.connect(
00119         iConfig.getParameter< std::string >( "onlineDB" ),
00120         iConfig.getParameter< std::string >( "onlineAuthentication" ) ) ;
00121     }
00122 }
00123 
00124 template< class TRcd, class TData >
00125 L1ConfigOnlineProdBase<TRcd, TData>::~L1ConfigOnlineProdBase()
00126 {
00127  
00128    // do anything here that needs to be done at desctruction time
00129    // (e.g. close files, deallocate resources etc.)
00130 
00131 }
00132 
00133 template< class TRcd, class TData >
00134 boost::shared_ptr< TData >
00135 L1ConfigOnlineProdBase<TRcd, TData>::produce( const TRcd& iRecord )
00136 {
00137    using namespace edm::es;
00138    boost::shared_ptr< TData > pData ;
00139 
00140    // Get object key and check if already in ORCON
00141    std::string key ;
00142    if( getObjectKey( iRecord, pData, key ) || m_forceGeneration )
00143    {
00144      if( m_copyFromCondDB )
00145        {
00146          // Get L1TriggerKeyList from EventSetup
00147          const L1TriggerKeyListRcd& keyListRcd =
00148            iRecord.template getRecord< L1TriggerKeyListRcd >() ;
00149          edm::ESHandle< L1TriggerKeyList > keyList ;
00150          keyListRcd.get( keyList ) ;
00151 
00152          // Find payload token
00153          std::string recordName = edm::typelookup::className<TRcd>();
00154          std::string dataType = edm::typelookup::className<TData>();
00155          std::string payloadToken =
00156            keyList->token( recordName, dataType, key ) ;
00157 
00158          edm::LogVerbatim( "L1-O2O" )
00159            << "Copying payload for " << recordName
00160            << "@" << dataType << " obj key " << key
00161            << " from CondDB." ;
00162          edm::LogVerbatim( "L1-O2O" )
00163            << "TOKEN " << payloadToken ;
00164 
00165          // Get object from POOL
00166          // Copied from l1t::DataWriter::readObject()
00167          if( !payloadToken.empty() )
00168            {
00169              cond::DbScopedTransaction tr( m_dbSession ) ;
00170              tr.start( true ) ; 
00171              pData = m_dbSession.getTypedObject<TData>( payloadToken ) ;
00172              tr.commit ();
00173            }
00174        }
00175      else
00176        {
00177          pData = newObject( key ) ;
00178        }
00179 
00180      //     if( pData.get() == 0 )
00181      if( pData == boost::shared_ptr< TData >() )
00182        {
00183          std::string dataType = edm::typelookup::className<TData>();
00184 
00185          throw l1t::DataInvalidException( "Unable to generate " +
00186                                           dataType + " for key " + key +
00187                                           "." ) ;
00188        }
00189    }
00190    else
00191    {
00192      std::string dataType = edm::typelookup::className<TData>();
00193 
00194      throw l1t::DataAlreadyPresentException( dataType +
00195         " for key " + key + " already in CondDB." ) ;
00196    }
00197 
00198    return pData ;
00199 }
00200 
00201 
00202 template< class TRcd, class TData >
00203 bool 
00204 L1ConfigOnlineProdBase<TRcd, TData>::getObjectKey(
00205   const TRcd& record,
00206   boost::shared_ptr< TData > data,
00207   std::string& objectKey )
00208 {
00209    // Get L1TriggerKey
00210    const L1TriggerKeyRcd& keyRcd =
00211       record.template getRecord< L1TriggerKeyRcd >() ;
00212 
00213    // Explanation of funny syntax: since record is dependent, we are not
00214    // expecting getRecord to be a template so the compiler parses it
00215    // as a non-template. http://gcc.gnu.org/ml/gcc-bugs/2005-11/msg03685.html
00216 
00217    // If L1TriggerKey is invalid, then all configuration objects are
00218    // already in ORCON.
00219    edm::ESHandle< L1TriggerKey > key ;
00220    try
00221    {
00222       keyRcd.get( key ) ;
00223    }
00224    catch( l1t::DataAlreadyPresentException& ex )
00225    {
00226       objectKey = std::string() ;
00227       return false ;      
00228    }
00229 
00230    // Get object key from L1TriggerKey
00231    std::string recordName = edm::typelookup::className<TRcd>();
00232    std::string dataType = edm::typelookup::className<TData>();
00233 
00234    objectKey = key->get( recordName, dataType ) ;
00235 
00236 /*    edm::LogVerbatim( "L1-O2O" ) */
00237 /*      << "L1ConfigOnlineProdBase record " << recordName */
00238 /*      << " type " << dataType << " obj key " << objectKey ; */
00239 
00240    // Get L1TriggerKeyList
00241    L1TriggerKeyList keyList ;
00242    l1t::DataWriter dataWriter ;
00243    if( !dataWriter.fillLastTriggerKeyList( keyList ) )
00244      {
00245        edm::LogError( "L1-O2O" )
00246          << "Problem getting last L1TriggerKeyList" ;
00247      }
00248 
00249    // If L1TriggerKeyList does not contain object key, token is empty
00250    return
00251       keyList.token( recordName, dataType, objectKey ) == std::string() ;
00252 }
00253 
00254 #endif