ATLAS Offline Software
Loading...
Searching...
No Matches
eFexEventDumper.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "eFexEventDumper.h"
6
7#include "TFile.h"
8#include "TTree.h"
10#include "TH2D.h"
11#include "TROOT.h"
12#include "TCanvas.h"
13#include "TBox.h"
14#include "TLatex.h"
15
16
17namespace LVL1 {
18
19 eFexEventDumper::eFexEventDumper(const std::string &name, ISvcLocator *pSvcLocator) :
20 AthReentrantAlgorithm(name,pSvcLocator) {
21
22
23 }
24
26 CHECK( m_towerKey.initialize(SG::AllowEmpty) );
27 CHECK( m_emTOBKey.initialize(SG::AllowEmpty) );
28 CHECK( m_tauTOBKey.initialize(SG::AllowEmpty) );
29 CHECK( m_noiseCutsKey.initialize() );
30 m_file.reset(TFile::Open(m_outputFileName.value().c_str(),"RECREATE"));
31 return StatusCode::SUCCESS;
32 }
33
34 StatusCode eFexEventDumper::execute(const EventContext& ctx) const {
35
36 std::map<std::pair<int, int>, int> noiseCutsMap; // key is [eta,layer]
37 SG::ReadCondHandle <CondAttrListCollection> noiseCuts{m_noiseCutsKey, ctx};
38 if (noiseCuts.isValid()) {
39 for (auto itr = noiseCuts->begin(); itr != noiseCuts->end(); ++itr) {
40 if (itr->first >= 50) continue;
41 noiseCutsMap[std::pair(itr->first, 0)] = itr->second["EmPS"].data<int>();
42 noiseCutsMap[std::pair(itr->first, 1)] = itr->second["EmFR"].data<int>();
43 noiseCutsMap[std::pair(itr->first, 2)] = itr->second["EmMD"].data<int>();
44 noiseCutsMap[std::pair(itr->first, 3)] = itr->second["EmBK"].data<int>();
45 noiseCutsMap[std::pair(itr->first, 4)] = (itr->first >= 10 && itr->first < 40)
46 ? itr->second["Tile"].data<int>()
47 : itr->second["HEC"].data<int>();
48 }
49 }
50
51
52 TDirectory* dir = gDirectory;
53 m_file->cd();
54 TCanvas c;c.Divide(2,3);
55 c.SetName(TString::Format("evt%lu", ctx.eventID().event_number()));
56 c.SetTitle(TString::Format("Run %u LB %u Event %lu",
57 ctx.eventID().run_number(),
58 ctx.eventID().lumi_block(),
59 ctx.eventID().event_number()));
60
61 TH2D ps("ps", "ps [MeV];#eta;#phi", 50, -2.5, 2.5, 64, -M_PI, M_PI);
62 TH2D l1("l1", "l1 [MeV];#eta;#phi", 200, -2.5, 2.5, 64, -M_PI, M_PI);
63 TH2D l2("l2", "l2 [MeV];#eta;#phi", 200, -2.5, 2.5, 64, -M_PI, M_PI);
64 TH2D l3("l3", "l3 [MeV];#eta;#phi", 50, -2.5, 2.5, 64, -M_PI, M_PI);
65 TH2D had("had", "had [MeV];#eta;#phi", 50, -2.5, 2.5, 64, -M_PI, M_PI);
66 TH2D tobs("tobs", "Sum [MeV];#eta;#phi", 50, -2.5, 2.5, 64, -M_PI, M_PI);
67 std::vector < TH2 * > hists{&ps, &l1, &l2, &l3, &had};
68 std::vector < TH2 * > fhists;
69 for(auto h : hists) fhists.push_back(dynamic_cast<TH2*>(h->Clone(TString::Format("%s_fail",h->GetName()))));
70
71 if(!m_towerKey.empty()) {
72 SG::ReadHandle <xAOD::eFexTowerContainer> towers{m_towerKey, ctx};
73 for (const xAOD::eFexTower* tower: *towers) {
74 auto counts = tower->et_count();
75 if (counts.empty()) continue;
76 double tEta = (int((tower->eta()+0.025)*10)-(tower->eta()<0)*1)*0.1; // left edge
77 double tPhi = tower->phi() + 0.025; // ~bin centre
78
79 for (size_t layer = 0; layer < 5; layer++) {
80 for (size_t cell = 0; cell < ((layer == 1 || layer == 2) ? 4 : 1); cell++) {
81
82 auto et = tower->cellEt(layer, cell); //- commented out until added to EDM
83 // only fill each bin once ... when using data towers some locations will have multiple towers
84 if (et && hists.at(layer)->GetBinContent(hists.at(layer)->FindFixBin(tEta + 0.025*cell + 0.0125, tPhi)) == 0) {
85 // check if fails noise cut ... will then also fill into another map
86 bool failedCut = (counts.at(tower->cellIdx(layer,cell)) <= noiseCutsMap[std::pair( int( (tower->eta() + 2.525)/0.1 ), layer)]);
87
88 hists.at(layer)->Fill(tEta + 0.025*cell + 0.0125, tPhi, et);
89 if(failedCut) fhists.at(layer)->Fill(tEta + 0.025*cell + 0.0125, tPhi, et);
90 // if filling a phi edge bin, fill the over/underflow on the other side, so that energies wrap around
91 int j = hists.at(layer)->GetYaxis()->FindFixBin(tPhi);
92 if(j==1) {
93 hists.at(layer)->Fill(tEta + 0.025*cell + 0.0125, tPhi+2*M_PI,et);
94 if(failedCut) fhists.at(layer)->Fill(tEta + 0.025*cell + 0.0125, tPhi+2*M_PI,et);
95 } else if(j==hists.at(layer)->GetNbinsY()) {
96 hists.at(layer)->Fill(tEta + 0.025*cell + 0.0125, tPhi-2*M_PI,et);
97 if(failedCut) fhists.at(layer)->Fill(tEta + 0.025*cell + 0.0125, tPhi-2*M_PI,et);
98 }
99 }
100 }
101 }
102 }
103 }
104
105 for (size_t i = 0; i < hists.size(); i++) {
106 c.GetPad(i + 1)->cd()->SetGrid(1,1);
107 hists[i]->SetStats(false);
108 hists[i]->SetMarkerSize(2); // controls text size
109 hists[i]->GetXaxis()->SetRangeUser(-0.3, 0.3);
110 hists[i]->GetYaxis()->SetRangeUser(-0.3, 0.3);
111 hists[i]->Draw((hists[i]->GetNbinsX()>50)?"col1text89" : "col1text");
112 fhists[i]->SetMarkerSize(2);
113 fhists[i]->SetMarkerColor(kRed); // displays supercells failing noise cuts in red text
114 fhists[i]->GetXaxis()->SetRangeUser(-0.3, 0.3);
115 fhists[i]->GetYaxis()->SetRangeUser(-0.3, 0.3);
116 fhists[i]->Draw((hists[i]->GetNbinsX()>50)?"sametext89" : "sametext");
117 for(int ii=1;ii<=hists[i]->GetNbinsX();ii++) {
118 for(int jj=1;jj<=hists[i]->GetNbinsY();jj++)
119 tobs.Fill(hists[i]->GetXaxis()->GetBinCenter(ii),hists[i]->GetYaxis()->GetBinCenter(jj),hists[i]->GetBinContent(ii,jj));
120 }
121 }
122 auto lastPad = c.GetPad(hists.size() + 1)->cd();
123 tobs.SetStats(false);
124 tobs.Draw("col1");
125 TBox b(-0.3, -0.3, 0.3, 0.3);
126 b.SetLineColor(kRed);
127 b.SetFillStyle(0);
128 b.SetLineWidth(1);
129 b.SetBit(TBox::kCannotMove);
130 tobs.GetListOfFunctions()->Add(b.Clone());
131 lastPad->AddExec("onClick", TString::Format(
132 "{ auto pad = gPad->GetCanvas()->GetPad(%lu); if( pad->GetEvent()==kButton1Down ) { double x = pad->PadtoX(pad->AbsPixeltoX(pad->GetEventX())); double y = pad->PadtoY(pad->AbsPixeltoY(pad->GetEventY())); for(int i=1;i<%lu;i++) {for(auto o : *gPad->GetCanvas()->GetPad(i)->GetListOfPrimitives()) {if(auto h = dynamic_cast<TH1*>(o);h) {h->GetXaxis()->SetRangeUser(x-0.3,x+0.3);h->GetYaxis()->SetRangeUser(y-0.3,y+0.3); } } } if(auto b = dynamic_cast<TBox*>(pad->FindObject(\"tobs\")->FindObject(\"TBox\"))) {b->SetX1(x-0.3);b->SetX2(x+0.3);b->SetY1(y-0.3);b->SetY2(y+0.3);} gPad->GetCanvas()->Paint(); gPad->GetCanvas()->Update(); } }",
133 hists.size() + 1, hists.size() + 1));
134
135 if(!m_emTOBKey.empty()) {
136 SG::ReadHandle <xAOD::eFexEMRoIContainer> tobs1{m_emTOBKey, ctx};
137 TLatex l;l.SetTextColor(kMagenta);
138 for (auto tob: *tobs1) {
139 l.DrawLatex(tob->eta(), tob->phi(), TString::Format("%x", tob->word0()));
140 }
141 }
142
143
144 c.Write();
145 gDirectory = dir;
146
147
148 return StatusCode::SUCCESS;
149 }
150
151
152
153
154}
#define M_PI
#define CHECK(...)
Evaluate an expression and check for errors.
Header file for AthHistogramAlgorithm.
An algorithm that can be simultaneously executed in multiple threads.
SG::ReadHandleKey< xAOD::eFexTowerContainer > m_towerKey
virtual StatusCode execute(const EventContext &ctx) const
virtual StatusCode initialize()
SG::ReadHandleKey< xAOD::eFexEMRoIContainer > m_emTOBKey
SG::ReadCondHandleKey< CondAttrListCollection > m_noiseCutsKey
std::shared_ptr< TFile > m_file
eFexEventDumper(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< xAOD::eFexTauRoIContainer > m_tauTOBKey
Gaudi::Property< std::string > m_outputFileName
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
eFexTower_v1 eFexTower
Define the latest version of the TriggerTower class.
Definition eFexTower.h:15
Extra patterns decribing particle interation process.