ATLAS Offline Software
Loading...
Searching...
No Matches
JfexSimMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
5
6JfexSimMonitorAlgorithm::JfexSimMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator ) : AthMonitorAlgorithm(name,pSvcLocator) {}
7
9
10 ATH_MSG_DEBUG("Initializing JfexSimMonitorAlgorithm algorithm with name: "<< name());
11
12
13 ATH_MSG_DEBUG("m_data_key_jJ " << m_data_key_jJ );
14 ATH_MSG_DEBUG("m_data_key_jLJ " << m_data_key_jLJ );
15 ATH_MSG_DEBUG("m_data_key_jTau " << m_data_key_jTau );
16 ATH_MSG_DEBUG("m_data_key_jEM " << m_data_key_jEM );
17 ATH_MSG_DEBUG("m_data_key_jXE " << m_data_key_jXE );
18 ATH_MSG_DEBUG("m_data_key_jTE " << m_data_key_jTE );
19
20 ATH_MSG_DEBUG("m_simu_key_jJ " << m_simu_key_jJ );
21 ATH_MSG_DEBUG("m_simu_key_jLJ " << m_simu_key_jLJ );
22 ATH_MSG_DEBUG("m_simu_key_jTau " << m_simu_key_jTau );
23 ATH_MSG_DEBUG("m_simu_key_jEM " << m_simu_key_jEM );
24 ATH_MSG_DEBUG("m_simu_key_jXE " << m_simu_key_jXE );
25 ATH_MSG_DEBUG("m_simu_key_jTE " << m_simu_key_jTE );
26
27
28 // we initialise all the containers
29 ATH_CHECK( m_data_key_jJ.initialize() );
30 ATH_CHECK( m_data_key_jLJ.initialize() );
31 ATH_CHECK( m_data_key_jTau.initialize() );
32 ATH_CHECK( m_data_key_jEM.initialize() );
33 ATH_CHECK( m_data_key_jXE.initialize() );
34 ATH_CHECK( m_data_key_jTE.initialize() );
35
36 ATH_CHECK( m_simu_key_jJ.initialize() );
37 ATH_CHECK( m_simu_key_jLJ.initialize() );
38 ATH_CHECK( m_simu_key_jTau.initialize() );
39 ATH_CHECK( m_simu_key_jEM.initialize() );
40 ATH_CHECK( m_simu_key_jXE.initialize() );
41 ATH_CHECK( m_simu_key_jTE.initialize() );
42
43 ATH_CHECK( m_jFexTowerKey.initialize() );
44 ATH_CHECK( m_scellKey.initialize() );
45
46 ATH_CHECK( m_bcContKey.initialize() );
47
48
49
51}
52
53StatusCode JfexSimMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
54
55 ATH_MSG_DEBUG("JfexMonitorAlgorithm::fillHistograms");
56
58 if(!jFexTowerContainer.isValid()) {
59 ATH_MSG_ERROR("No jFex Tower container found in storegate "<< m_jFexTowerKey);
60 return StatusCode::SUCCESS;
61 }
62
63 std::string inputTower = jFexTowerContainer->empty() ? "EmulatedTowers" : "DataTowers";
64
65 // mismatches can be caused by recent/imminent OTF maskings, so track timings
66 auto timeSince = Monitored::Scalar<int>("timeSince", -1);
67 auto timeUntil = Monitored::Scalar<int>("timeUntil", -1);
69 if(larBadChan.isValid()) {
70 timeSince = ctx.eventID().time_stamp() - larBadChan.getRange().start().time_stamp();
71 timeUntil = larBadChan.getRange().stop().time_stamp() - ctx.eventID().time_stamp();
72 }
73 auto EventType = Monitored::Scalar<std::string>("EventType","DataTowers");
74 if(jFexTowerContainer->empty()) {
75 EventType = "EmulatedTowers";
76 if (timeUntil>=0 && timeUntil<=5) {
77 EventType += "+JustBeforeOTF";
78 }
79
80 // check if any supercells are missing, there should be 34048
82 if (!scells.isValid() || scells->size() != 34048) {
83 EventType += "+MissingSCells";
84 }
85 }
86
87
88 //maximum number of TOBs (not xTOBs) that fit on the realtime path in hardware
89 static constexpr int jJmaxTobs = 7;
90 static constexpr int jTAUmaxTobs = 6;
91 static constexpr int jEMmaxTobs = 5;
92 bool simReady = !jFexTowerContainer->empty();
93 compareRoI("jJ",EventType,m_data_key_jJ, m_simu_key_jJ,ctx,simReady,jJmaxTobs);
94 //compareRoI("jLJ",EventType,m_data_key_jLJ, m_simu_key_jLJ,ctx,false); - commented out b.c. jFEX doesn't produce Large jets now
95 compareRoI("jTAU",EventType,m_data_key_jTau, m_simu_key_jTau,ctx,simReady,jTAUmaxTobs);
96 compareRoI("jEM",EventType,m_data_key_jEM, m_simu_key_jEM,ctx,simReady,jEMmaxTobs);
99
100
101 return StatusCode::SUCCESS;
102}
103
104template<typename T> uint16_t tobEt(const T* tob) { return tob->tobEt(); }
105template<> uint16_t tobEt(const xAOD::jFexMETRoI*) { return 0; }
106template<> uint16_t tobEt(const xAOD::jFexSumETRoI*) { return 0; }
107
108template <typename T> bool JfexSimMonitorAlgorithm::compareRoI(const std::string& label, const std::string& evenType,
109 const SG::ReadHandleKey<T>& tobsDataKey,
110 const SG::ReadHandleKey<T>& tobsSimKey,
111 const EventContext& ctx, bool simReadyFlag, size_t maxTobs) const {
112 SG::ReadHandle<T> tobsDataCont{tobsDataKey, ctx};
113 if(!tobsDataCont.isValid()) {
114 return false;
115 }
116 SG::ReadHandle<T> tobsSimCont{tobsSimKey, ctx};
117 if(!tobsSimCont.isValid()) {
118 return false;
119 }
120
121 bool mismatches = false;
122
123 auto eventType = Monitored::Scalar<std::string>("EventType",evenType);
124 auto Signature = Monitored::Scalar<std::string>("Signature",label);
125 auto signatureEventType = Monitored::Scalar<std::string>("SignatureEventType",label+":"+evenType);
126 auto tobMismatched = Monitored::Scalar<double>("tobMismatched",0);
127 auto simReady = Monitored::Scalar<bool>("SimulationReady",simReadyFlag);
128 auto IsDataTowers = Monitored::Scalar<bool>("IsDataTowers",evenType=="DataTowers");
129 auto IsEmulatedTowers = Monitored::Scalar<bool>("IsEmulatedTowers",evenType=="EmulatedTowers");
130
131 // saturation bits currently not properly simulated. But because they aren't used anywhere downstream
132 // in the trigger, we will allow mismatches in these bits.
133 // The saturation bit is the lowest bit on all TOBs except jTE where it is also the highest bit (2 bits):
134 auto mask = (label=="jTE") ? 0x7FFFFFFE : 0xFFFFFFFE;
135
136 // if have a max tobs count, need to see if we reached max count in any fpga in any jfex module
137 // if we did, then we allow mismatches of any tob that has the min et
138 std::map<std::pair<uint8_t,uint8_t>,std::multiset<uint16_t>> tobEts_byFpga;
139
140 unsigned zeroTobs1 = 0;
141 unsigned zeroTobs2 = 0;
142 for(const auto tob1 : *tobsDataCont) {
143 bool isMatched = false;
144 auto word1 = tob1->tobWord();
145 auto jfex1 = tob1->jFexNumber();
146 auto fpga1 = tob1->fpgaNumber();
147
148 for (const auto tob2 : *tobsSimCont) {
149 if(word1==0 || ((word1&mask) == (tob2->tobWord()&mask) && jfex1 == tob2->jFexNumber() && fpga1 == tob2->fpgaNumber())) { // do not flag as mismatch if the TOB word is zero, it might simply be (zero) suppressed in the other container!
150 isMatched = true;
151 break;
152 }
153 }
154 if(!isMatched) {
155 // if this signature has a max number of TOBs (in an FPGA),
156 // possible the mismatch is an ambiguity in the lowest ET TOB
157 // so treat as a match if this data TOB has same ET as the lowest ET sim TOB in the same FPGA
158 if(maxTobs>0) {
159 // first populate the fpga->tobs map with simulation tobs if it hasn't already been filled
160 if(tobEts_byFpga.empty()) {
161 for (const auto tob: *tobsSimCont) {
162 // use of multiset ensures all the TOBs are automatically ordered by ET
163 // the first tob in the multiset will be the lowest ET tob.
164 tobEts_byFpga[std::pair(tob->jFexNumber(), tob->fpgaNumber())].insert(tobEt(tob));
165 }
166 }
167 // now check if the FPGA that produced the data TOB reached its max number of TOBs and
168 // the lowest ET TOB has the same ET
169 if(auto itr = tobEts_byFpga.find(std::pair(jfex1,fpga1)); itr != tobEts_byFpga.end()
170 && itr->second.size() == maxTobs // number of TOBs in the FPGA reached the maximum
171 && (*itr->second.begin())==tobEt(tob1) // tob has same ET as lowest ET TOB (first tob in the multiset)
172 ) {
173 // possible ambiguity ... treat as a match
174 isMatched = true;
175 }
176 }
177 if(!isMatched) {
178 mismatches = true;
179 }
180 }
181 if (word1 == 0) {
182 zeroTobs1++;
183 }
184 }
185
186 for (const auto tob2: *tobsSimCont) {
187 if (tob2->tobWord() == 0) {
188 zeroTobs2++;
189 }
190 }
191
192 // check for extra non-zero sim tobs (compared to number of non-zero data tobs)
193 if(tobsSimCont.isValid() && (tobsDataCont->size() - zeroTobs1) < (tobsSimCont->size() - zeroTobs2) ) {
194 mismatches=true;
195 }
196
197 auto lbn = Monitored::Scalar<ULong64_t>("LBN",GetEventInfo(ctx)->lumiBlock());
198 if(mismatches) {
199 // fill the debugging tree with all the words for this signature
200 auto lbnString = Monitored::Scalar<std::string>("LBNString",std::to_string(GetEventInfo(ctx)->lumiBlock()));
201 auto evtNumber = Monitored::Scalar<ULong64_t>("EventNumber",GetEventInfo(ctx)->eventNumber());
202 {
203 std::scoped_lock lock(m_firstEventsMutex);
204 auto itr = m_firstEvents.find(lbn);
205 if(itr==m_firstEvents.end()) {
206 m_firstEvents[lbn] = std::to_string(lbn)+":"+std::to_string(evtNumber);
207 itr = m_firstEvents.find(lbn);
208 }
209 lbnString = itr->second;
210 }
211 std::vector<float> detas{};std::vector<float> setas{};
212 std::vector<float> dphis{};std::vector<float> sphis{};
213 std::vector<unsigned int> dword0s{};std::vector<unsigned int> sword0s{};
214 auto dtobEtas = Monitored::Collection("dataEtas", detas);
215 auto dtobPhis = Monitored::Collection("dataPhis", dphis);
216 auto dtobWord0s = Monitored::Collection("dataWord0s", dword0s);
217 auto stobEtas = Monitored::Collection("simEtas", setas);
218 auto stobPhis = Monitored::Collection("simPhis", sphis);
219 auto stobWord0s = Monitored::Collection("simWord0s", sword0s);
220 fillVectors(tobsDataKey,ctx,detas,dphis,dword0s);
221 fillVectors(tobsSimKey,ctx,setas,sphis,sword0s);
222 if(msgLvl(MSG::DEBUG)) {
223 std::cout << "LBN: " << std::string(lbnString) << " EventNumber: " << ULong64_t(evtNumber) << " signature: " << label << std::endl;
224 std::cout << " data : " << std::hex;
225 for (const auto w: dword0s) std::cout << w << " ";
226 std::cout << std::endl << " sim : ";
227 for (const auto w: sword0s) std::cout << w << " ";
228 std::cout << std::endl << std::dec;
229 }
230 tobMismatched=100;
231 auto simReadyMismatch = Monitored::Scalar<bool>("SimulationReadyMismatch",simReady);
232 fill("mismatches",simReadyMismatch,tobMismatched,lbn,lbnString,evtNumber,dtobEtas,dtobPhis,dtobWord0s,stobEtas,stobPhis,stobWord0s,Signature,eventType,IsDataTowers,IsEmulatedTowers,simReady,signatureEventType);
233 } else {
234 tobMismatched=0;
235 fill("mismatches",lbn,Signature,tobMismatched,simReady,eventType);
236 }
237
238 return !mismatches;
239
240}
241
242template <> void JfexSimMonitorAlgorithm::fillVectors(const SG::ReadHandleKey<xAOD::jFexMETRoIContainer>& key, const EventContext& ctx, std::vector<float>& etas, std::vector<float>& phis, std::vector<unsigned int>& word0s) const {
243 etas.clear();phis.clear();word0s.clear();
245 if(tobs.isValid()) {
246 etas.reserve(tobs->size());
247 phis.reserve(tobs->size());
248 word0s.reserve(tobs->size());
249 std::vector<SortableTob> sortedTobs;
250 sortedTobs.reserve(tobs->size());
251 for(const xAOD::jFexMETRoI* tob : *tobs) {
252 sortedTobs.emplace_back(SortableTob{tob->tobWord(),0.,0.});
253 }
254 std::sort(sortedTobs.begin(),sortedTobs.end(),[](const SortableTob& lhs, const SortableTob& rhs) { return lhs.word0<rhs.word0; });
255 for(const auto& tob : sortedTobs) {
256 etas.push_back(tob.eta);
257 phis.push_back(tob.phi);
258 word0s.push_back(tob.word0);
259 }
260 }
261}
262template <> void JfexSimMonitorAlgorithm::fillVectors(const SG::ReadHandleKey<xAOD::jFexSumETRoIContainer>& key, const EventContext& ctx, std::vector<float>& etas, std::vector<float>& phis, std::vector<unsigned int>& word0s) const {
263 etas.clear();phis.clear();word0s.clear();
265 if(tobs.isValid()) {
266 etas.reserve(tobs->size());
267 phis.reserve(tobs->size());
268 word0s.reserve(tobs->size());
269 std::vector<SortableTob> sortedTobs;
270 sortedTobs.reserve(tobs->size());
271 for(const auto tob : *tobs) {
272 sortedTobs.emplace_back(SortableTob{tob->tobWord(),0.,0.});
273 }
274 std::sort(sortedTobs.begin(),sortedTobs.end(),[](const SortableTob& lhs, const SortableTob& rhs) { return lhs.word0<rhs.word0; });
275 for(const auto& tob : sortedTobs) {
276 etas.push_back(tob.eta);
277 phis.push_back(tob.phi);
278 word0s.push_back(tob.word0);
279 }
280 }
281}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
uint16_t tobEt(const T *tob)
bool msgLvl(const MSG::Level lvl) const
virtual StatusCode initialize() override
initialize
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
bool empty() const noexcept
Returns true if the collection is empty.
This class represents the "type of event" where the type is given by one or more "characteristics".
Definition EventType.h:92
SG::ReadHandleKey< xAOD::jFexLRJetRoIContainer > m_data_key_jLJ
SG::ReadHandleKey< xAOD::jFexMETRoIContainer > m_simu_key_jXE
SG::ReadHandleKey< xAOD::jFexFwdElRoIContainer > m_simu_key_jEM
SG::ReadHandleKey< xAOD::jFexTowerContainer > m_jFexTowerKey
SG::ReadHandleKey< xAOD::jFexTauRoIContainer > m_data_key_jTau
SG::ReadHandleKey< xAOD::jFexSRJetRoIContainer > m_data_key_jJ
SG::ReadHandleKey< xAOD::jFexLRJetRoIContainer > m_simu_key_jLJ
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
SG::ReadHandleKey< xAOD::jFexSumETRoIContainer > m_data_key_jTE
SG::ReadCondHandleKey< LArBadChannelCont > m_bcContKey
SG::ReadHandleKey< xAOD::jFexFwdElRoIContainer > m_data_key_jEM
void fillVectors(const SG::ReadHandleKey< T > &key, const EventContext &ctx, std::vector< float > &etas, std::vector< float > &phis, std::vector< unsigned int > &word0s) const
SG::ReadHandleKey< xAOD::jFexSumETRoIContainer > m_simu_key_jTE
SG::ReadHandleKey< CaloCellContainer > m_scellKey
bool compareRoI(const std::string &label, const std::string &evenType, const SG::ReadHandleKey< T > &tobs1Key, const SG::ReadHandleKey< T > &tobs2Key, const EventContext &ctx, bool simReadyFlag=false, size_t maxTobs=0) const
JfexSimMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< xAOD::jFexMETRoIContainer > m_data_key_jXE
virtual StatusCode initialize() override
initialize
SG::ReadHandleKey< xAOD::jFexTauRoIContainer > m_simu_key_jTau
SG::ReadHandleKey< xAOD::jFexSRJetRoIContainer > m_simu_key_jJ
Declare a monitored scalar variable.
const EventIDRange & getRange()
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
std::string label(const std::string &format, int i)
Definition label.h:19
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
jFexSumETRoI_v1 jFexSumETRoI
Define the latest version of the jFexSumETJetRoI class.
jFexMETRoI_v1 jFexMETRoI
Define the latest version of the jFexMETRoI class.
Definition jFexMETRoI.h:13
void fill(H5::Group &out_file, size_t iterations)