diff --git a/DataFormats/L1TGlobal/interface/AXOL1TLScore.h b/DataFormats/L1TGlobal/interface/AXOL1TLScore.h new file mode 100644 index 0000000000000..9bad7ed301311 --- /dev/null +++ b/DataFormats/L1TGlobal/interface/AXOL1TLScore.h @@ -0,0 +1,71 @@ +#ifndef DataFormats_L1TGlobal_AXOL1TLScore_h +#define DataFormats_L1TGlobal_AXOL1TLScore_h + +/** +* \class AXOL1TLScore +* +* +* Description: L1 micro Global Trigger - Extra NN score emulation information for AXOL1TL. +* +* +* \author: Melissa Quinnan - UC San Diego +* +* +*/ + +// system include files +#include +#include +#include + +// user include files +#include "FWCore/Utilities/interface/typedefs.h" +#include "DataFormats/L1Trigger/interface/L1Candidate.h" +#include "DataFormats/L1Trigger/interface/BXVector.h" +#include "DataFormats/L1Trigger/interface/L1TObjComparison.h" + +// forward declarations + +// namespace l1t { +class AXOL1TLScore; +typedef BXVector AXOL1TLScoreBxCollection; + +typedef l1t::ObjectRef AXOL1TLScoreRef; +typedef l1t::ObjectRefBxCollection AXOL1TLScoreRefBxCollection; +// typedef l1t::ObjectRefPair AXOL1TLScoreRefPair; +// typedef l1t::ObjectRefPairBxCollection AXOL1TLScoreRefPairBxCollection; //dont think pair part is needed + +// class interface +class AXOL1TLScore { +public: + /// constructors + AXOL1TLScore(); //empty constructor + + AXOL1TLScore(int bxInEvent); + + AXOL1TLScore(int bxInEvent, float score); + + /// destructor + virtual ~AXOL1TLScore(); + + ///set/get axo score and other simple members + void setAXOScore(float score) { axoscore_ = score; } + void setbxInEventNr(int bxNr) { m_bxInEvent = bxNr; } + + inline float const& getAXOScore() const { return axoscore_; } + inline const int getbxInEventNr() const { return m_bxInEvent; } + + void reset(); + +private: + /// bunch cross in the GT event record (E,F,0,1,2) + int m_bxInEvent; + + //axo score value + float axoscore_; + + //store version or type of network? + // std::string nnversion; +}; +//} l1t namespace +#endif /*DataFormats_L1TGlobal_AXOL1TLScore_h*/ diff --git a/DataFormats/L1TGlobal/src/AXOL1TLScore.cc b/DataFormats/L1TGlobal/src/AXOL1TLScore.cc new file mode 100644 index 0000000000000..dae03f851257b --- /dev/null +++ b/DataFormats/L1TGlobal/src/AXOL1TLScore.cc @@ -0,0 +1,28 @@ +/** +* \class AXOL1TLScore +* +* +* +* \author: Melissa Quinnan -- UC San Diego +* +* +*/ + +// this class header +#include "DataFormats/L1TGlobal/interface/AXOL1TLScore.h" + +void AXOL1TLScore::reset() { + axoscore_ = 0.0; + m_bxInEvent = 0; +} + +AXOL1TLScore::AXOL1TLScore() { reset(); } + +AXOL1TLScore::AXOL1TLScore(int bxInEvent) : m_bxInEvent(bxInEvent) { axoscore_ = 0.0; } + +AXOL1TLScore::AXOL1TLScore(int bxInEvent, float score) : m_bxInEvent(bxInEvent), axoscore_(score) {} + +//destructor +AXOL1TLScore::~AXOL1TLScore() { + //empty +} diff --git a/DataFormats/L1TGlobal/src/classes.h b/DataFormats/L1TGlobal/src/classes.h index b881e49055c03..df5cfeda47359 100644 --- a/DataFormats/L1TGlobal/src/classes.h +++ b/DataFormats/L1TGlobal/src/classes.h @@ -2,6 +2,7 @@ #include "DataFormats/Common/interface/Wrapper.h" #include "DataFormats/L1TGlobal/interface/GlobalAlgBlk.h" #include "DataFormats/L1TGlobal/interface/GlobalExtBlk.h" +#include "DataFormats/L1TGlobal/interface/AXOL1TLScore.h" #include "DataFormats/L1TGlobal/interface/GlobalObjectMapRecord.h" #include "DataFormats/L1TGlobal/interface/GlobalObjectMapFwd.h" #include "DataFormats/L1TGlobal/interface/GlobalObjectMap.h" diff --git a/DataFormats/L1TGlobal/src/classes_def.xml b/DataFormats/L1TGlobal/src/classes_def.xml index 12c69e7bbd273..b1df5c7316978 100644 --- a/DataFormats/L1TGlobal/src/classes_def.xml +++ b/DataFormats/L1TGlobal/src/classes_def.xml @@ -19,6 +19,13 @@ + + + + + + + @@ -55,6 +62,11 @@ + + + + + diff --git a/L1Trigger/L1TGlobal/interface/AXOL1TLCondition.h b/L1Trigger/L1TGlobal/interface/AXOL1TLCondition.h index 64540dce2714b..2d485447aa272 100644 --- a/L1Trigger/L1TGlobal/interface/AXOL1TLCondition.h +++ b/L1Trigger/L1TGlobal/interface/AXOL1TLCondition.h @@ -59,6 +59,11 @@ namespace l1t { void setuGtB(const GlobalBoard*); + /// get/set score value + void setScore(const float scoreval) const; + + inline float getScore() const { return m_savedscore; } + private: /// copy function for copy constructor and operator= void copy(const AXOL1TLCondition& cp); @@ -68,6 +73,9 @@ namespace l1t { /// pointer to uGt GlobalBoard, to be able to get the trigger objects const GlobalBoard* m_gtGTB; + + ///axo score for possible score saving + mutable float m_savedscore; }; } // namespace l1t diff --git a/L1Trigger/L1TGlobal/interface/GlobalBoard.h b/L1Trigger/L1TGlobal/interface/GlobalBoard.h index a6d14a0c8d5a6..b21fc432c2562 100644 --- a/L1Trigger/L1TGlobal/interface/GlobalBoard.h +++ b/L1Trigger/L1TGlobal/interface/GlobalBoard.h @@ -39,6 +39,7 @@ // Objects to produce for the output record. #include "DataFormats/L1TGlobal/interface/GlobalAlgBlk.h" #include "DataFormats/L1TGlobal/interface/GlobalExtBlk.h" +#include "DataFormats/L1TGlobal/interface/AXOL1TLScore.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" @@ -90,6 +91,8 @@ namespace l1t { void receiveExternalData(const edm::Event&, const edm::EDGetTokenT>&, const bool receiveExt); + void fillAXOScore(int iBxInEvent, std::unique_ptr& AxoScoreRecord); + /// initialize the class (mainly reserve) void init(const int numberPhysTriggers, const int nrL1Mu, @@ -207,6 +210,8 @@ namespace l1t { public: inline void setVerbosity(const int verbosity) { m_verbosity = verbosity; } + inline void enableAXOScoreSaving(bool savescore) { m_saveAXOScore = savescore; } + private: // cached stuff @@ -247,6 +252,11 @@ namespace l1t { GlobalAlgBlk m_uGtAlgBlk; + //for optional software-only saving of axol1tl score + AXOL1TLScore m_uGtAXOScore; //score dataformat + float m_storedAXOScore = -999.0; //score from cond class + bool m_saveAXOScore = false; + // cache of maps std::vector m_conditionResultMaps; diff --git a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc index 81a51738e67c5..500d61085f440 100644 --- a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc +++ b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc @@ -27,6 +27,7 @@ #include "DataFormats/L1TGlobal/interface/GlobalAlgBlk.h" #include "DataFormats/L1TGlobal/interface/GlobalExtBlk.h" #include "DataFormats/L1TGlobal/interface/GlobalObjectMapRecord.h" +#include "DataFormats/L1TGlobal/interface/AXOL1TLScore.h" #include "L1Trigger/L1TGlobal/interface/TriggerMenu.h" @@ -71,6 +72,9 @@ void L1TGlobalProducer::fillDescriptions(edm::ConfigurationDescriptions& descrip // switch for muon showers in Run-3 desc.add("useMuonShowers", false); + //switch for saving AXO score + desc.add("produceAXOL1TLScore", false); + // disables resetting the prescale counters each lumisection (needed for offline) // originally, the L1T firmware applied the reset of prescale counters at the end of every LS; // this reset was disabled in the L1T firmware starting from run-362658 (November 25th, 2022), see @@ -130,7 +134,8 @@ L1TGlobalProducer::L1TGlobalProducer(const edm::ParameterSet& parSet) m_algoblkInputTag(parSet.getParameter("AlgoBlkInputTag")), m_resetPSCountersEachLumiSec(parSet.getParameter("resetPSCountersEachLumiSec")), m_semiRandomInitialPSCounters(parSet.getParameter("semiRandomInitialPSCounters")), - m_useMuonShowers(parSet.getParameter("useMuonShowers")) { + m_useMuonShowers(parSet.getParameter("useMuonShowers")), + m_produceAXOL1TLScore(parSet.getParameter("produceAXOL1TLScore")) { m_egInputToken = consumes>(m_egInputTag); m_tauInputToken = consumes>(m_tauInputTag); m_jetInputToken = consumes>(m_jetInputTag); @@ -208,6 +213,10 @@ L1TGlobalProducer::L1TGlobalProducer(const edm::ParameterSet& parSet) produces(); } + if (m_produceAXOL1TLScore) { + produces("AXOScore"); + } + // create new uGt Board m_uGtBrd = std::make_unique(); m_uGtBrd->setVerbosity(m_verbosity); @@ -556,6 +565,11 @@ void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSet // * produce the GlobalObjectMapRecord std::unique_ptr gtObjectMapRecord(new GlobalObjectMapRecord()); + std::unique_ptr uGtAXOScoreRecord(nullptr); + if (m_produceAXOL1TLScore) { + uGtAXOScoreRecord = std::make_unique(); + } + // fill the boards not depending on the BxInEvent in the L1 GT DAQ record // GMT, PSB and FDL depend on BxInEvent @@ -624,6 +638,9 @@ void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSet if (m_useMuonShowers) m_uGtBrd->receiveMuonShowerObjectData(iEvent, m_muShowerInputToken, receiveMuShower, m_nrL1MuShower); + //tell board to save axo scores when running GTL + m_uGtBrd->enableAXOScoreSaving(m_produceAXOL1TLScore); + m_uGtBrd->receiveExternalData(iEvent, m_extInputToken, receiveExt); // loop over BxInEvent @@ -668,6 +685,11 @@ void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSet m_l1GtMenu->gtTriggerMenuImplementation()); } + //save scores to score collection + if (m_produceAXOL1TLScore) { + m_uGtBrd->fillAXOScore(iBxInEvent, uGtAXOScoreRecord); + } + } //End Loop over Bx // Add explicit reset of Board @@ -710,6 +732,10 @@ void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSet if (m_produceL1GtObjectMapRecord) { iEvent.put(std::move(gtObjectMapRecord)); } + + if (m_produceAXOL1TLScore) { + iEvent.put(std::move(uGtAXOScoreRecord), "AXOScore"); + } } //define this as a plug-in diff --git a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h index 2da54f435f6fb..f7321eeb64536 100644 --- a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h +++ b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h @@ -197,6 +197,9 @@ class L1TGlobalProducer : public edm::stream::EDProducer<> { // switch to load muon showers in the global board bool m_useMuonShowers; + + //switch to save axo scores in global board + bool m_produceAXOL1TLScore; }; #endif // L1TGlobalProducer_h diff --git a/L1Trigger/L1TGlobal/src/AXOL1TLCondition.cc b/L1Trigger/L1TGlobal/src/AXOL1TLCondition.cc index 83fdc4225bbbc..f8266d9f6d4ce 100644 --- a/L1Trigger/L1TGlobal/src/AXOL1TLCondition.cc +++ b/L1Trigger/L1TGlobal/src/AXOL1TLCondition.cc @@ -85,6 +85,9 @@ void l1t::AXOL1TLCondition::setGtAXOL1TLTemplate(const AXOL1TLTemplate* caloTemp /// set the pointer to uGT GlobalBoard void l1t::AXOL1TLCondition::setuGtB(const GlobalBoard* ptrGTB) { m_gtGTB = ptrGTB; } +/// set score for score saving +void l1t::AXOL1TLCondition::setScore(const float scoreval) const { m_savedscore = scoreval; } + const bool l1t::AXOL1TLCondition::evaluateCondition(const int bxEval) const { bool condResult = false; int useBx = bxEval + m_gtAXOL1TLTemplate->condRelativeBx(); @@ -236,6 +239,8 @@ const bool l1t::AXOL1TLCondition::evaluateCondition(const int bxEval) const { result = ADModelResult.first; loss = ADModelResult.second; score = ((loss).to_float()) * 16.0; //scaling to match threshold + //save score to class variable in case score saving needed + setScore(score); //number of objects/thrsholds to check int iCondition = 0; // number of conditions: there is only one diff --git a/L1Trigger/L1TGlobal/src/GlobalBoard.cc b/L1Trigger/L1TGlobal/src/GlobalBoard.cc index b026a2fd1af68..5bea6c0c2d784 100644 --- a/L1Trigger/L1TGlobal/src/GlobalBoard.cc +++ b/L1Trigger/L1TGlobal/src/GlobalBoard.cc @@ -76,6 +76,7 @@ l1t::GlobalBoard::GlobalBoard() m_currentLumi(0), m_isDebugEnabled(edm::isDebugEnabled()) { m_uGtAlgBlk.reset(); + m_uGtAXOScore.reset(); m_gtlAlgorithmOR.reset(); m_gtlDecisionWord.reset(); @@ -492,6 +493,22 @@ void l1t::GlobalBoard::receiveExternalData(const edm::Event& iEvent, } //end if ReceiveExt data } +// fill axo score value per bx in event +void l1t::GlobalBoard::fillAXOScore(int iBxInEvent, std::unique_ptr& AxoScoreRecord) { + m_uGtAXOScore.reset(); + m_uGtAXOScore.setbxInEventNr((iBxInEvent & 0xF)); + + //save stored condition score if Bx is zero, else set to 0 + float scorevalue = 0.0; + if (iBxInEvent == 0) { + scorevalue = m_storedAXOScore; + } + + //set dataformat value + m_uGtAXOScore.setAXOScore(scorevalue); + AxoScoreRecord->push_back(iBxInEvent, m_uGtAXOScore); +} + // run GTL void l1t::GlobalBoard::runGTL(const edm::Event&, const edm::EventSetup& evSetup, @@ -655,6 +672,12 @@ void l1t::GlobalBoard::runGTL(const edm::Event&, cMapResults[itCond->first] = axol1tlCondition; + //for optional software-only saving of axol1tl score + //m_storedAXOScore < 0.0 ensures only sets once per condition if score not default of -999 + if (m_saveAXOScore && m_storedAXOScore < 0.0) { + m_storedAXOScore = axol1tlCondition->getScore(); + } + if (m_verbosity && m_isDebugEnabled) { std::ostringstream myCout; axol1tlCondition->print(myCout); @@ -1154,6 +1177,10 @@ void l1t::GlobalBoard::reset() { m_uGtAlgBlk.reset(); + //reset AXO score + m_storedAXOScore = -999.0; + m_uGtAXOScore.reset(); + m_gtlDecisionWord.reset(); m_gtlAlgorithmOR.reset(); } diff --git a/L1Trigger/L1TNtuples/plugins/L1AXOTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1AXOTreeProducer.cc new file mode 100644 index 0000000000000..73224dd8974f3 --- /dev/null +++ b/L1Trigger/L1TNtuples/plugins/L1AXOTreeProducer.cc @@ -0,0 +1,93 @@ +// system include files +#include + +// {fmt} headers +#include + +// ROOT +#include + +// framework and data formats +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "CondFormats/DataRecord/interface/L1TUtmTriggerMenuRcd.h" +#include "CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h" +#include "DataFormats/L1TGlobal/interface/AXOL1TLScore.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" + +// +// class declaration +// + +class L1AXOTreeProducer : public edm::one::EDAnalyzer { +public: + explicit L1AXOTreeProducer(edm::ParameterSet const &); + ~L1AXOTreeProducer() override = default; + +private: + void beginJob() override; + void analyze(edm::Event const &, edm::EventSetup const &) override; + void endJob() override; + +private: + // output file + edm::Service fs_; + + // pointers to the objects that will be stored as branches within the tree + float anomaly_score; + + // tree + TTree *tree_; + + // EDM input tokens + const edm::EDGetTokenT scoreToken_; +}; + +L1AXOTreeProducer::L1AXOTreeProducer(edm::ParameterSet const &config) + : anomaly_score(0.0f), + tree_(nullptr), + scoreToken_(consumes(config.getUntrackedParameter("axoscoreToken"))) { + usesResource(TFileService::kSharedResource); + // set up the TTree and its branches + tree_ = fs_->make("L1AXOTree", "L1AXOTree"); + tree_->Branch("axo_score", &anomaly_score, "axo_score/F"); +} + +// +// member functions +// + +// ------------ method called to for each event ------------ +void L1AXOTreeProducer::analyze(edm::Event const &event, edm::EventSetup const &setup) { + //save axo score + edm::Handle axo; + event.getByToken(scoreToken_, axo); + + float const *ptr; + + if (axo.isValid()) { + ptr = &axo->at(0, 0).getAXOScore(); + anomaly_score = *ptr; + + } else { + edm::LogWarning("MissingProduct") << "AXOL1TLScoreBxCollection not found. Branch will not be filled" << std::endl; + } + + tree_->Fill(); +} + +// ------------ method called once each job just before starting event loop ------------ +void L1AXOTreeProducer::beginJob(void) {} + +// ------------ method called once each job just after ending the event loop ------------ +void L1AXOTreeProducer::endJob() {} + +//define this as a plug-in +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1AXOTreeProducer); diff --git a/L1Trigger/L1TNtuples/python/L1NtupleEMU_cff.py b/L1Trigger/L1TNtuples/python/L1NtupleEMU_cff.py index 703f3e6161e6c..911aee007008c 100644 --- a/L1Trigger/L1TNtuples/python/L1NtupleEMU_cff.py +++ b/L1Trigger/L1TNtuples/python/L1NtupleEMU_cff.py @@ -8,6 +8,7 @@ from L1Trigger.L1TNtuples.l1UpgradeTree_cfi import * from L1Trigger.L1TNtuples.l1EventTree_cfi import * from L1Trigger.L1TNtuples.l1uGTTree_cfi import * +from L1Trigger.L1TNtuples.l1AXOTree_cfi import * l1UpgradeTfMuonEmuTree = l1UpgradeTfMuonTree.clone() l1UpgradeTfMuonEmuTree.bmtfMuonToken = cms.untracked.InputTag("simBmtfDigis","BMTF") @@ -50,6 +51,9 @@ l1uGTEmuTree = l1uGTTree.clone() l1uGTEmuTree.ugtToken = cms.InputTag("simGtStage2Digis") +l1AXOEmuTree = l1AXOTree.clone() +l1AXOEmuTree.axoscoreToken = cms.untracked.InputTag("simGtStage2Digis","AXOScore") + L1NtupleEMU = cms.Sequence( l1EventTree +l1UpgradeTfMuonEmuTree @@ -58,4 +62,5 @@ +l1UpgradeEmuTree # +l1MuonEmuTree +l1uGTEmuTree + +l1AXOEmuTree ) diff --git a/L1Trigger/L1TNtuples/python/l1AXOTree_cfi.py b/L1Trigger/L1TNtuples/python/l1AXOTree_cfi.py new file mode 100644 index 0000000000000..a8135483aa4a6 --- /dev/null +++ b/L1Trigger/L1TNtuples/python/l1AXOTree_cfi.py @@ -0,0 +1,5 @@ +import FWCore.ParameterSet.Config as cms + +l1AXOTree = cms.EDAnalyzer("L1AXOTreeProducer", + axoscoreToken = cms.untracked.InputTag("simGtStage2Digis","AXOScore") +)