Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[L1-O2O] ESGetToken migration L1CondDBPayloadWriter and O2O unit tests #37602

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 13 additions & 7 deletions CondTools/L1Trigger/interface/WriterProxy.h
Expand Up @@ -3,6 +3,7 @@

#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Framework/interface/ESHandle.h"
#include "FWCore/Framework/interface/ConsumesCollector.h"

#include "FWCore/PluginManager/interface/PluginFactory.h"

Expand Down Expand Up @@ -32,6 +33,8 @@ namespace l1t {
* methods here.
*/

virtual void setToken(edm::ConsumesCollector cc) = 0;

virtual std::string save(const edm::EventSetup& setup) const = 0;

protected:
Expand All @@ -42,20 +45,24 @@ namespace l1t {
*/
template <class Record, class Type>
class WriterProxyT : public WriterProxy {
private:
edm::ESGetToken<Type, Record> rcdToken;

public:
~WriterProxyT() override {}

void setToken(edm::ConsumesCollector cc) override { rcdToken = cc.esConsumes(); }

/* This method requires that Record and Type supports copy constructor */
std::string save(const edm::EventSetup& setup) const override {
// load record and type from EventSetup and save them in db
edm::ESHandle<Type> handle;

try {
setup.get<Record>().get(handle);
handle = setup.getHandle(rcdToken);
} catch (l1t::DataAlreadyPresentException& ex) {
return std::string();
}

// If handle is invalid, then data is already in DB

edm::Service<cond::service::PoolDBOutputService> poolDb;
Expand All @@ -64,14 +71,13 @@ namespace l1t {
}
poolDb->forceInit();
cond::persistency::Session session = poolDb->session();
cond::persistency::TransactionScope tr(session.transaction());
// if throw transaction will unroll
/// tr.start(false);
if (not session.transaction().isActive())
session.transaction().start(false); // true: read only, false: read-write

std::shared_ptr<Type> pointer = std::make_shared<Type>(*(handle.product()));
std::string payloadToken = session.storePayload(*pointer);
/// tr.commit();
tr.close();

session.transaction().commit();
return payloadToken;
}
};
Expand Down
13 changes: 11 additions & 2 deletions CondTools/L1TriggerExt/interface/DataWriterExt.h
Expand Up @@ -32,15 +32,19 @@ namespace l1t {
* REGISTER_PLUGIN(record, type) from registration_macros.h found in PluginSystem.
*/

typedef std::unique_ptr<WriterProxy> WriterProxyPtr;

class DataWriterExt {
public:
DataWriterExt();
DataWriterExt(const std::string&);
~DataWriterExt();

// Payload and IOV writing functions.

// Get payload from EventSetup and write to DB with no IOV
// recordType = "record@type", return value is payload token
std::string writePayload(const edm::EventSetup& setup);
std::string writePayload(const edm::EventSetup& setup, const std::string& recordType);

// Use PoolDBOutputService to append IOV with sinceRun to IOV sequence
Expand All @@ -65,6 +69,11 @@ namespace l1t {

bool fillLastTriggerKeyList(L1TriggerKeyListExt& output);

WriterProxy* getWriter() { return writer_.get(); }

private:
WriterProxyPtr writer_;

protected:
};

Expand All @@ -77,12 +86,12 @@ namespace l1t {

poolDb->forceInit();
cond::persistency::Session session = poolDb->session();
/// session.transaction().start(true);
session.transaction().start(true);

// Get object from CondDB
std::shared_ptr<T> ref = session.fetchPayload<T>(payloadToken);
outputObject = *ref;
/// session.transaction().commit ();
session.transaction().commit();
}

} // namespace l1t
Expand Down
171 changes: 97 additions & 74 deletions CondTools/L1TriggerExt/plugins/L1CondDBPayloadWriterExt.cc
Expand Up @@ -15,6 +15,9 @@
#include "FWCore/Utilities/interface/ESGetToken.h"
#include "CondTools/L1TriggerExt/interface/DataWriterExt.h"

using DataWriterExtPtr = std::unique_ptr<l1t::DataWriterExt>;
using RecordToWriterMap = std::map<std::string, DataWriterExtPtr>;

class L1CondDBPayloadWriterExt : public edm::one::EDAnalyzer<> {
public:
explicit L1CondDBPayloadWriterExt(const edm::ParameterSet&);
Expand All @@ -26,7 +29,7 @@ class L1CondDBPayloadWriterExt : public edm::one::EDAnalyzer<> {
void endJob() override;

// ----------member data ---------------------------
l1t::DataWriterExt m_writer;
RecordToWriterMap m_rcdToWriterMap;
// std::string m_tag ; // tag is known by PoolDBOutputService

// set to false to write config data without valid TSC key
Expand All @@ -53,7 +56,15 @@ L1CondDBPayloadWriterExt::L1CondDBPayloadWriterExt(const edm::ParameterSet& iCon
m_overwriteKeys(iConfig.getParameter<bool>("overwriteKeys")),
m_logTransactions(iConfig.getParameter<bool>("logTransactions")),
m_newL1TriggerKeyListExt(iConfig.getParameter<bool>("newL1TriggerKeyListExt")),
theL1TriggerKeyExtToken_(esConsumes()) {}
theL1TriggerKeyExtToken_(esConsumes()) {
auto cc = consumesCollector();
for (const auto& sysWriter : iConfig.getParameter<std::vector<std::string>>("sysWriters")) {
//construct writer
DataWriterExtPtr writer = std::make_unique<l1t::DataWriterExt>(sysWriter);
writer->getWriter()->setToken(cc);
m_rcdToWriterMap[sysWriter] = std::move(writer); //the sysWriter holds info in 'rcd@prod' format
}
}

L1CondDBPayloadWriterExt::~L1CondDBPayloadWriterExt() {
// do anything here that needs to be done at desctruction time
Expand All @@ -66,12 +77,10 @@ void L1CondDBPayloadWriterExt::analyze(const edm::Event& iEvent, const edm::Even

// Get L1TriggerKeyListExt and make a copy
L1TriggerKeyListExt oldKeyList;
l1t::DataWriterExt& m_writer = *m_rcdToWriterMap.at("L1TriggerKeyExtRcd@L1TriggerKeyExt");

if (!m_newL1TriggerKeyListExt) {
if (!m_writer.fillLastTriggerKeyList(oldKeyList)) {
edm::LogError("L1-O2O") << "Problem getting last L1TriggerKeyListExt";
}
}
if (not(m_newL1TriggerKeyListExt or m_writer.fillLastTriggerKeyList(oldKeyList)))
edm::LogError("L1-O2O") << "Problem getting last L1TriggerKeyListExt";

L1TriggerKeyListExt* keyList = nullptr;

Expand All @@ -93,84 +102,98 @@ void L1CondDBPayloadWriterExt::analyze(const edm::Event& iEvent, const edm::Even
edm::LogVerbatim("L1-O2O") << ex.what();
}

if (triggerKeyOK && m_writeL1TriggerKeyExt) {
edm::LogVerbatim("L1-O2O") << "Object key for L1TriggerKeyExtRcd@L1TriggerKeyExt: " << key.tscKey();
token = m_writer.writePayload(iSetup, "L1TriggerKeyExtRcd@L1TriggerKeyExt");
if (triggerKeyOK and m_writeL1TriggerKeyExt) {
edm::LogVerbatim("L1-O2O") << "Object key for L1TriggerKeyExtRcd@L1TriggerKeyExt: " << key.tscKey()
<< " (about to run writePayload)";
token = m_writer.writePayload(iSetup);
}

// If L1TriggerKeyExt is invalid (empty), then all configuration data is already in DB
// m_writeL1TriggerKeyExt the naming is misleading,
// the bool is used to say to the module whether it runs or not to update a L1TriggerKeyExtRcd
// (so if no payload for L1TriggerKeyExtRcd AND you run for updating L1TriggerKeyExtRcd ==> you have nothing to update)
if (token.empty() and m_writeL1TriggerKeyExt) {
edm::LogInfo("L1CondDBPayloadWriterExt::analyze") << " token = " << token;
return;
}

// If L1TriggerKeyExt is invalid, then all configuration data is already in DB
// Record token in L1TriggerKeyListExt
if (m_writeL1TriggerKeyExt) {
keyList = new L1TriggerKeyListExt(oldKeyList);
if (not keyList->addKey(key.tscKey(), token, m_overwriteKeys))
throw cond::Exception("L1CondDBPayloadWriter: TSC key " + key.tscKey() + " already in L1TriggerKeyListExt");
}

if (not m_writeConfigData) {
// Write L1TriggerKeyListExt to ORCON
if (keyList)
m_writer.writeKeyList(keyList, 0, m_logTransactions);
return;
}

// Loop over record@type in L1TriggerKeyExt
// (as before make writers, try to write payload and if needed handle exceptions)

// this is not needed maps have implemented begin and end methods for their iterators
// L1TriggerKeyExt::RecordToKey::const_iterator it = key.recordToKeyMap().begin();
// L1TriggerKeyExt::RecordToKey::const_iterator end = key.recordToKeyMap().end();
// for (; it != end; ++it) {

bool throwException = false;
for (const auto& it : key.recordToKeyMap()) {
// If there isn't any WriterProxyT constructed for this rcd, continue
// (the missing rcds are left out for a reason - those are static that throw exceptions that cannot be handled in 12_3)
if (m_rcdToWriterMap.find(it.first) == m_rcdToWriterMap.end())
continue;

// Do nothing if object key is null.
// (Panos) this might not be working as the "empty" keys are L1TriggerKeyExt::kEmptyKey (std::string(""))
if (it.second == L1TriggerKeyExt::kNullKey) {
edm::LogVerbatim("L1-O2O") << "L1CondDBPayloadWriter: null object key for " << it.first
<< "; skipping this record.";
continue;
}

if (!token.empty() || !m_writeL1TriggerKeyExt) {
// Record token in L1TriggerKeyListExt
if (m_writeL1TriggerKeyExt) {
keyList = new L1TriggerKeyListExt(oldKeyList);
if (!(keyList->addKey(key.tscKey(), token, m_overwriteKeys))) {
throw cond::Exception("L1CondDBPayloadWriter: TSC key " + key.tscKey() + " already in L1TriggerKeyListExt");
// Check key is new before writing
if (oldKeyList.token(it.first, it.second).empty() || m_overwriteKeys) {
// Write data to ORCON with no IOV
if (!oldKeyList.token(it.first, it.second).empty()) {
edm::LogVerbatim("L1-O2O") << "*** Overwriting payload: object key for " << it.first << ": " << it.second;
} else {
edm::LogVerbatim("L1-O2O") << "object key for " << it.first << ": " << it.second;
}
}

if (m_writeConfigData) {
// Loop over record@type in L1TriggerKeyExt
L1TriggerKeyExt::RecordToKey::const_iterator it = key.recordToKeyMap().begin();
L1TriggerKeyExt::RecordToKey::const_iterator end = key.recordToKeyMap().end();

for (; it != end; ++it) {
// Do nothing if object key is null.
if (it->second == L1TriggerKeyExt::kNullKey) {
edm::LogVerbatim("L1-O2O") << "L1CondDBPayloadWriter: null object key for " << it->first
<< "; skipping this record.";
} else {
// Check key is new before writing
if (oldKeyList.token(it->first, it->second).empty() || m_overwriteKeys) {
// Write data to ORCON with no IOV
if (!oldKeyList.token(it->first, it->second).empty()) {
edm::LogVerbatim("L1-O2O") << "*** Overwriting payload: object key for " << it->first << ": "
<< it->second;
} else {
edm::LogVerbatim("L1-O2O") << "object key for " << it->first << ": " << it->second;
}

try {
token = m_writer.writePayload(iSetup, it->first);
} catch (l1t::DataInvalidException& ex) {
edm::LogVerbatim("L1-O2O") << ex.what() << " Skipping to next record.";

throwException = true;

continue;
}

if (!token.empty()) {
// Record token in L1TriggerKeyListExt
if (!keyList) {
keyList = new L1TriggerKeyListExt(oldKeyList);
}

if (!(keyList->addKey(it->first, it->second, token, m_overwriteKeys))) {
// This should never happen because of the check
// above, but just in case....
throw cond::Exception("L1CondDBPayloadWriter: subsystem key " + it->second + " for " + it->first +
" already in L1TriggerKeyListExt");
}
}
} else {
edm::LogVerbatim("L1-O2O") << "L1CondDBPayloadWriter: object key " << it->second << " for " << it->first
<< " already in L1TriggerKeyListExt";
}
}
try {
edm::LogVerbatim("L1-O2O") << "about to run writePayload for " << it.first;
token = m_rcdToWriterMap.at(it.first)->writePayload(iSetup);
} catch (l1t::DataInvalidException& ex) {
edm::LogVerbatim("L1-O2O") << ex.what() << " Skipping to next record.";
throwException = true;
continue;
}
}
}

if (keyList) {
// Write L1TriggerKeyListExt to ORCON
if (!token.empty()) {
// Record token in L1TriggerKeyListExt
if (!keyList)
keyList = new L1TriggerKeyListExt(oldKeyList);
// The following should never happen because of the check
// above, but just in case....
if (!(keyList->addKey(it.first, it.second, token, m_overwriteKeys)))
throw cond::Exception("L1CondDBPayloadWriter")
<< "subsystem key " << it.second << " for " << it.first << " already in L1TriggerKeyListExt";
}

} else
edm::LogVerbatim("L1-O2O") << "L1CondDBPayloadWriter: object key " << it.second << " for " << it.first
<< " already in L1TriggerKeyListExt";

} // for rcds from keys

if (keyList) // Write L1TriggerKeyListExt to ORCON
m_writer.writeKeyList(keyList, 0, m_logTransactions);
}

if (throwException) {
if (throwException)
throw l1t::DataInvalidException("Payload problem found.");
}
}

// ------------ method called once each job just before starting event loop ------------
Expand Down
27 changes: 20 additions & 7 deletions CondTools/L1TriggerExt/python/L1CondDBPayloadWriterExt_cfi.py
@@ -1,11 +1,24 @@
import FWCore.ParameterSet.Config as cms

L1CondDBPayloadWriterExt = cms.EDAnalyzer("L1CondDBPayloadWriterExt",
writeL1TriggerKeyExt = cms.bool(True),
writeConfigData = cms.bool(True),
overwriteKeys = cms.bool(False),
logTransactions = cms.bool(False),
newL1TriggerKeyListExt = cms.bool(False)
)
L1CondDBPayloadWriterExt = cms.EDAnalyzer(
"L1CondDBPayloadWriterExt",
writeL1TriggerKeyExt = cms.bool(True),
writeConfigData = cms.bool(True),
overwriteKeys = cms.bool(False),
logTransactions = cms.bool(False),
newL1TriggerKeyListExt = cms.bool(False),
sysWriters = cms.vstring(
"L1TriggerKeyExtRcd@L1TriggerKeyExt",
"L1TCaloParamsO2ORcd@CaloParams",
"L1TGlobalPrescalesVetosFractO2ORcd@L1TGlobalPrescalesVetosFract",
"L1TMuonBarrelParamsO2ORcd@L1TMuonBarrelParams",
"L1TMuonEndCapForestO2ORcd@L1TMuonEndCapForest",
"L1TMuonEndCapParamsO2ORcd@L1TMuonEndCapParams",
"L1TMuonGlobalParamsO2ORcd@L1TMuonGlobalParams",
"L1TMuonOverlapFwVersionO2ORcd@L1TMuonOverlapFwVersion",
"L1TMuonOverlapParamsO2ORcd@L1TMuonOverlapParams",
"L1TUtmTriggerMenuO2ORcd@L1TUtmTriggerMenu"
)
)