ATLAS Offline Software
Loading...
Searching...
No Matches
MistimedStreamMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5
8#include <iostream>
9#include <vector>
10#include <TMath.h>
11
12MistimedStreamMonitorAlgorithm::MistimedStreamMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
13 : AthMonitorAlgorithm(name,pSvcLocator)
14{
15}
16
18
19 ATH_MSG_DEBUG("MistimedStreamMonitorAlgorith::initialize");
20 ATH_MSG_DEBUG("Package Name "<< m_packageName);
21 ATH_MSG_DEBUG("m_xAODTriggerTowerContainerName "<< m_xAODTriggerTowerContainerName);
22
23 ATH_MSG_INFO("m_eFexEMContainer: "<< m_eFexEMContainerKey);
24 ATH_MSG_INFO("m_eFexEMOutContainer: "<< m_eFexEMOutContainerKey);
25 ATH_MSG_INFO("m_eFexTauContainer: "<< m_eFexTauContainerKey);
26
27 // we initialise all the containers that we need
30 ATH_CHECK( m_cpmTowerLocation.initialize());
31 ATH_CHECK( m_jetElementLocation.initialize());
32 ATH_CHECK( m_trigDec.retrieve() );
33 ATH_CHECK( m_ttTool.retrieve());
34 ATH_CHECK( m_runParametersContainer.initialize() );
36 ATH_CHECK( m_ctpRdoReadKey.initialize() );
37
38 // eFex Container
39 ATH_CHECK( m_eFexEMContainerKey.initialize() );
40 ATH_CHECK( m_eFexEMOutContainerKey.initialize() );
41 ATH_CHECK( m_eFexTauContainerKey.initialize() );
42
43 // jFex Container
44 ATH_CHECK( m_jFexLRJetContainerKey.initialize() );
45 ATH_CHECK( m_jFexSRJetContainerKey.initialize() );
46 ATH_CHECK( m_jFexTauContainerKey.initialize() );
47 ATH_CHECK( m_jFexDataTowerKey.initialize() );
48 ATH_CHECK( m_EmulTowerKey.initialize() );
49
50 // gFex Container
51 ATH_CHECK( m_gFexJetTobKeyList.initialize() ) ;
52
54}
55
56StatusCode MistimedStreamMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
57
58 ATH_MSG_DEBUG("MistimedStreamMonitorAlgorith::fillHistograms");
59
60 // Retrieve L1CaloRunParametersContainer
62 ATH_CHECK(runParameters.isValid());
63
64 unsigned int readoutConfigID = runParameters->runParameters(1)->readoutConfigID();
65 ATH_MSG_DEBUG("RunParameters:: readoutConfigID " << readoutConfigID);
66
68
69 unsigned int channelID = 0;
70 unsigned int numFadcSlices = 0;
71 unsigned int l1aFadcSlice = 0;
72 unsigned int readout80ModePpm = 0;
73
74 //the readout config ID tells you, which readoutConfig is loaded. now you can retrieve the l1aFadcSlice from this DB entry
75 if ( readoutConfigJSON->readoutConfigJSON(readoutConfigID)->channelId() == readoutConfigID){
76 ATH_MSG_DEBUG("readoutConfigID " << readoutConfigID);
77 channelID = readoutConfigJSON->readoutConfigJSON(readoutConfigID)->channelId();
78 numFadcSlices = readoutConfigJSON->readoutConfigJSON(readoutConfigID)->numFadcSlices();
79 l1aFadcSlice = readoutConfigJSON->readoutConfigJSON(readoutConfigID)->l1aFadcSlice();
80 readout80ModePpm = readoutConfigJSON->readoutConfigJSON(readoutConfigID)->readout80ModePpm();
81 ATH_MSG_DEBUG("channelID :: " << channelID);
82 ATH_MSG_DEBUG("numFadcSlices :: " << numFadcSlices);
83 ATH_MSG_DEBUG("l1aFadcSlice :: " << l1aFadcSlice);
84 ATH_MSG_DEBUG("readout80ModePpm :: " << readout80ModePpm);
85 }
86
87 // Retrieve jetElementfrom SG
89 if(!jetElementTES.isValid()){
90 ATH_MSG_ERROR("No JetElement container found in TES "<< m_jetElementLocation);
91 return StatusCode::FAILURE;
92 }
93
94 // Retrieve Core CPM Towers from SG
96 if(!cpmTowerTES.isValid()){
97 ATH_MSG_ERROR("No CPMTower container found in TES "<< m_cpmTowerLocation);
98 return StatusCode::FAILURE;
99 }
100
101 // Retrieve Trigger Towers from SG
103 if(!triggerTowerTES.isValid()){
104 ATH_MSG_ERROR("No Trigger Tower container found in TES "<< m_xAODTriggerTowerContainerName);
105 return StatusCode::FAILURE;
106 }
107
108 // Retrieve EventInfo from SG and save lumi block number, global event number and run number
109 unsigned int lumiNo = GetEventInfo(ctx)->lumiBlock();
110 unsigned int currentRunNo = ctx.eventID().run_number();
111 unsigned int currentEventNo = ctx.eventID().event_number();
112
113 ATH_MSG_DEBUG("Lumi Block :: " << lumiNo);
114 ATH_MSG_DEBUG("Run Number :: " << currentRunNo);
115 ATH_MSG_DEBUG("Event Number :: " << currentEventNo);
116
117 Monitored::Scalar<int> cutFlowX = Monitored::Scalar<int>("cutFlowX", 0);
118
119 // fill first bin in cutflow
120 cutFlowX=All;
121 fill(m_packageName,cutFlowX);
122
123 //for the algorithm to run, we need the 2 adc slices before and after the l1a-slice
124 //readout compatibility checks of the algo here
125 if(readout80ModePpm){
126 if(numFadcSlices < 9){
127 ATH_MSG_DEBUG("Number of ADC slices < 9 for 80 MHz readout, algorithm cannot run, aborting...");
128 return StatusCode::SUCCESS;
129 }
130 if(l1aFadcSlice < 4){
131 ATH_MSG_DEBUG("L1a readout pointer < 4 for 80 MHz readout, algorithm cannot run, aborting...");
132 return StatusCode::SUCCESS;
133 }
134 if(numFadcSlices - l1aFadcSlice < 4){
135 ATH_MSG_DEBUG("L1a readout pointer is at "<< l1aFadcSlice << " with "<< numFadcSlices << "slices at 80 MHz readout mode, algorithm cannot run, aborting...");
136 return StatusCode::SUCCESS;
137 }
138 }
139 else {
140 if(numFadcSlices < 5){
141 ATH_MSG_DEBUG("Number of ADC slices < 5 for 40 MHz readout, algorithm cannot run, aborting...");
142 return StatusCode::SUCCESS;
143 }
144 if(l1aFadcSlice < 2){
145 ATH_MSG_DEBUG("L1a readout pointer < 2 for 40 MHz readout, algorithm cannot run, aborting...");
146 return StatusCode::SUCCESS;
147 }
148 if(numFadcSlices - l1aFadcSlice < 2){
149 ATH_MSG_DEBUG("L1a readout pointer is at "<< l1aFadcSlice << " with "<< numFadcSlices << "slices at 40 MHz readout mode, algorithm cannot run, aborting...");
150 return StatusCode::SUCCESS;
151 }
152 }
153 cutFlowX=UnsuitableReadout;
154 fill(m_packageName,cutFlowX);
155
156 //Select events that fired HLT_mistimedmonj400
157 if(! (m_trigDec->isPassed("HLT_mistimemonj400_L1All",TrigDefs::requireDecision))){
158 ATH_MSG_DEBUG("TrigDec don't pass HLT_mistimemonj400_L1All");
159 return StatusCode::SUCCESS;
160 }
161
162 cutFlowX=HLT_mistimemonj400;
163 fill(m_packageName,cutFlowX);
164
165 //Only select events which passed a proper trigger
166 //Adjustable depending on which trigger we are interested
167 bool legacyTrigger= false;
168 bool phase1Trigger= false;
169 std::string trigger = "";
170
171 if (m_usephaseI) {
172 for (const auto &item: m_efexItems) {
173 if (m_trigDec->isPassed( item )) {
174 phase1Trigger= true;
175 trigger = "eFex";
176 }
177 }
178 for (const auto &item: m_jfexItems) {
179 if (m_trigDec->isPassed( item )) {
180 phase1Trigger= true;
181 trigger = "jFex";
182 }
183 }
184 for (const auto &item: m_gfexItems) {
185 if (m_trigDec->isPassed( item )) {
186 phase1Trigger= true;
187 trigger = "gFex";
188 }
189 }
190 }
191 else if (m_uselegacy) {
192 if (m_trigDec->isPassed("L1_J100")) {
193 legacyTrigger= true;
194 }
195 }
196 else {
197 ATH_MSG_ERROR("No system selected, this should not happen, abort.");
198 return StatusCode::FAILURE;
199 }
200
201 // Reject event if no trigger fired
202 if ( (legacyTrigger==false) and (phase1Trigger==false) ) {
203 ATH_MSG_DEBUG("TrigDec doesn't pass");
204 return StatusCode::SUCCESS;
205 }
206
207 cutFlowX=L1_Trigger;
208 fill(m_packageName,cutFlowX);
209
210
211 // now classify the tower signals by looking at their FADC counts, if it exceeds 70
212 int good3Counter = 0; // category 5 good peak 3
213 int good2Counter = 0; // category 5 good peak 2
214 int eFexintimeCounter = 0; // in-time TOBs
215 int eFexoutoftimeCounter = 0; // out-of-time TOBs
216 int jFexCounter = 0; // in-time TOBs
217 int gFexCounter = 0; // in-time TOBs
218
219 double dEta = 0., dPhi = 0., dPhi1 = 0., dR = 0.;
220 double etaIn = 0., phiIn = 0., etIn = 0.;
221 double etaOut = 0., phiOut = 0., etOut = 0.;
222 bool overlap = false;
223
225 if(!jFexSRJetContainer.isValid()) {
226 ATH_MSG_WARNING("No jFex SR Jet container found in storegate "<< m_jFexSRJetContainerKey<<". Will be skipped!");
227 }
228
229 // =====================================================================
230 // ================= Container: TriggerTower ===========================
231 // =====================================================================
232
233 // Creating a new container for saving pulseClassification
234 std::unique_ptr<xAOD::TriggerTowerContainer> ttContainer = std::make_unique<xAOD::TriggerTowerContainer>();
235 std::unique_ptr<xAOD::TriggerTowerAuxContainer> ttContainerAux = std::make_unique<xAOD::TriggerTowerAuxContainer>();
236 ttContainer->setStore(ttContainerAux.get());
237
238 static const SG::Accessor<float> pulseClassificationAcc("pulseClassification");
239
240 // Creating a new container for TT with pulseClassification
241 for (const xAOD::TriggerTower* tt : *triggerTowerTES) {
242
243 float ttPulseCategory = 0;
244 const std::vector<uint16_t>& ttADC = (tt)->adc();
245 std::vector<uint16_t> readoutCorrectedADC; //this is the standard readout ADC vector: 5 40MHz samples with l1A in the middle
246 if(!readout80ModePpm){//40 MHz
247 //just acess the acd vector, as the sanity checks where done above
248 readoutCorrectedADC.push_back(ttADC.at(l1aFadcSlice-2));
249 readoutCorrectedADC.push_back(ttADC.at(l1aFadcSlice-1));
250 readoutCorrectedADC.push_back(ttADC.at(l1aFadcSlice));
251 readoutCorrectedADC.push_back(ttADC.at(l1aFadcSlice+1));
252 readoutCorrectedADC.push_back(ttADC.at(l1aFadcSlice+2));
253 }
254 else{//80 MHz
255 readoutCorrectedADC.push_back(ttADC.at(l1aFadcSlice-4));
256 readoutCorrectedADC.push_back(ttADC.at(l1aFadcSlice-2));
257 readoutCorrectedADC.push_back(ttADC.at(l1aFadcSlice));
258 readoutCorrectedADC.push_back(ttADC.at(l1aFadcSlice+2));
259 readoutCorrectedADC.push_back(ttADC.at(l1aFadcSlice+4));
260 }
261
262 // retrieve max ADC value and position, this seems to be buggy in the DAOD
263 auto maxValIterator = std::max_element(readoutCorrectedADC.begin(), readoutCorrectedADC.end());
264 int maxADCval = *maxValIterator;
265 int adcPeakPositon = std::distance(std::begin(readoutCorrectedADC), maxValIterator);
266
267 if(maxADCval < 70){
268 ttPulseCategory = 0.1;
269 }
270 else if(maxADCval == 1023) {
271 ttPulseCategory = 1;
272 }
273 else{
274 bool goodQual = pulseQuality(readoutCorrectedADC, adcPeakPositon);
275 //look at any of the five FADC values
276 if(adcPeakPositon == 2){ // can be class 3 or 4 now
277 if(goodQual){
278 //nicely peaking TT in BCID0
279 good2Counter++;
280 ttPulseCategory = 3;
281 }
282 else{
283 //badly peaking TT in BCID0
284 ttPulseCategory = 4;
285 }
286 }
287 else if(adcPeakPositon == 3){ // can be class 5 or 6 now
288 if(goodQual){
289 //nicely peaking TT in BCID+1
290 good3Counter++;
291 ttPulseCategory = 5;
292 }
293 else{
294 //badly peaking TT in BCID+1
295 ttPulseCategory = 6;
296 }
297 }
298 else{
299 //TT peaking in BCID-1,-2 or +2
300 ttPulseCategory = 2;
301 }
302
303 if (trigger == "jFex") {
304 const xAOD::jFexSRJetRoIContainer* jFexSRJetRoI;
305 CHECK( evtStore()->retrieve( jFexSRJetRoI, "L1_jFexSRJetRoI" ) );
306 for(auto tob : *jFexSRJetRoI) {
307 etaIn = tob->eta();
308 phiIn = tob->phi();
309 etIn = tob->tobEt()/5;
310
311 if( (adcPeakPositon == 3) and (goodQual) ) {
312 etaOut = tt->eta();
313 phiOut = tt->phi()-M_PI;
314 dEta = std::abs(etaIn-etaOut);
315 dPhi = std::abs(phiIn-phiOut);
316 if ((phiIn < 0) and (phiOut > 0)){
317 dPhi1 = std::abs((phiIn+2*M_PI)-phiOut);
318 if (dPhi1 < dPhi) {
319 dPhi = dPhi1;
320 }
321 }
322 else if ((phiIn > 0) and (phiOut < 0)){
323 dPhi1 = std::abs(phiIn-(phiOut+2*M_PI));
324 if (dPhi1 < dPhi) {
325 dPhi = dPhi1;
326 }
327 }
328 dR = TMath::Sqrt(dEta*dEta+dPhi*dPhi);
329 if ((dR < .2) and (etIn > 160.)) {
330 overlap = true;
331 }
332 } // if statement - good tt
333 } // for loop - jFex TOBs
334 } // if statement - jFex
335
336 if (trigger == "gFex") {
337
338 for (const auto& key : m_gFexJetTobKeyList){
339 SG::ReadHandle<xAOD::gFexJetRoIContainer> jetContainer (key, ctx);
340 // Check that this container is present
341 if ( !jetContainer.isValid() ) {
342 ATH_MSG_WARNING("No gFex jet container found in storegate: "<< key.key());
343 }
344 else {
345 const xAOD::gFexJetRoIContainer* gFexJetRoI;
346 CHECK( evtStore()->retrieve( gFexJetRoI, key.key() ) );
347 for(auto tob : *gFexJetRoI) {
348 etaIn = tob->eta();
349 phiIn = tob->phi();
350 etIn = tob->gFexTobEt()/10;
351
352 if( (adcPeakPositon == 3) and (goodQual) ) {
353 etaOut = tt->eta();
354 phiOut = tt->phi()-M_PI;
355 dEta = std::abs(etaIn-etaOut);
356 dPhi = std::abs(phiIn-phiOut);
357 if ((phiIn < 0) and (phiOut > 0)){
358 dPhi1 = std::abs((phiIn+2*M_PI)-phiOut);
359 if (dPhi1 < dPhi) {
360 dPhi = dPhi1;
361 }
362 }
363 else if ((phiIn > 0) and (phiOut < 0)){
364 dPhi1 = std::abs(phiIn-(phiOut+2*M_PI));
365 if (dPhi1 < dPhi) {
366 dPhi = dPhi1;
367 }
368 }
369 dR = TMath::Sqrt(dEta*dEta+dPhi*dPhi);
370 if ((dR < .2) and (etIn > 100.)) {
371 overlap = true;
372 }
373 } // if statement - good tt
374 } // for loop - gFex TOBs
375 } // else stamement - valid container
376 } // for loop - gFex container
377 } // if statement - gFex
378
379 }
380
381 // decorate the TT in order to have to recompute the pulse categorisation
382 xAOD::TriggerTower* newTT = new xAOD::TriggerTower; //create a new TT object
383 ttContainer->push_back(newTT); // add the newTT to new output TT container (at the end of it)
384 *newTT = *(tt);// copy over all information from TT to newTT
385 pulseClassificationAcc(*newTT) = ttPulseCategory; //decorate
386 }
387
388 // count all eFex in-time and out-of-time TOBs with at least 5GeV
389 for(auto key : {"L1_eEMxRoI","L1_eEMxRoIOutOfTime"}) {
390
391 const xAOD::eFexEMRoIContainer* emTobs;
392 CHECK( evtStore()->retrieve( emTobs, key ) );
393
394 for(auto tob : *emTobs) {
395 if (tob->et() > 5000) { //eFex TOB energy in MeV
396 if (tob->bcn4() == ((ctx.eventID().bunch_crossing_id()) & 0xf )) {
397 eFexintimeCounter++;
398 }
399 else if (tob->bcn4() == (((ctx.eventID().bunch_crossing_id())+1) & 0xf )) {
400 eFexoutoftimeCounter++;
401 }
402 }
403 }
404
405 }
406
407 // count all gFex in-time TOBs with at least 5GeV
408 const xAOD::gFexJetRoIContainer* gFexLRJetRoI;
409 CHECK( evtStore()->retrieve( gFexLRJetRoI, "L1_gFexLRJetRoI" ) );
410 for(auto tob : *gFexLRJetRoI) {
411 if (tob->et() > 50) { //gFex TOB energy in 0.1GeV
412 gFexCounter++;
413 }
414 }
415
416 // count all jFex in-time TOBs with at least 5GeV
417 const xAOD::jFexSRJetRoIContainer* jFexJetRoI;
418 CHECK( evtStore()->retrieve( jFexJetRoI, "L1_jFexSRJetRoI" ) );
419 for(auto tob : *jFexJetRoI) {
420 if (tob->et() > 25) { //jFex TOB energy in 0.2GeV
421 jFexCounter++;
422 }
423 }
424
425 if ((good3Counter < 2) and (m_isIons == false)) {
426 //reject events with less than 2 pulses nicely peaking in slice 3
427 return StatusCode::SUCCESS;
428 }
429 cutFlowX=lateTT;
430 fill(m_packageName,cutFlowX);
431
432 if ((trigger == "eFex") and (eFexoutoftimeCounter < 2)) {
433 //for eFEX triggers, require at least two late TOBs
434 return StatusCode::SUCCESS;
435 }
436 cutFlowX=lateTOB;
437 fill(m_packageName,cutFlowX);
438
439 if( (good2Counter > 3) or
440 ((trigger == "eFex") and (eFexintimeCounter > 3)) or
441 ((trigger == "jFex") and (jFexCounter > 3)) or
442 ((trigger == "gFex") and (gFexCounter > 3)) ){
443 //reject events with more than 3 pulses nicely peaking/ 3 TOBs in slice 2 to avoid event being triggered by pileup
444 return StatusCode::SUCCESS;
445 }
446 cutFlowX= InTime;
447 fill(m_packageName,cutFlowX);
448
449 if (trigger == "eFex") {
450 const xAOD::eFexEMRoIContainer* emTobs;
451 CHECK( evtStore()->retrieve( emTobs, "L1_eEMxRoI" ) );
452 const xAOD::eFexEMRoIContainer* emTobsOut;
453 CHECK( evtStore()->retrieve( emTobsOut, "L1_eEMxRoIOutOfTime" ) );
454
455 for(auto tob : *emTobs) {
456 etaIn = tob->eta();
457 phiIn = tob->phi();
458 etIn = tob->et()/1000; //eT in GeV
459
460 for(auto tobOut : *emTobsOut) {
461 etaOut = tobOut->eta();
462 phiOut = tobOut->phi();
463 etOut = tobOut->et()/1000; //eT in GeV
464
465 dEta = std::abs(etaIn-etaOut);
466 dPhi = std::abs(phiIn-phiOut);
467 if ((phiIn < 0) and (phiOut > 0)){
468 dPhi1 = std::abs((phiIn+2*M_PI)-phiOut);
469 if (dPhi1 < dPhi) {
470 dPhi = dPhi1;
471 }
472 }
473 else if ((phiIn > 0) and (phiOut < 0)){
474 dPhi1 = std::abs(phiIn-(phiOut+2*M_PI));
475 if (dPhi1 < dPhi) {
476 dPhi = dPhi1;
477 }
478 }
479 dR = TMath::Sqrt(dEta*dEta+dPhi*dPhi);
480 if ((dR < .2) and (etIn > 26.) and (etOut > 26.)){
481 overlap = true;
482 }
483 }
484 }
485 }
486
487 if ((legacyTrigger) and !(phase1Trigger)){
488 overlap = true;
489 }
490
491 if ((overlap==false) and (m_isIons == false)) {
492 //reject events where BCID and BCID+1 are spatially separated
493 return StatusCode::SUCCESS;
494 }
495 cutFlowX= EtaPhiOverlap;
496 fill(m_packageName,cutFlowX);
497
498 // scope for mutable error event per lumi block tt counter
499 // it allows only one event per lumiblock
500 std::lock_guard<std::mutex> lock(m_mutex);
501 m_event_counter[lumiNo]+=1;
502 const int eventCounter = m_eventCounter++;
503
504 if( (m_event_counter[lumiNo] <m_maxEvents) && (eventCounter < m_maxEvents) ){
505 ATH_MSG_DEBUG( "EventID :: " << m_event_counter[lumiNo]);
506
507 // Saving the lumiblock and event number of the events with mistimed
508 auto eventMonitor_legacy= Monitored::Scalar<std::string>("eventMonitor_legacy", "Event"+std::to_string(eventCounter)+"="+std::to_string(currentEventNo));
509 auto eventMonitor_phaseI= Monitored::Scalar<std::string>("eventMonitor_phaseI", "Event"+std::to_string(eventCounter)+"_"+trigger+"="+std::to_string(currentEventNo));
510 auto lbMonitor= Monitored::Scalar<std::string>("lbMonitor", std::to_string(lumiNo));
511 std::string groupName = "Event_";
512 if (legacyTrigger) {
513 fill(groupName, eventMonitor_legacy, lbMonitor );
514 }
515 if (phase1Trigger) {
516 fill(groupName, eventMonitor_phaseI, lbMonitor );
517 }
518
519 // Create a vector of trigger towers with quantities to be monitored
520 std::vector<MonitorTT> vecMonTTDecor; // All towers
521
522 // Loop over trigger tower container
523 //Create the trigger tower objects and calculate scaled phi
524 for (const xAOD::TriggerTower* tt : *ttContainer) {
525 ATH_CHECK( makeTowerPPM(tt, vecMonTTDecor) );
526 ATH_MSG_DEBUG( "tt->pulseClassification :: " << pulseClassificationAcc(*tt));
527 }
528
529 groupName = "EventofInterest_" + std::to_string(eventCounter) + "_";
530 auto bcidWord = Monitored::Scalar<uint8_t>("bcidWord", 0);
531 auto pulseCat = Monitored::Scalar<float>("pulseCat", 0);
532
533 for (auto& myTower : vecMonTTDecor) {
534 ATH_MSG_DEBUG(" looping over TTs");
535 const int layer = (myTower.tower)->layer();
536 pulseCat = pulseClassificationAcc(*myTower.tower);
537 bcidWord = (myTower.tower)->bcidVec()[0]; // look at the status bit in the central time slice
538 ATH_MSG_DEBUG("groupName :: " << groupName);
539
540 // Check if TT is in EM or HAD layer:
541 if (layer == 0) { //========== ELECTROMAGNETIC LAYER =========================
542 ATH_CHECK( fillPPMEtaPhi(myTower, groupName+"TT_EM", "pulseCat", pulseCat) );
543 if(pulseCat > 0.5 && bcidWord > 0) {
544 ATH_CHECK( fillPPMEtaPhi(myTower, groupName+"TT_EM", "bcidWord", bcidWord) );
545 }
546 }
547 else if(layer == 1 ) { //========== HADRONIC LAYER ===============================
548 ATH_CHECK( fillPPMEtaPhi(myTower, groupName+"TT_HAD", "pulseCat", pulseCat) );
549 if(pulseCat > 0.5 && bcidWord > 0 ) ATH_CHECK( fillPPMEtaPhi(myTower, groupName+"TT_HAD", "bcidWord", bcidWord) );
550 }
551 }
552
553 //Loop over CPM tower container
554 //Create the CPM objects and calculate scaled phi
555 std::vector<MonitorCPM> vecMonCPM; // All towers
556 for (const xAOD::CPMTower* cpm : *cpmTowerTES) {
557 ATH_CHECK( makeTowerCPM(cpm, vecMonCPM) );
558 }
559
560 // Coordinates for CPM tower and JetElement containers
561 auto etalut = Monitored::Scalar<double>("etalut", 0);
562 auto philut = Monitored::Scalar<double>("philut", 0);
563
564 // lut variables
565 auto emLUT0 = Monitored::Scalar<int>("emLUT0", 0);
566 auto emLUT1 = Monitored::Scalar<int>("emLUT1", 0);
567 auto emLUT2 = Monitored::Scalar<int>("emLUT2", 0);
568 auto hadLUT0 = Monitored::Scalar<int>("hadLUT0", 0);
569 auto hadLUT1 = Monitored::Scalar<int>("hadLUT1", 0);
570 auto hadLUT2 = Monitored::Scalar<int>("hadLUT2", 0);
571
572 //loop over the cpm tower container to fill the lut histos
573 for (auto& myTower : vecMonCPM) {
574
575 std::vector<uint8_t> cpmEMenergy = (myTower.tower)->emEnergyVec();
576 std::vector<uint8_t> cpmHADenergy = (myTower.tower)->hadEnergyVec();
577 // eta scaled
578 etalut = myTower.etaScaled;
579
580 for (auto phi: myTower.phiScaled) {
581 // phi scaled
582 philut = phi;
583
584 if(cpmEMenergy.size() > 2){ // expect 3 slices to be read out
585 ATH_MSG_DEBUG("CPM :: emLUT0 :: " << static_cast<unsigned>(cpmEMenergy.at(0)) << ":: emLUT1 :: " << static_cast<unsigned>(cpmEMenergy.at(1)) << ":: emLUT2 :: " << static_cast<unsigned>(cpmEMenergy.at(2)));
586
587 emLUT0 = static_cast<int>(cpmEMenergy.at(0));
588 if(cpmEMenergy.at(0) > 0) fill(groupName+"lut_EM0",etalut,philut, emLUT0);
589
590 emLUT1 = static_cast<int>(cpmEMenergy.at(1));
591 if(cpmEMenergy.at(1) > 0) fill(groupName+"lut_EM1",etalut,philut, emLUT1);
592
593 emLUT2 = static_cast<int>(cpmEMenergy.at(2));
594 if(cpmEMenergy.at(2) > 0) fill(groupName+"lut_EM2",etalut,philut, emLUT2);
595 }
596 if(cpmHADenergy.size() > 2){
597 ATH_MSG_DEBUG("CPM :: hadLUT0 :: " << static_cast<unsigned>(cpmHADenergy.at(0)) << ":: hadLUT1 :: " << static_cast<unsigned>(cpmHADenergy.at(1)) << ":: hadLUT2 :: " << static_cast<unsigned>(cpmHADenergy.at(2)));
598
599 hadLUT0 = static_cast<int>(cpmHADenergy.at(0));
600 if(cpmHADenergy.at(0) > 0) fill(groupName+"lut_HAD0",etalut,philut, hadLUT0);
601 hadLUT1 = static_cast<int>(cpmHADenergy.at(1));
602 if(cpmHADenergy.at(1) > 0) fill(groupName+"lut_HAD1",etalut,philut, hadLUT1);
603 hadLUT2 = static_cast<int>(cpmHADenergy.at(2));
604 if(cpmHADenergy.at(2) > 0)fill(groupName+"lut_HAD2",etalut,philut, hadLUT2);
605 }
606 }
607 }
608
609 std::vector<MonitorJE> vecMonJE; // All elements
610
611 //Create the JetElement objects and calculate scaled phi
612 for (const xAOD::JetElement* je : *jetElementTES) {
613 ATH_CHECK( makeTowerJE(je, vecMonJE) );
614 }
615
616 //loop over the jet element container to fill the lut histos
617 for (auto& jet : vecMonJE) {
618
619 std::vector<uint16_t> jepEMenergy = (jet.element)->emJetElementETVec();
620 std::vector<uint16_t> jepHADenergy = (jet.element)->hadJetElementETVec();
621
622 for (auto eta: jet.etaScaled) {
623 etalut = eta;
624 if ( std::abs(eta) > 2.5){
625 for (auto phi: jet.phiScaled) {
626 philut = phi;
627 if(jepEMenergy.size() > 2){
628 ATH_MSG_DEBUG("JetElement :: emLUT0 :: " << static_cast<unsigned>(jepEMenergy.at(0)) << ":: emLUT1 :: " << static_cast<unsigned>(jepEMenergy.at(1)) << ":: emLUT2 :: " << static_cast<unsigned>(jepEMenergy.at(2)));
629
630 emLUT0 = static_cast<int>(jepEMenergy.at(0));
631 if(jepEMenergy.at(0) > 0) fill(groupName+"lut_EM0",etalut,philut, emLUT0);
632
633 emLUT1 = static_cast<int>(jepEMenergy.at(1));
634 if(jepEMenergy.at(1) > 0) fill(groupName+"lut_EM1",etalut,philut, emLUT1);
635
636 emLUT2 = static_cast<int>(jepEMenergy.at(2));
637 if(jepEMenergy.at(2) > 0) fill(groupName+"lut_EM2",etalut,philut, emLUT2);
638 }
639 if(jepHADenergy.size()> 2){
640 ATH_MSG_DEBUG("JetElement :: hadLUT0 :: " << static_cast<unsigned>(jepHADenergy.at(0)) << ":: hadLUT1 :: " << static_cast<unsigned>(jepHADenergy.at(1)) << ":: hadLUT2 :: " << static_cast<unsigned>(jepHADenergy.at(2)));
641
642 hadLUT0 = static_cast<int>(jepHADenergy.at(0));
643 if(jepHADenergy.at(0) > 0) fill(groupName+"lut_HAD0",etalut,philut, hadLUT0);
644
645 hadLUT1 = static_cast<int>(jepHADenergy.at(1));
646 if(jepHADenergy.at(1) > 0) fill(groupName+"lut_HAD1",etalut,philut, hadLUT1);
647
648 hadLUT2 = static_cast<int>(jepHADenergy.at(2));
649 if(jepHADenergy.at(2) > 0) fill(groupName+"lut_HAD2",etalut,philut, hadLUT2);
650 }
651 }
652 }
653 }
654 }
655
657 if ( !eFexContainer.isValid() ) {
658 ATH_MSG_WARNING("No eFex EM container found in storegate "<< eFexContainer.key());
659 }
660
661 // monitored variables for histograms
662 auto TOBeT = Monitored::Scalar<float>("TOBTransverseEnergy",0.0);
663 auto TOBeta = Monitored::Scalar<float>("TOBEta",0.0);
664 auto TOBphi = Monitored::Scalar<float>("TOBPhi",0.0);
665 auto TOBeT_max = Monitored::Scalar<float>("TOBTransverseEnergy_max",0.0);
666 auto TOBeta_max = Monitored::Scalar<float>("TOBEta_max",0.0);
667 auto TOBphi_max = Monitored::Scalar<float>("TOBPhi_max",0.0);
668 auto TOBeT_max_in = Monitored::Scalar<float>("TOBTransverseEnergy_max",0.0);
669 auto TOBeta_max_in = Monitored::Scalar<float>("TOBEta_max",0.0);
670 auto TOBphi_max_in = Monitored::Scalar<float>("TOBPhi_max",0.0);
671
672 TOBeT_max = 0;
673 TOBeT_max_in = 0;
674
675 for(auto key : {"L1_eEMxRoI","L1_eEMxRoIOutOfTime"}) {
676
677 const xAOD::eFexEMRoIContainer* emTobs;
678 CHECK( evtStore()->retrieve( emTobs, key ) );
679
680 for(auto tob : *emTobs) {
681 TOBeT = tob->et()/1000; //eT in GeV
682 TOBeta = tob->eta();
683
684 // adjust the phi to 0 to 2 pi
685 if (tob->phi() < 0) {
686 TOBphi = tob->phi()+2*M_PI;
687 }
688 else {
689 TOBphi = tob->phi();
690 }
691
692 // fill the eFex histograms in the right time slice
693 if (tob->bcn4() == (((ctx.eventID().bunch_crossing_id())-1) & 0xf )) {
694 if (TOBeT > 0.0){
695 fill(groupName+"Efex0", TOBeta, TOBphi, TOBeT);
696 }
697 }
698 else if (tob->bcn4() == ((ctx.eventID().bunch_crossing_id()) & 0xf )) {
699 if (TOBeT > 0.0){
700 if (TOBeT_max_in < TOBeT) {
701 TOBeT_max_in = tob->et()/1000;
702 TOBeta_max_in = tob->eta();
703 if (tob->phi() < 0) {
704 TOBphi_max_in = tob->phi()+2*M_PI;
705 }
706 else {
707 TOBphi_max_in = tob->phi();
708 }
709 }
710 fill(groupName+"Efex1", TOBeta, TOBphi, TOBeT);
711 }
712 }
713 else if (tob->bcn4() == (((ctx.eventID().bunch_crossing_id())+1) & 0xf )) {
714 if (TOBeT > 0.0){
715 if (TOBeT_max < TOBeT) {
716 TOBeT_max = tob->et()/1000;
717 TOBeta_max = tob->eta();
718 if (tob->phi() < 0) {
719 TOBphi_max = tob->phi()+2*M_PI;
720 }
721 else {
722 TOBphi_max = tob->phi();
723 }
724 }
725 fill(groupName+"Efex2", TOBeta, TOBphi, TOBeT);
726 }
727 }
728 }
729 }
730 if (trigger == "eFex") {
731 fill("Efex_maxTOB_in", TOBeT_max_in);
732 fill("Efex_maxTOB_out", TOBeT_max);
733 fill("Efex_maxTOB_out", TOBeta_max, TOBphi_max);
734 fill("Efex_maxTOB_in", TOBeta_max_in, TOBphi_max_in);
735 }
736
737 // variables for histograms
738 auto jFexEt = Monitored::Scalar<int> ("jFexEt",0);
739 auto jFexeta = Monitored::Scalar<float>("jFexEta",0.0);
740 auto jFexphi = Monitored::Scalar<float>("jFexPhi",0.0);
741
742 // Access jFex tower container
744 if(!jFexTowerContainer.isValid()) {
745 ATH_MSG_WARNING("No jFex Tower container valid in storegate with key: "<< m_jFexDataTowerKey<<". Will be skipped!");
746 }
747
748 //SG::ReadHandle<xAOD::jFexTowerContainer> jFexEmulatedTowerContainer{m_jFexEmulatedTowerKey, ctx};
749 SG::ReadHandle<xAOD::jFexTowerContainer> jEmulatedTowerContainer;
750 jEmulatedTowerContainer = SG::ReadHandle<xAOD::jFexTowerContainer>(m_EmulTowerKey,ctx);
751 if(!jEmulatedTowerContainer.isValid()) {
752 ATH_MSG_WARNING("No jFex Tower container valid in storegate with key: "<< jEmulatedTowerContainer.key()<<". Will be skipped!");
753 }
754 else {
755 for(const xAOD::jFexTower* emulTower : *jEmulatedTowerContainer) {
756 jFexEt=emulTower->et_count().at(0);
757 //Adding 1e-5 for plotting style
758 jFexeta=emulTower->eta()+1e-5;
759 if (emulTower->phi() < 0) {
760 jFexphi=emulTower->phi()+2*M_PI;
761 }
762 else {
763 jFexphi=emulTower->phi();
764 }
765 if (jFexEt > 175) {
766 fill(groupName+"JfexEmulated",jFexeta,jFexphi, jFexEt);
767 }
768 }
769 }
770
771 TOBeT_max = 0;
772 for(const xAOD::jFexSRJetRoI* jFexSRJetRoI : *jFexSRJetContainer) {
773 if(jFexSRJetRoI->tobWord()==0) continue; //remove empty TOBs
774 jFexEt=jFexSRJetRoI->tobEt()/5;
775 jFexeta=jFexSRJetRoI->eta();
776 if (jFexSRJetRoI->phi() < 0) {
777 jFexphi=jFexSRJetRoI->phi()+2*M_PI;
778 }
779 else {
780 jFexphi=jFexSRJetRoI->phi();
781 }
782 if (TOBeT_max < jFexEt) {
783 TOBeT_max = jFexSRJetRoI->tobEt()/5;
784 TOBeta_max = jFexSRJetRoI->eta();
785 if (jFexSRJetRoI->phi() < 0) {
786 TOBphi_max =jFexSRJetRoI->phi()+2*M_PI;
787 }
788 else {
789 TOBphi_max =jFexSRJetRoI->phi();
790 }
791 }
792 fill(groupName+"JfexSRJet", jFexeta, jFexphi, jFexEt);
793 }
794 if (trigger == "jFex") {
795 fill("Jfex_maxTOB", TOBeT_max);
796 fill("Jfex_maxTOB", TOBeta_max, TOBphi_max);
797 }
798
800 if(!jFexTauContainer.isValid()) {
801 ATH_MSG_WARNING("No jFex Tau container found in storegate "<< m_jFexTauContainerKey<<". Will be skipped!");
802 }
803 else {
804 for(const xAOD::jFexTauRoI* jFexTauRoI : *jFexTauContainer) {
805 if(jFexTauRoI->tobWord()==0) continue; //remove empty TOBs
806 jFexEt =jFexTauRoI->tobEt()/5;
807 jFexeta=jFexTauRoI->eta();
808 if (jFexTauRoI->phi() < 0) {
809 jFexphi=jFexTauRoI->phi()+2*M_PI;
810 }
811 else {
812 jFexphi=jFexTauRoI->phi();
813 }
814 fill(groupName+"JfexTau", jFexeta, jFexphi, jFexEt);
815 }
816 }
817
818 auto gFexEt = Monitored::Scalar<int> ("gFexEt",0);
819 auto gFexEta = Monitored::Scalar<float>("gFexEta",0.0);
820 auto gFexPhi = Monitored::Scalar<float>("gFexPhi",0.0);
821 int key_index = 0;
822
823 TOBeT_max = 0;
824 // Small-R and large-R jets container loop
825 for (const auto& key : m_gFexJetTobKeyList){
826 SG::ReadHandle<xAOD::gFexJetRoIContainer> jetContainer (key, ctx);
827 // Check that this container is present
828 if ( !jetContainer.isValid() ) {
829 ATH_MSG_WARNING("No gFex jet container found in storegate: "<< key.key());
830 }
831 else {
832 for(const xAOD::gFexJetRoI* gFexJetRoIContainer : *jetContainer) {
833 gFexEt =gFexJetRoIContainer->gFexTobEt()/10;
834 gFexEta=gFexJetRoIContainer->eta();
835 if (gFexJetRoIContainer->phi() < 0) {
836 gFexPhi=gFexJetRoIContainer->phi()+2*M_PI;
837 }
838 else {
839 gFexPhi=gFexJetRoIContainer->phi();
840 }
841 if (TOBeT_max < gFexEt) {
842 TOBeT_max = gFexJetRoIContainer->gFexTobEt()/10;
843 TOBeta_max = gFexJetRoIContainer->eta();
844 if (gFexJetRoIContainer->phi() < 0) {
845 TOBphi_max=gFexJetRoIContainer->phi()+2*M_PI;
846 }
847 else {
848 TOBphi_max=gFexJetRoIContainer->phi();
849 }
850 }
851 if (key_index == 0) {
852 fill(groupName+"GfexSRJet",gFexEta, gFexPhi, gFexEt);
853 }
854 else if (key_index == 1) {
855 fill(groupName+"GfexLRJet",gFexEta, gFexPhi, gFexEt);
856 }
857 }
858 }
859 key_index++;
860 }
861 if (trigger == "gFex") {
862 fill("Gfex_maxTOB", TOBeT_max);
863 fill("Gfex_maxTOB", TOBeta_max, TOBphi_max);
864 }
865
866 }
867 else {
868 auto eventMonitor_all_legacy= Monitored::Scalar<std::string>("eventMonitor_all_legacy", std::to_string(currentEventNo));
869 auto eventMonitor_all_phaseI= Monitored::Scalar<std::string>("eventMonitor_all_phaseI", trigger+"="+std::to_string(currentEventNo));
870 auto lbMonitor_all= Monitored::Scalar<std::string>("lbMonitor_all", std::to_string(lumiNo));
871 if (legacyTrigger) {
872 fill("Event_all_", eventMonitor_all_legacy, lbMonitor_all );
873 }
874 if (phase1Trigger) {
875 fill("Event_all_", eventMonitor_all_phaseI, lbMonitor_all );
876 }
877
879 if ( !eFexContainer.isValid() ) {
880 ATH_MSG_WARNING("No eFex EM container found in storegate "<< eFexContainer.key());
881 }
882
883 // monitored variables for histograms
884 auto TOBeT = Monitored::Scalar<float>("TOBTransverseEnergy",0.0);
885 auto TOBeta = Monitored::Scalar<float>("TOBEta",0.0);
886 auto TOBphi = Monitored::Scalar<float>("TOBPhi",0.0);
887 auto TOBeT_max = Monitored::Scalar<float>("TOBTransverseEnergy_max",0.0);
888 auto TOBeta_max = Monitored::Scalar<float>("TOBEta_max",0.0);
889 auto TOBphi_max = Monitored::Scalar<float>("TOBPhi_max",0.0);
890 auto TOBeT_max_in = Monitored::Scalar<float>("TOBTransverseEnergy_max",0.0);
891 auto TOBeta_max_in = Monitored::Scalar<float>("TOBEta_max",0.0);
892 auto TOBphi_max_in = Monitored::Scalar<float>("TOBPhi_max",0.0);
893
894 TOBeT_max = 0;
895 TOBeT_max_in = 0;
896
897 for(auto key : {"L1_eEMxRoI","L1_eEMxRoIOutOfTime"}) {
898
899 const xAOD::eFexEMRoIContainer* emTobs;
900 CHECK( evtStore()->retrieve( emTobs, key ) );
901
902 for(auto tob : *emTobs) {
903 TOBeT = tob->et()/1000; //eT in GeV
904 TOBeta = tob->eta();
905
906 // adjust the phi to 0 to 2 pi
907 if (tob->phi() < 0) {
908 TOBphi = tob->phi()+2*M_PI;
909 }
910 else {
911 TOBphi = tob->phi();
912 }
913
914 if (tob->bcn4() == ((ctx.eventID().bunch_crossing_id()) & 0xf )) {
915 if (TOBeT > 0.0){
916 if (TOBeT_max_in < TOBeT) {
917 TOBeT_max_in = tob->et()/1000;
918 TOBeta_max_in = tob->eta();
919 if (tob->phi() < 0) {
920 TOBphi_max_in = tob->phi()+2*M_PI;
921 }
922 else {
923 TOBphi_max_in = tob->phi();
924 }
925 }
926 }
927 }
928 else if (tob->bcn4() == (((ctx.eventID().bunch_crossing_id())+1) & 0xf )) {
929 if (TOBeT > 0.0){
930 if (TOBeT_max < TOBeT) {
931 TOBeT_max = tob->et()/1000;
932 TOBeta_max = tob->eta();
933 if (tob->phi() < 0) {
934 TOBphi_max = tob->phi()+2*M_PI;
935 }
936 else {
937 TOBphi_max = tob->phi();
938 }
939 }
940 }
941 }
942 }
943 }
944 if (trigger == "eFex") {
945 fill("Efex_maxTOB_in", TOBeT_max_in);
946 fill("Efex_maxTOB_out", TOBeT_max);
947 fill("Efex_maxTOB_out", TOBeta_max, TOBphi_max);
948 fill("Efex_maxTOB_in", TOBeta_max_in, TOBphi_max_in);
949 }
950
951 // variables for histograms
952 auto jFexEt = Monitored::Scalar<int> ("jFexEt",0);
953 auto jFexeta = Monitored::Scalar<float>("jFexEta",0.0);
954 auto jFexphi = Monitored::Scalar<float>("jFexPhi",0.0);
955
956 // Access jFex tower container
958 if(!jFexTowerContainer.isValid()) {
959 ATH_MSG_WARNING("No jFex Tower container valid in storegate with key: "<< m_jFexDataTowerKey<<". Will be skipped!");
960 }
961
962 TOBeT_max = 0;
963 for(const xAOD::jFexSRJetRoI* jFexSRJetRoI : *jFexSRJetContainer) {
964 if(jFexSRJetRoI->tobWord()==0) continue; //remove empty TOBs
965 jFexEt=jFexSRJetRoI->tobEt()/5;
966 jFexeta=jFexSRJetRoI->eta();
967 if (jFexSRJetRoI->phi() < 0) {
968 jFexphi=jFexSRJetRoI->phi()+2*M_PI;
969 }
970 else {
971 jFexphi=jFexSRJetRoI->phi();
972 }
973 if (TOBeT_max < jFexEt) {
974 TOBeT_max = jFexSRJetRoI->tobEt()/5;
975 TOBeta_max = jFexSRJetRoI->eta();
976 if (jFexSRJetRoI->phi() < 0) {
977 TOBphi_max =jFexSRJetRoI->phi()+2*M_PI;
978 }
979 else {
980 TOBphi_max =jFexSRJetRoI->phi();
981 }
982 }
983 }
984 if (trigger == "jFex") {
985 fill("Jfex_maxTOB", TOBeT_max);
986 fill("Jfex_maxTOB", TOBeta_max, TOBphi_max);
987 }
988
989 auto gFexEt = Monitored::Scalar<int> ("gFexEt",0);
990 auto gFexEta = Monitored::Scalar<float>("gFexEta",0.0);
991 auto gFexPhi = Monitored::Scalar<float>("gFexPhi",0.0);
992
993 TOBeT_max = 0;
994 // Small-R and large-R jets container loop
995 for (const auto& key : m_gFexJetTobKeyList){
996 SG::ReadHandle<xAOD::gFexJetRoIContainer> jetContainer (key, ctx);
997 // Check that this container is present
998 if ( !jetContainer.isValid() ) {
999 ATH_MSG_WARNING("No gFex jet container found in storegate: "<< key.key());
1000 }
1001 else {
1002 for(const xAOD::gFexJetRoI* gFexJetRoIContainer : *jetContainer) {
1003 gFexEt =gFexJetRoIContainer->gFexTobEt()/10;
1004 gFexEta=gFexJetRoIContainer->eta();
1005 if (gFexJetRoIContainer->phi() < 0) {
1006 gFexPhi=gFexJetRoIContainer->phi()+2*M_PI;
1007 }
1008 else {
1009 gFexPhi=gFexJetRoIContainer->phi();
1010 }
1011 if (TOBeT_max < gFexEt) {
1012 TOBeT_max = gFexJetRoIContainer->gFexTobEt()/10;
1013 TOBeta_max = gFexJetRoIContainer->eta();
1014 if (gFexJetRoIContainer->phi() < 0) {
1015 TOBphi_max=gFexJetRoIContainer->phi()+2*M_PI;
1016 }
1017 else {
1018 TOBphi_max=gFexJetRoIContainer->phi();
1019 }
1020 }
1021 }
1022 }
1023 }
1024 if (trigger == "gFex") {
1025 fill("Gfex_maxTOB", TOBeT_max);
1026 fill("Gfex_maxTOB", TOBeta_max, TOBphi_max);
1027 }
1028
1029 }
1030
1031 return StatusCode::SUCCESS;
1032}
1033
1034
1036 std::vector<MonitorTT> &vecMonTT) const
1037{
1038 // Geometry
1039 const double phi = tt->phi();
1040 double phiMod = phi * m_phiScaleTT;
1041
1042
1043
1044 // Fill TT quantities
1045 MonitorTT monTT;
1046 monTT.tower = tt;
1047 monTT.phiScaled = phiMod;
1048 monTT.phi1d = 0;
1049 vecMonTT.push_back(monTT);
1050
1051 return StatusCode::SUCCESS;
1052}
1053
1054
1056 std::vector<MonitorCPM> &vecMonCPM) const
1057{
1058 // Geometry
1059 const double phi = cpm->phi();
1060 double phiMod = phi * m_phiScaleTT;
1061
1062
1063 // Fill CPM quantities
1064 MonitorCPM monCPM;
1065 monCPM.tower = cpm;
1066
1067 double etaMod = monCPM.tower->eta();
1068 const double absEta = std::abs(etaMod);
1069
1070 const std::vector<double> offset32 = {1.5, 0.5, -0.5, -1.5};
1071 const std::vector<double> offset25 = {0.5, -0.5};
1072 std::vector<double> offset = {};
1073
1074 if (absEta > 3.2) {
1075 // Fill four bins in phi
1076 phiMod = std::floor(phiMod/4)*4. + 2.;
1077 offset = offset32;
1078 }
1079 else if (absEta > 2.5) {
1080 // Fill two bins in phi
1081 phiMod = std::floor(phiMod/2)*2. + 1.;
1082 offset = offset25;
1083 }
1084 else {
1085 offset = {0.};
1086 }
1087
1088
1089
1090 // Fill the histograms
1091 for (auto phiOffset : offset) {
1092 monCPM.phiScaled.push_back(phiMod + phiOffset);
1093 }
1094
1095 monCPM.etaScaled = etaMod;
1096
1097
1098 vecMonCPM.push_back(monCPM);
1099
1100 return StatusCode::SUCCESS;
1101}
1102
1104 std::vector<MonitorJE> &vecMonJE) const
1105{
1106
1107 // Use JEP info to fill the forward part of the lut plots, but since this has TT granularity we have to play some tricks
1108
1109 // Geometry
1110 const double phi = je->phi();
1111 double phiMod = phi * m_phiScaleTT;
1112
1113 // Fill JE quantities
1114 MonitorJE monJE;
1115 monJE.element = je;
1116
1117 double etaMod = monJE.element->eta();
1118 const double absEta = std::abs(etaMod);
1119 int signeta = 1;
1120 if( etaMod < 0) signeta = -1;
1121
1122
1123 const std::vector<double> offset32 = {1.5, 0.5, -0.5, -1.5};
1124 const std::vector<double> offset25 = {0.5, -0.5};
1125 std::vector<double> offset = {};
1126
1127 if (absEta > 3.2) {
1128 // Fill four bins in phi
1129 phiMod = std::floor(phiMod/4)*4. + 2.;
1130 offset = offset32;
1131 monJE.etaScaled.push_back(signeta*4.7);
1132 monJE.etaScaled.push_back(signeta*3.7);
1133 monJE.etaScaled.push_back(signeta*3.5);
1134
1135 }
1136 else if(absEta > 2.9) {
1137 phiMod = std::floor(phiMod/2)*2. + 1.;
1138 offset = offset25;
1139 monJE.etaScaled.push_back(signeta*3.15);
1140 }
1141
1142
1143 if (absEta > 2.5) {
1144 // Fill two bins in phi
1145 phiMod = std::floor(phiMod/2)*2. + 1.;
1146 offset = offset25;
1147 monJE.etaScaled.push_back(etaMod);
1148 }
1149 else {
1150 offset = {0.};
1151 monJE.etaScaled.push_back(etaMod);
1152 }
1153
1154
1155 // Fill the histograms
1156 for (auto phiOffset : offset) {
1157 monJE.phiScaled.push_back(phiMod + phiOffset);
1158 }
1159
1160 vecMonJE.push_back(monJE);
1161
1162 return StatusCode::SUCCESS;
1163}
1164
1165
1167 const std::string& groupName,
1168 const std::string& weightName,
1169 double weight) const {
1170
1171
1172 double phiMod = monTT.phiScaled; // Integer binning for 2D plots
1173 double etaMod = monTT.tower->eta();
1174 const double absEta = std::abs(etaMod);
1175
1176 const std::vector<double> offset32 = {1.5, 0.5, -0.5, -1.5};
1177 const std::vector<double> offset25 = {0.5, -0.5};
1178 std::vector<double> offset = {};
1179
1180 if (absEta > 3.2) {
1181 // Fill four bins in phi
1182 phiMod = std::floor(phiMod/4)*4. + 2.;
1183 offset = offset32;
1184 }
1185 else if (absEta > 2.5) {
1186 // Fill two bins in phi
1187 phiMod = std::floor(phiMod/2)*2. + 1.;
1188 offset = offset25;
1189 }
1190 else {
1191 offset = {0.};
1192 }
1193
1194 ATH_MSG_DEBUG("absEta: " << absEta << "offset.size(): " << offset.size());
1195
1196 // Fill the histograms
1197 for (auto phiOffset : offset) {
1198
1199 auto etaTT_2D = Monitored::Scalar<double>("etaTT_2D", etaMod);
1200 auto phiTT_2D = Monitored::Scalar<double>("phiTT_2D", phiMod + phiOffset);
1201
1202 auto weight_2D = Monitored::Scalar<double>(weightName, weight); // Weight for filling 2D profile histograms; name must be included in python histogram definition
1203 ATH_MSG_DEBUG("groupName: weight_2D" << weight_2D);
1204
1205 fill(groupName, etaTT_2D, phiTT_2D, weight_2D);
1206
1207 }
1208
1209 return StatusCode::SUCCESS;
1210}
1211
1212
1213bool MistimedStreamMonitorAlgorithm::pulseQuality(const std::vector<uint16_t>& ttPulse, int peakSlice) const {
1214
1215 bool goodPulse = true;
1216 int size = ttPulse.size();
1217 if (peakSlice > size) {
1218 ATH_MSG_ERROR("Peak Slice " << peakSlice << " supress the ttPulse vector size " << size );
1219 goodPulse = false;
1220 return goodPulse;
1221 }
1222 if (size < 1) {
1223 ATH_MSG_ERROR("The ttPulse vector size " << size << " not valid for Peak Slice " << peakSlice );
1224 goodPulse = false;
1225 return goodPulse;
1226 }
1227 int a = ttPulse[peakSlice-1];
1228 int b = ttPulse[peakSlice];
1229 int c = ttPulse[peakSlice+1];
1230 double tim = (0.5*a-0.5*c)/(a+c-2*b);
1231 double wid = (a+c-64.0)/(b-32.0);
1232 if ( tim < 0.0 ) goodPulse = false;
1233 else if ( tim > 0.3 ) goodPulse = false;
1234 if ( wid < 1.0 ) goodPulse = false;
1235 else if ( wid > 1.6 ) goodPulse = false;
1236
1237 ATH_MSG_DEBUG("Pulse qual= "<< goodPulse<<" tim = "<<tim<<" wid = "<<wid);
1238 ATH_MSG_DEBUG("a = "<< a <<" b = "<<b<<" c = "<<c);
1239
1240 return goodPulse;
1241}
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Helper class to provide constant type-safe access to aux data.
#define CHECK(...)
Evaluate an expression and check for errors.
static Double_t a
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.
virtual StatusCode initialize() override
initialize
StatusCode makeTowerCPM(const xAOD::CPMTower *cpm, std::vector< MonitorCPM > &vecMonCPM) const
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
Gaudi::Property< std::vector< std::string > > m_gfexItems
SG::ReadHandleKey< xAOD::CPMTowerContainer > m_cpmTowerLocation
ToolHandle< LVL1::IL1TriggerTowerToolRun3 > m_ttTool
SG::ReadHandleKey< xAOD::eFexEMRoIContainer > m_eFexEMOutContainerKey
SG::ReadHandleKey< xAOD::eFexTauRoIContainer > m_eFexTauContainerKey
SG::ReadHandleKey< xAOD::jFexTowerContainer > m_EmulTowerKey
SG::ReadCondHandleKey< L1CaloReadoutConfigContainerJSON > m_readoutConfigContainerJSON
bool pulseQuality(const std::vector< uint16_t > &ttPulse, int peakSlice) const
SG::ReadHandleKey< CTP_RDO > m_ctpRdoReadKey
PublicToolHandle< Trig::TrigDecisionTool > m_trigDec
SG::ReadHandleKey< xAOD::jFexTowerContainer > m_jFexDataTowerKey
Gaudi::Property< std::vector< std::string > > m_jfexItems
Gaudi::Property< std::vector< std::string > > m_efexItems
StatusCode fillPPMEtaPhi(MonitorTT &monTT, const std::string &groupName, const std::string &weightName, double weight) const
SG::ReadCondHandleKey< L1CaloRunParametersContainer > m_runParametersContainer
SG::ReadHandleKey< xAOD::eFexEMRoIContainer > m_eFexEMContainerKey
MistimedStreamMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< xAOD::jFexTauRoIContainer > m_jFexTauContainerKey
SG::ReadHandleKeyArray< xAOD::gFexJetRoIContainer > m_gFexJetTobKeyList
StatusCode makeTowerJE(const xAOD::JetElement *je, std::vector< MonitorJE > &vecMonJE) const
SG::ReadHandleKey< xAOD::JetElementContainer > m_jetElementLocation
SG::ReadHandleKey< xAOD::TriggerTowerContainer > m_xAODTriggerTowerContainerName
container keys including steering parameter and description
SG::ReadHandleKey< xAOD::jFexSRJetRoIContainer > m_jFexSRJetContainerKey
SG::ReadHandleKey< xAOD::jFexLRJetRoIContainer > m_jFexLRJetContainerKey
StatusCode makeTowerPPM(const xAOD::TriggerTower *tt, std::vector< MonitorTT > &vecMonTT) const
Helper functions.
Declare a monitored scalar variable.
Helper class to provide type-safe access to aux data.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
float phi() const
get phi (note that for L1Calo phi runs from 0 to 2pi)
float phi() const
get phi (note that for L1Calo phi runs from 0 to 2pi)
uint16_t tobEt() const
uint32_t tobWord() const
The "raw" 32-bit word describing the object candidate.
uint32_t tobWord() const
The "raw" 32-bit word describing the object candidate.
float phi() const
uint16_t tobEt() const
float eta() const
eFexEMRoIContainer_v1 eFexEMRoIContainer
gFexJetRoI_v1 gFexJetRoI
Define the latest version of the gFexJetRoI class.
Definition gFexJetRoI.h:16
JetElement_v2 JetElement
Define the latest version of the JetElement class.
gFexJetRoIContainer_v1 gFexJetRoIContainer
CPMTower_v2 CPMTower
Define the latest version of the CPMTower class.
TriggerTower_v2 TriggerTower
Define the latest version of the TriggerTower class.
jFexTauRoI_v1 jFexTauRoI
Define the latest version of the jFexSRJetRoI class.
Definition jFexTauRoI.h:13
jFexSRJetRoI_v1 jFexSRJetRoI
Define the latest version of the jFexSRJetRoI class.
jFexSRJetRoIContainer_v1 jFexSRJetRoIContainer
jFexTower_v1 jFexTower
Define the latest version of the TriggerTower class.
Definition jFexTower.h:15
void fill(H5::Group &out_file, size_t iterations)