22 #include "ROOT/RVec.hxx"
48 std::unique_ptr<TFile>
f( TFile::Open(
fileName.c_str()) );
50 TTree*
t =
f->Get<TTree>(
"mapping");
52 unsigned long long scid = 0;
53 std::pair<int,int>
coord = {0,0};
54 std::pair<int,int> slot;
55 t->SetBranchAddress(
"scid",&scid);
56 t->SetBranchAddress(
"etaIndex",&
coord.first);
57 t->SetBranchAddress(
"phiIndex",&
coord.second);
58 t->SetBranchAddress(
"slot1",&slot.first);
59 t->SetBranchAddress(
"slot2",&slot.second);
60 for(Long64_t
i=0;
i<
t->GetEntries();
i++) {
62 m_scMap[scid] = std::make_pair(
coord,slot);
66 if (m_scMap.empty()) {
74 return StatusCode::SUCCESS;
84 return StatusCode::FAILURE;
89 return StatusCode::FAILURE;
95 std::map<std::pair<int,int>,std::array<int,11>>
towers;
97 for (
auto digi: *scells) {
98 const auto itr = m_scMap.find(digi->ID().get_compact());
99 if (itr == m_scMap.end()) {
continue; }
100 int val =
std::round(digi->energy()/(12.5*std::cosh(digi->eta())));
102 bool isMasked =
m_applyMasking ? ((digi)->provenance()&0x80) :
false;
109 auto& tower =
towers[itr->second.first];
110 if (itr->second.second.second<11) {
112 if (!isMasked &&
val!=-99999) {
115 tower.at(itr->second.second.first)=0;
117 tower.at(itr->second.second.first) +=
val >> 1;
118 tower.at(itr->second.second.second) += (
val - (
val >> 1));
124 auto&
v = tower.at(itr->second.second.first);
136 static const auto etaIndex = [](
float eta) {
return int(
eta*10 ) + ((
eta<0) ? -1 : 1); };
138 for(
const auto& tTower : *tTowers) {
139 if (std::abs(tTower->eta()) > 1.5)
continue;
140 if (tTower->sampling() != 1)
continue;
150 TFile *debugFile =
dynamic_cast<TFile *
>(gROOT->GetListOfFiles()->FindObject(
"debug_eFexTowerBuilder.root"));
151 if (!debugFile) debugFile = TFile::Open(
"debug_eFexTowerBuilder.root",
"RECREATE");
152 if (debugFile->GetListOfKeys()->GetEntries() < 20) {
155 TH2D ps(
"ps",
"ps [MeV];#eta;#phi", 50, -2.5, 2.5, 64, -
M_PI,
M_PI);
156 TH2D l1(
"l1",
"l1 [MeV];#eta;#phi", 200, -2.5, 2.5, 64, -
M_PI,
M_PI);
157 TH2D l2(
"l2",
"l2 [MeV];#eta;#phi", 200, -2.5, 2.5, 64, -
M_PI,
M_PI);
158 TH2D l3(
"l3",
"l3 [MeV];#eta;#phi", 50, -2.5, 2.5, 64, -
M_PI,
M_PI);
159 TH2D had(
"had",
"had [MeV];#eta;#phi", 50, -2.5, 2.5, 64, -
M_PI,
M_PI);
161 if (counts.empty())
continue;
162 double tEta = ((
coord.first < 0 ? 0.5 : -0.5) +
coord.first - 0.5) * 0.1;
163 double tPhi = ((
coord.second < 0 ? 0.5 : -0.5) +
coord.second) *
M_PI / 32;
165 for (
int i = 0;
i < 4;
i++)
167 l1.Fill(tEta + 0.025 *
i + 0.0125, tPhi, counts.at(
i + 1) * 12.5);
168 for (
int i = 0;
i < 4;
i++)
170 l2.Fill(tEta + 0.025 *
i + 0.0125, tPhi, counts.at(
i + 5) * 12.5);
173 had.Fill(tEta + 0.05, tPhi, counts.at(10) * (std::abs(
coord.first) <= 15 ? 500. : 12.5));
175 std::vector < TH1 * >
hists{&ps, &
l1, &
l2, &l3, &had};
178 c.SetTitle(
TString::Format(
"Run %u LB %u Event %lu", ctx.eventID().run_number(), ctx.eventID().lumi_block(),
179 ctx.eventID().event_number()));
181 TH2D tobs(
"tobs",
"Sum [MeV];#eta;#phi", 50, -2.5, 2.5, 64, -
M_PI,
M_PI);
182 for (
size_t i = 0;
i <
hists.size();
i++) {
183 c.GetPad(
i + 1)->cd();
184 hists[
i]->SetStats(
false);
185 hists[
i]->SetMarkerSize(2);
186 hists[
i]->GetXaxis()->SetRangeUser(-0.3, 0.3);
187 hists[
i]->GetYaxis()->SetRangeUser(-0.3, 0.3);
188 hists[
i]->Draw((
hists[
i]->GetNbinsX() > 50) ?
"coltext89" :
"coltext");
189 for (
int ii = 1; ii <=
hists[
i]->GetNbinsX(); ii++) {
190 for (
int jj = 1; jj <=
hists[
i]->GetNbinsY(); jj++)
191 tobs.Fill(
hists[
i]->GetXaxis()->GetBinCenter(ii),
hists[
i]->GetYaxis()->GetBinCenter(jj),
192 hists[
i]->GetBinContent(ii, jj));
195 c.GetPad(
hists.size() + 1)->cd();
196 tobs.SetStats(
false);
198 TBox
b(-0.3, -0.3, 0.3, 0.3);
199 b.SetLineColor(kRed);
202 b.SetBit(TBox::kCannotMove);
203 tobs.GetListOfFunctions()->Add(
b.Clone());
205 "{ 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++) {auto h = dynamic_cast<TH1*>(gPad->GetCanvas()->GetPad(i)->GetListOfPrimitives()->At(1)); if(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(); } }",
215 ATH_CHECK( eTowers.
record(std::make_unique<xAOD::eFexTowerContainer>(),std::make_unique<xAOD::eFexTowerAuxContainer>()) );
217 static const auto calToFex = [](
int calEt) {
219 if( calEt == -99999 )
return 1022;
220 if(calEt<448)
return std::max((calEt&~1)/2+32,1);
221 if(calEt<1472)
return (calEt-448)/4+256;
222 if(calEt<3520)
return (calEt-1472)/8+512;
223 if(calEt<11584)
return (calEt-3520)/32+768;
229 size_t ni = (std::abs(
coord.first)<=15) ? 10 : 11;
230 for(
size_t i=0;
i<ni;++
i) counts[
i] = (scells->empty() ? 1025 : calToFex(counts[
i]));
231 eTowers->
push_back( std::make_unique<xAOD::eFexTower>() );
232 eTowers->
back()->initialize( ( (
coord.first<0 ? 0.5:-0.5) +
coord.first)*0.1 ,
234 std::vector<uint16_t>(counts.begin(), counts.end()),
240 return StatusCode::SUCCESS;
252 return StatusCode::FAILURE;
254 if (scells->
size() != 34048) {
255 ATH_MSG_FATAL(
"Cannot fill sc -> eFexTower mapping with an incomplete sc collection");
256 return StatusCode::FAILURE;
259 std::vector<unsigned long long> ps;
260 std::vector<std::pair<float,unsigned long long>>
l1;
261 std::vector<std::pair<float,unsigned long long>>
l2;
262 std::vector<unsigned long long> l3;
263 std::vector<unsigned long long> had;
264 std::vector<unsigned long long>
other;
266 static const auto etaIndex = [](
float eta) {
return int(
eta*10 ) + ((
eta<0) ? -1 : 1); };
267 static const auto phiIndex = [](
float phi) {
return int(
phi*32./ROOT::Math::Pi() ) + (
phi<0 ? -1 : 1); };
268 std::map<std::pair<int,int>,TowerSCells>
towers;
269 std::map<unsigned long long,int> eTowerSlots;
271 for (
auto digi: *scells) {
274 if (
auto elem = ddm->get_element(
id); elem && std::abs(elem->eta_raw())<2.5) {
275 float eta = elem->eta_raw();
276 int sampling = elem->getSampling();
277 if(sampling==6 && ddm->getCaloCell_ID()->region(
id)==0 &&
eta<0)
eta-=0.01;
279 unsigned long long val =
id.get_compact();
281 int towerid = -1;
int slot = -1;
bool issplit =
false;
283 eTowerSlots[
id.get_compact()] = slot;
288 sc.ps.push_back(
val);
291 sc.l1.push_back({elem->eta(),
val});
break;
293 sc.l2.push_back({elem->eta(),
val});
break;
295 sc.l3.push_back(
val);
break;
296 case 8:
case 9:
case 10:
case 11:
297 sc.had.push_back(
val);
break;
299 sc.other.push_back(
val);
break;
307 std::vector<size_t> slotVector(11);
309 std::sort(
sc.l1.begin(),
sc.l1.end());
310 std::sort(
sc.l2.begin(),
sc.l2.end());
312 if (
sc.l2.size()==5) {
313 if (
coord.first >= 0) {
314 sc.l3.push_back(
sc.l2.front().second);
315 sc.l2.erase(
sc.l2.begin());
317 sc.l3.push_back(
sc.l2.back().second);
318 sc.l2.resize(
sc.l2.size()-1);
321 if (std::abs(
coord.first)==15) {
328 if (
sc.l1.size()==6) {
329 m_scMap[
sc.l1.at(0).second] = std::pair(
coord,std::pair(1,11));
330 m_scMap[
sc.l1.at(1).second] = std::pair(
coord,std::pair(1,2));
331 m_scMap[
sc.l1.at(2).second] = std::pair(
coord,std::pair(2,11));
332 m_scMap[
sc.l1.at(3).second] = std::pair(
coord,std::pair(3,11));
333 m_scMap[
sc.l1.at(4).second] = std::pair(
coord,std::pair(3,4));
334 m_scMap[
sc.l1.at(5).second] = std::pair(
coord,std::pair(4,11));
335 slotVector[1] = eTowerSlots[
sc.l1.at(0).second];
336 slotVector[2] = eTowerSlots[
sc.l1.at(2).second];
337 slotVector[3] = eTowerSlots[
sc.l1.at(3).second];
338 slotVector[4] = eTowerSlots[
sc.l1.at(5).second];
342 if (
sc.l1.size()==1) {
343 m_scMap[
sc.l1.at(0).second] = std::pair(
coord,std::pair(4,11));
344 slotVector[1] = 1; slotVector[2] = 2; slotVector[3] = 3; slotVector[4] = eTowerSlots[
sc.l1.at(0).second];
348 if (!
sc.ps.empty()) {m_scMap[
sc.ps.at(0)] = std::pair(
coord,std::pair(0,11)); slotVector[0] = eTowerSlots[
sc.ps.at(0)]; }
349 if(
sc.l1.size()==4)
for(
size_t i=0;
i<4;
i++)
if(
sc.l1.size() >
i) {m_scMap[
sc.l1.at(
i).second] = std::pair(
coord,std::pair(
i+1,11)); slotVector[
i+1] = eTowerSlots[
sc.l1.at(
i).second]; }
350 for(
size_t i=0;
i<4;
i++)
if(
sc.l2.size() >
i) { m_scMap[
sc.l2.at(
i).second] = std::pair(
coord,std::pair(
i+5,11)); slotVector[
i+5] = eTowerSlots[
sc.l2.at(
i).second]; }
351 if (!
sc.l3.empty()) {m_scMap[
sc.l3.at(0)] = std::pair(
coord,std::pair(9,11)); slotVector[9] = eTowerSlots[
sc.l3.at(0)]; }
352 if (!
sc.had.empty()) {m_scMap[
sc.had.at(0)] = std::pair(
coord,std::pair(10,11));slotVector[10] = eTowerSlots[
sc.had.at(0)]; }
366 TFile
f(
"scToEfexTowers.root",
"RECREATE");
367 TTree*
t =
new TTree(
"mapping",
"mapping");
368 unsigned long long scid = 0;
369 std::pair<int,int>
coord = {0,0};
370 std::pair<int,int> slot = {-1,-1};
371 t->Branch(
"scid",&scid);
372 t->Branch(
"etaIndex",&
coord.first);
373 t->Branch(
"phiIndex",&
coord.second);
374 t->Branch(
"slot1",&slot.first);
375 t->Branch(
"slot2",&slot.second);
376 for(
auto& [
id,
val] : m_scMap) {
383 return StatusCode::SUCCESS;
394 std::lock_guard lock(m_fillMapMutex);