Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-31 22:25:35

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