Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:52:18

0001 #ifndef CondTools_L1TriggerExt_L1ConfigOnlineProdBaseExt_h
0002 #define CondTools_L1TriggerExt_L1ConfigOnlineProdBaseExt_h
0003 
0004 // system include files
0005 #include <memory>
0006 
0007 // user include files
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 
0010 #include "FWCore/Framework/interface/ModuleFactory.h"
0011 #include "FWCore/Framework/interface/ESProducer.h"
0012 
0013 #include "CondFormats/L1TObjects/interface/L1TriggerKeyListExt.h"
0014 #include "CondFormats/DataRecord/interface/L1TriggerKeyListExtRcd.h"
0015 
0016 #include "CondFormats/L1TObjects/interface/L1TriggerKeyExt.h"
0017 #include "CondFormats/DataRecord/interface/L1TriggerKeyExtRcd.h"
0018 
0019 #include "CondTools/L1Trigger/interface/OMDSReader.h"
0020 #include "CondTools/L1TriggerExt/interface/DataWriterExt.h"
0021 #include "CondTools/L1Trigger/interface/Exception.h"
0022 
0023 #include "FWCore/Utilities/interface/typelookup.h"
0024 #include "FWCore/Framework/interface/EventSetup.h"
0025 
0026 #include "CondCore/CondDB/interface/Session.h"
0027 #include "CondCore/CondDB/interface/ConnectionPool.h"
0028 
0029 // forward declarations
0030 
0031 template <class TRcd, class TData>
0032 class L1ConfigOnlineProdBaseExt : public edm::ESProducer {
0033 public:
0034   L1ConfigOnlineProdBaseExt(const edm::ParameterSet&);
0035   ~L1ConfigOnlineProdBaseExt() override;
0036 
0037   std::unique_ptr<const TData> produce(const TRcd& iRecord);
0038 
0039   virtual std::unique_ptr<const TData> newObject(const std::string& objectKey, const TRcd& iRecord) = 0;
0040 
0041 private:
0042   // ----------member data ---------------------------
0043   edm::ESGetToken<L1TriggerKeyListExt, L1TriggerKeyListExtRcd> keyList_token;
0044   edm::ESGetToken<L1TriggerKeyExt, L1TriggerKeyExtRcd> key_token;
0045 
0046 protected:
0047   l1t::OMDSReader m_omdsReader;
0048   bool m_forceGeneration;
0049   edm::ESConsumesCollectorT<TRcd> wrappedSetWhatProduced(const edm::ParameterSet&);
0050 
0051   // Called from produce methods.
0052   // bool is true if the object data should be made.
0053   // If bool is false, produce method should throw
0054   // DataAlreadyPresentException.
0055   bool getObjectKey(const TRcd& record, std::string& objectKey);
0056 
0057   // For reading object directly from a CondDB w/o PoolDBOutputService
0058   cond::persistency::Session m_dbSession;
0059   bool m_copyFromCondDB;
0060 };
0061 
0062 template <class TRcd, class TData>
0063 L1ConfigOnlineProdBaseExt<TRcd, TData>::L1ConfigOnlineProdBaseExt(const edm::ParameterSet& iConfig)
0064     : m_omdsReader(),
0065       m_forceGeneration(iConfig.getParameter<bool>("forceGeneration")),
0066       m_dbSession(),
0067       m_copyFromCondDB(false) {
0068   //the following line is needed to tell the framework what
0069   // data is being produced
0070   // setWhatProduced(this)
0071   //   .setConsumes(keyList_token)
0072   //   .setConsumes(key_token);
0073 
0074   //now do what ever other initialization is needed
0075 
0076   if (iConfig.exists("copyFromCondDB")) {
0077     m_copyFromCondDB = iConfig.getParameter<bool>("copyFromCondDB");
0078 
0079     if (m_copyFromCondDB) {
0080       cond::persistency::ConnectionPool connectionPool;
0081       // Connect DB Session
0082       connectionPool.setAuthenticationPath(iConfig.getParameter<std::string>("onlineAuthentication"));
0083       connectionPool.configure();
0084       m_dbSession = connectionPool.createSession(iConfig.getParameter<std::string>("onlineDB"));
0085     }
0086   } else {
0087     m_omdsReader.connect(iConfig.getParameter<std::string>("onlineDB"),
0088                          iConfig.getParameter<std::string>("onlineAuthentication"));
0089   }
0090 }
0091 
0092 template <class TRcd, class TData>
0093 edm::ESConsumesCollectorT<TRcd> L1ConfigOnlineProdBaseExt<TRcd, TData>::wrappedSetWhatProduced(
0094     const edm::ParameterSet& iConfig) {
0095   auto collector = setWhatProduced(this);
0096   keyList_token = collector.consumes();
0097   key_token = collector.consumes();
0098   return collector;
0099 }
0100 
0101 template <class TRcd, class TData>
0102 L1ConfigOnlineProdBaseExt<TRcd, TData>::~L1ConfigOnlineProdBaseExt() {
0103   // do anything here that needs to be done at desctruction time
0104   // (e.g. close files, deallocate resources etc.)
0105 }
0106 
0107 template <class TRcd, class TData>
0108 std::unique_ptr<const TData> L1ConfigOnlineProdBaseExt<TRcd, TData>::produce(const TRcd& iRecord) {
0109   std::unique_ptr<const TData> pData;
0110 
0111   // Get object key and check if already in ORCON
0112   std::string key;
0113   if (getObjectKey(iRecord, key) || m_forceGeneration) {
0114     if (m_copyFromCondDB) {
0115       // Get L1TriggerKeyListExt from EventSetup
0116       const L1TriggerKeyListExtRcd& keyListRcd =
0117           ///    // Get L1TriggerKeyList from EventSetup
0118           ///    const L1TriggerKeyListRcd& keyListRcd =
0119           iRecord.template getRecord<L1TriggerKeyListExtRcd>();
0120       ///      iRecord.template getRecord< L1TriggerKeyListRcd >() ;
0121       ///    edm::ESHandle< L1TriggerKeyList > keyList ;
0122 
0123       auto const& keyList = keyListRcd.get(keyList_token);
0124 
0125       // Find payload token
0126       std::string recordName = edm::typelookup::className<TRcd>();
0127       std::string dataType = edm::typelookup::className<TData>();
0128       std::string payloadToken = keyList.token(recordName, dataType, key);
0129 
0130       edm::LogVerbatim("L1-O2O") << "Copying payload for " << recordName << "@" << dataType << " obj key " << key
0131                                  << " from CondDB.";
0132       edm::LogVerbatim("L1-O2O") << "TOKEN " << payloadToken;
0133 
0134       // Get object from POOL
0135       // Copied from l1t::DataWriter::readObject()
0136       if (!payloadToken.empty()) {
0137         m_dbSession.transaction().start();
0138         pData = m_dbSession.fetchPayload<TData>(payloadToken);
0139         m_dbSession.transaction().commit();
0140       }
0141     } else {
0142       pData = newObject(key, iRecord);
0143     }
0144 
0145     //     if( pData.get() == 0 )
0146     if (pData == std::unique_ptr<const TData>()) {
0147       std::string dataType = edm::typelookup::className<TData>();
0148 
0149       throw l1t::DataInvalidException("Unable to generate " + dataType + " for key " + key + ".");
0150     }
0151   } else {
0152     std::string dataType = edm::typelookup::className<TData>();
0153 
0154     throw l1t::DataAlreadyPresentException(dataType + " for key " + key + " already in CondDB.");
0155   }
0156 
0157   return pData;
0158 }
0159 
0160 template <class TRcd, class TData>
0161 bool L1ConfigOnlineProdBaseExt<TRcd, TData>::getObjectKey(const TRcd& record, std::string& objectKey) {
0162   // Get L1TriggerKeyExt
0163   const L1TriggerKeyExtRcd& keyRcd = record.template getRecord<L1TriggerKeyExtRcd>();
0164 
0165   // Explanation of funny syntax: since record is dependent, we are not
0166   // expecting getRecord to be a template so the compiler parses it
0167   // as a non-template. http://gcc.gnu.org/ml/gcc-bugs/2005-11/msg03685.html
0168 
0169   // If L1TriggerKeyExt is invalid, then all configuration objects are
0170   // already in ORCON.
0171   // edm::ESHandle<L1TriggerKeyExt> key_token;
0172   try {
0173     keyRcd.get(key_token);
0174   } catch (l1t::DataAlreadyPresentException& ex) {
0175     objectKey = std::string();
0176     return false;
0177   }
0178 
0179   // Get object key from L1TriggerKeyExt
0180   std::string recordName = edm::typelookup::className<TRcd>();
0181   std::string dataType = edm::typelookup::className<TData>();
0182 
0183   objectKey = keyRcd.get(key_token).get(recordName, dataType);
0184 
0185   /*    edm::LogVerbatim( "L1-O2O" ) */
0186   /*      << "L1ConfigOnlineProdBase record " << recordName */
0187   /*      << " type " << dataType << " obj key " << objectKey ; */
0188 
0189   // Get L1TriggerKeyListExt
0190   L1TriggerKeyListExt keyList;
0191   ///   // Get L1TriggerKeyList
0192   ///   L1TriggerKeyList keyList ;
0193   l1t::DataWriterExt dataWriter;
0194   ///   l1t::DataWriter dataWriter ;
0195   if (!dataWriter.fillLastTriggerKeyList(keyList)) {
0196     edm::LogError("L1-O2O") << "Problem getting last L1TriggerKeyListExt";
0197     ///         << "Problem getting last L1TriggerKeyList" ;
0198   }
0199 
0200   // If L1TriggerKeyList does not contain object key, token is empty
0201 
0202   return keyList.token(recordName, dataType, objectKey).empty();
0203 }
0204 
0205 #endif