ATLAS Offline Software
Loading...
Searching...
No Matches
Egamma1_OnlineMapNbhood.cxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3 */
4
5/*
6 This algorithm outputs Calorimeter strip data in the region of
7 eFex RoIs.
8*/
9
12#include "../IO/eEmNbhoodTOB.h"
13
14#include "CaloEvent/CaloCell.h"
16
18
20
21#include <fstream>
22#include <vector>
23#include <algorithm>
24#include <optional>
25#include <ranges>
26
27namespace GlobalSim {
28
29 Egamma1_OnlineMapNbhood::Egamma1_OnlineMapNbhood(const std::string& name, ISvcLocator* pSvcLocator ) :
30 AthReentrantAlgorithm(name, pSvcLocator){
31 }
32
33 //This is not a good hashId. Use this as a dummy/halt point throughout the code.
34 constexpr IdentifierHash hashIdDummy = 999999;
35 //The maximum number of cells (i.e. the ceiling of the IdentifierHash's
36 constexpr int maxIdentifierHash = 187650;
37
38 //Before all events, setup the required variables and tools.
40 ATH_MSG_DEBUG ("Initializing " << name());
41
42 //Input keys
43 CHECK(m_eventInfoKey.initialize());
44 CHECK(m_gblLArCellContainerKey.initialize());
45 CHECK(m_roiAlgTool.retrieve());
46 //Output keys
47 CHECK(m_neighKey.initialize());
48 CHECK(m_eFEXetaKey.initialize());
49 CHECK(m_eFEXphiKey.initialize());
50 CHECK(m_FailedeFEXetaKey.initialize());
51 CHECK(m_FailedeFEXphiKey.initialize());
52
53 // retrieve ID helpers
54 ATH_CHECK(detStore()->retrieve(m_calocell_id, "CaloCell_ID"));
55
56 //Launch the calorimeter ID managers
57 const CaloIdManager* caloIdMgr = nullptr;
58 StatusCode sc = detStore()->retrieve(caloIdMgr);
59 if (sc.isFailure()) {
60 ATH_MSG_ERROR(" Unable to retrieve CaloIdManager from DetectoreStore");
61 return StatusCode::FAILURE;
62 }
63 m_larem_id = caloIdMgr->getEM_ID();
64
65 return StatusCode::SUCCESS;
66 }
67
68 // For each event, read in the event info, GlobalLArCell and eFeXRoI containers.
69 // Ask producers to create windows around each incoming RoI in the event.
70 StatusCode Egamma1_OnlineMapNbhood::execute(const EventContext& ctx) const {
71
72 ATH_MSG_DEBUG ("Executing");
73
74 //Get EventInfo
76 if(!eventInfo.isValid()) {
77 ATH_MSG_ERROR ("Error obtaining EventInfo object");
78 return StatusCode::FAILURE;
79 }
80
81 //Get GlobalLArCells
82 auto h_gblLArCells = SG::makeHandle(m_gblLArCellContainerKey, ctx);
83 CHECK(h_gblLArCells.isValid());
84 const auto & gblLArCells = *h_gblLArCells;
85 ATH_MSG_DEBUG(gblLArCells.size() <<"Cells read in");
86
87 //Get eFeXRoIs
88 std::vector<const xAOD::eFexEMRoI*> rois_in;
89 CHECK(m_roiAlgTool->RoIs(rois_in, ctx));
90 ATH_MSG_DEBUG(rois_in.size() << " RoI(s) read in");
91
92 //Remove the RoIs in the barrel/endcap crack region (hopefully temporary)
93 std::vector<const xAOD::eFexEMRoI*> rois;
94 for(auto roi:rois_in){
95 //Kill rois in the crack
96 if(std::abs(roi->eta()) >= 1.37 && std::abs(roi->eta()) <= 1.52) continue;
97 ATH_MSG_DEBUG ("Roi et " << roi->et());
98 rois.push_back(roi);
99 }
100
101 // find GlobalLArCells in the neighborhood of RoIs.
102 // A neighborhood is a collection of CellData objects which
103 // contain cell eta, phi and Et.
104
105 //Setup a container of TOBs with associated GlobalLArCell windows
106 auto neighborhoodTOBs = std::make_unique<IOBitwise::eEmNbhoodTOBContainer>();
107 //Flags for window finding success/failure
108 std::vector<bool> successes;
109
110 //Finw the windows for all of the valid incoming RoIs
111 CHECK(findNeighborhoods_OnlineMap(rois, gblLArCells, successes, *neighborhoodTOBs));
112
113 //Setup output for eFeXRoI eta/phi debug variables
115 CHECK(h_eFEXeta.record(std::make_unique<std::vector<float> >()));
117 CHECK(h_eFEXphi.record(std::make_unique<std::vector<float> >()));
118
120 CHECK(h_FailedeFEXeta.record(std::make_unique<std::vector<float> >()));
122 CHECK(h_FailedeFEXphi.record(std::make_unique<std::vector<float> >()));
123
124
125 //Fill RoI eta/phi variables for valid windows
126 for(int i=0; auto success:successes){
127 if(success){
128 h_eFEXeta->push_back(rois[i]->eta());
129 h_eFEXphi->push_back(rois[i]->phi());
130 } else {
131 h_FailedeFEXeta->push_back(rois[i]->eta());
132 h_FailedeFEXphi->push_back(rois[i]->phi());
133 }
134 i++;
135 }
136
137 //Setup the write out of the resultant TOBs
139
140 //Dump the window/RoI information to local files (for DEBUG)
142 if(m_dump || m_dumpTerse){
143 if (m_dump) {
144 CHECK(dumper.dump(name(), *eventInfo, *neighborhoodTOBs));
145 }
146
147 if (m_dumpTerse) {
148 CHECK(dumper.dumpTerse(name(), *eventInfo, *neighborhoodTOBs));
149 }
150 }
151
152 //Write out the TOBs
153 CHECK(h_neighborhoodTOBs.record(std::move(neighborhoodTOBs)));
154
155 return StatusCode::SUCCESS;
156 }
157
158 //This member function steps through all RoIs to produce windows for each RoI
159 //There are cases where the window finding can fail (no seed cell found). The
160 //success or failure of the algorithm is recorded here for debug purposes.
161 StatusCode
162 Egamma1_OnlineMapNbhood::findNeighborhoods_OnlineMap(const std::vector<const xAOD::eFexEMRoI*>& rois,
164 std::vector<bool>& successes,
165 IOBitwise::eEmNbhoodTOBContainer& neighborhoodTOBs) const{
166
167 for (const auto& roi : rois) {
168 ATH_MSG_DEBUG("roi et " << roi->et());
169 bool success = false;
170 ATH_CHECK(findNeighborhood_OnlineMap(roi, cells, success, neighborhoodTOBs));
171 successes.push_back(success);
172 }
173
174 return StatusCode::SUCCESS;
175 }
176
177 // This member function constructs an LArStripNeighborhood.
178 //
179 // A neighourhood is constructed from StripData objects constructed
180 // from GlobalLArCells (strips) in the vicinity of an EM RoI the following manner:
181 // The strip seed cell in the vicinity of the RoI is identified. An initial
182 // neighbourhood of strips centered on the seed is formed. The maximum energy
183 // cell within this window is then found. A final neighbourhood is then centered on
184 // this cell.
185 //
186 // In more detail:
187 // The RoI eta/phi coordinate (a supercell coordinate) is used to identify
188 // the seed cell in the strips (EM1) to form the window. This is done by forming
189 // a box in eta/phi space for each cell (using the cells known size and centre)
190 // and asking if the RoI's eta/phi position falls in it.
191 // As the granularity of the strips changes through the detector the search occurs in
192 // differing numbers of strips for each RoI tower range (the crack 1.37-152 is currently
193 // not dealth with).
194 // There are (8,6,4,1) strips per RoI supercell. First, the inner eta central strip
195 // is searched for first, e.g. +eta 4/8 or -eta 6/8. If a cell is found in the collection
196 // its ID is returned. If no cell is found then the search continues inwards, then finally
197 // outwards in eta. If no strips are found then the window finding halts. This halting is
198 // an issue with this method, and a fix is needed.
199 //
200 // A 17x3 eta/phi window is then formed around this seed cell. First the seed cell is found
201 // from a map of CellID->GlobalLArCells. Then the +-8 cells in eta are found using the
202 // m_larem_id->get_neighbours function. If a cell isn't present in the collection a dummy
203 // with the correct cellID is added to the list. If the window is at the edge of the detector
204 // a dummy with cellID 999999 is added, to allow for full sized windows at the edge. Once the
205 // central row has been filled, the process is repeated to fill the phi rows above and below.
206 //
207 // Once an initial window has been formed the maximum energy cell in this window is found.
208 // If the cell maxima for two rows are equal, then the central row is taken.
209 //
210 // This maximum energy cell is then used to repeat the first window finding step to find
211 // the final neighbourhood for this eFeXRoI, and an eEmNbhoodTOB is added to the list.
212 StatusCode
215 bool& success,
216 IOBitwise::eEmNbhoodTOBContainer& neighborhoodTOBs) const {
217
218 // Form the window, and set the vector sizes.
219 auto window = std::vector<std::vector<std::shared_ptr<const GlobalLArCell>>>(3);
220 window[0].resize(17);
221 window[1].resize(17);
222 window[2].resize(17);
223
224 //Setup variables
225 Identifier CellID;
226 float eta = roi->eta();
227 float phi = roi->phi();
228 bool found = false;
229 int strip = 0;
230
231 //Tower position to find strip granularity
232 int iEta = roi->iEta();
233 int iPhi = roi->iPhi();
234 ATH_MSG_DEBUG("Where is this RoI? eta: " << eta << " phi: " << phi << " iEta" << iEta << " iPhi " << iPhi);
235 //There are 1 strips per 0.025 supercell at the edge.
236 //Shouldn't need to shift these?
237 if(iEta == -25 || iEta == 24) {
238 //Just use the eta/phi as is, becasue there is only one strip here.
239 found = findSeedCell(eta, phi, cells, CellID);
240 }
241 //There are 4 strips per 0.025 in these towers
242 else if((iEta > -25 && iEta <= -21) || (iEta < 24 && iEta >= 20)){
243 strip = 4;
244 }
245 //There are 6 strips per 0.025 in these towers
246 else if((iEta > -21 && iEta <= -19) || (iEta < 20 && iEta >= 18)) {
247 strip = 6;
248 }
249 //There are 8 strips per 0.025 in these towers, apart from the crack region where
250 //here be dragons. The crack region is not currently dealt with.
251 else if((iEta > -19 && iEta <=-1) || (iEta < 18 && iEta >=0)) {
252 strip = 8;
253 } else {
254 //We shouldn't get here, but just in case...
255 ATH_MSG_WARNING("Where are we? eta " << eta << " phi " << phi);
256 }
257 //
258 if(strip != 0){
259 //Send the number of strips information along with the eta/phi supercell.
260 found = findHalfStrips(strip, eta, phi, cells, CellID);
261 }
262
263 //If we successfully found the seed cell, then continue.
264 if(found){
265 int ibec = abs(m_larem_id->barrel_ec(CellID)); // 1 barrel 2 EC OW 3 EC IW
266 int sampling = m_larem_id->sampling(CellID);
267 int eta = m_larem_id->eta(CellID);
268 int phi = m_larem_id->phi(CellID);
269 int region = m_larem_id->region(CellID);
270
271 ATH_MSG_DEBUG("Where is this Seed? B/E? " << ibec << " sampling " << sampling << " eta " << eta << " phi " << phi << " region " << region);
272
273 //Need the hash for the neighbours
274 IdentifierHash hashId=m_calocell_id->calo_cell_hash(CellID);
275 //Find the initial 17x3 eta/phi window
276 ATH_CHECK(findWindow(hashId, cells, window));
277 //Find the maxima in the window (only once!)
278 ATH_CHECK(findMaxima(hashId, window));
279 //Find the new 17x3 eta/phi window around this maxima
280 ATH_CHECK(findWindow(hashId, cells, window));
281
282 //Rediscover the maximum energy cell
283 auto it = std::ranges::max_element(std::begin(window[1]),
284 std::end(window[1]),
285 [](const auto& l,const auto& r) {
286 return l->getEnergy() < r->getEnergy();
287 });
288
289 std::shared_ptr<const GlobalLArCell> max_cell{*it};
290
291 //Function to fill the StripData for the neighbourhood
292 auto toStripData = [](const auto& fromCells){
293 auto stripdata = std::vector<StripData>();
294 stripdata.reserve(fromCells.size());
295 std::ranges::transform(std::begin(fromCells),
296 std::end(fromCells),
297 back_inserter(stripdata),
298 [](const auto& c) {
299 return StripData(c->eta(),
300 c->phi(),
301 c->getEnergy());});
302 return stripdata;
303 };
304
305 //Check that we didn't lose the maximum energy cell
306 auto max_neigh_cell_it = std::ranges::find(window[1],
307 max_cell);
308 if (max_neigh_cell_it == std::end(window[1])){
309 ATH_MSG_ERROR("Lost the max cell");
310 return StatusCode::FAILURE;
311 }
312
313 //Find the position of the maximum energy cell in the neighbourhood.
314 auto max_neigh_cell_pos{std::distance(std::begin(window[1]),
315 max_neigh_cell_it)};
316
317 //Fill the StripData vectors
318 auto low = toStripData(window[0]);
319 auto center = toStripData(window[1]);
320 auto high = toStripData(window[2]);
321
322 //Fill the neighbourhood seed roi, and maximum cell positions.
323 Coords roi_c{roi->eta(), roi->phi()};
324 Coords cell_c{max_cell->eta(), max_cell->phi()};
325
326 //Form the neighbourhood
327 LArStripNeighborhood neighborhood = LArStripNeighborhood(low, center, high, roi_c, cell_c, max_neigh_cell_pos);
328
329 //Add the neighbourhood to the list.
330 neighborhoodTOBs.push_back(std::make_unique<IOBitwise::eEmNbhoodTOB>(*roi, neighborhood));
331 success = true;
332 } else {
333 //If we didn't find the window, then tell us about it.
334 ATH_MSG_DEBUG("Didn't find the RoI eta: " << roi->eta() << " phi: " << roi->phi());
335 }
336 return StatusCode::SUCCESS;
337 }
338
339 // Function to step through midpoints of the LAr strips, depending on how many strips
340 // there are in the current tower.
342 float eta,
343 float phi,
345 Identifier& CellID) const {
346 //Initialise variables
347 bool found = false;
348 //For each supercell there are different numbers of strips, this finds the midpoints.
349 float half_strip = 0.025/strip/2;
350 //Define the "inwards" direction
351 //int sign = 1;
352 //if(eta < 0) sign = -1;
353 int sign = std::copysign(1, eta);
354 int halt = strip-1;
355 //Starting at the inner centre strip, step through the allowed strips to find the
356 //seed cell.
357 for(int i=1;i<=halt;i+=2){
358 found = findSeedCell(eta-(i*half_strip*sign), phi, cells, CellID);
359 if(found) {
360 ATH_MSG_DEBUG("We found it! Going in by " << (i+1)/2 << " eta: " << eta-(i*half_strip) << " phi: " << phi);
361 return found;
362 }
363 }
364 //If we didn't find the strip going inwards, look outwards instead.
365 if(!found){
366 for(int i=1;i<=halt;i+=2){
367 found = findSeedCell(eta+(i*half_strip*sign), phi, cells, CellID);
368 if(found) {
369 ATH_MSG_DEBUG("We found it! Going out " << (i+1)/2 << " eta: " << eta+(i*half_strip) << " phi: " << phi);
370 return found;
371 }
372 }
373 }
374 //Return if we failed to find a strip.
375 return found;
376 }
377
378 // Function to locate the seed cell for a window from an input eta/phi position.
379 // Loops over the input strips in layer 1 and asks if the input eta/phi position is within
380 // their physical location (i.e. centre +- half width in eta/phi).
381 // Once found it returns the CellID of the located cell for future retrieval.
384 Identifier& CellID) const {
385
386 // Loop over the cells
387 for(const GlobalSim::GlobalLArCell* cell :cells){
388 // Find the layer one cells
389 if(cell->getSampling() == 1 || cell->getSampling() == 5) {
390 // Draw the boxes for each cell
391 float etamin = cell->eta() - (0.5*cell->deta());
392 float etamax = cell->eta() + (0.5*cell->deta());
393
394 float phimin = cell->phi() - (0.5*cell->dphi());
395 float phimax = cell->phi() + (0.5*cell->dphi());
396
397 // Ask if the input lies within a box.
398 if(etamin < eta && eta < etamax && phimin < phi && phi < phimax){
399 // Return the cellID if we find a match
400 CellID = cell->getID();
401 ATH_MSG_DEBUG("Found the seed " << CellID << " eta "<< cell->eta() << " phi " << cell->phi() << " sampling " << m_larem_id->sampling(CellID));
402 return true;
403 }
404 }
405 }
406 // Otherwise report that we failed to find a match.
407 return false;
408 }
409
410 // Function to draw a window around a seed cell starting from the hashID of the seed cell
411 // and a container of all known GlobalLArCells. Returns the window.
414 std::vector<std::vector<std::shared_ptr<const GlobalLArCell>>>& window) const {
415
416 // If we pass in a Dummy ID we cannot start the process, fail gracefully for now.
417 if(hashId == hashIdDummy) return StatusCode::SUCCESS;
418
419 //Setup container for found neighbours.
420 std::vector<IdentifierHash> neighbourList;
421 //Setup next/previous hashIDs
422 IdentifierHash hashIdNext;
423 IdentifierHash hashIdPrev;
424 //Initialise them to the input for the first loop.
425 hashIdNext = hashIdPrev = hashId;
426 //Position of the cell in each 17 long eta row. Defined by position in loop.
427 int shift = 0;
428 //Check if we have hit the edge of the detector.
429 float etaMax = 0;
430
431 ATH_MSG_DEBUG("Seed Hash: " << hashId);
432 //Start loop to fill the central row of the 17x3 eta/phi window.
433 for(int etaOffset = 0; etaOffset <=8; etaOffset++){
434 ATH_MSG_DEBUG("Offset: " << etaOffset);
435 //Rediscover the centre cell for the first step.
436 if(etaOffset == 0){
437 //This retrieves the cell from a hash map in the GlobalLArCell container.
438 auto cell = cells.getCellFromHash(hashId);
439 //Sanity check.
440 if(cell != nullptr){
441 //Fill the central neighbourhood position.
442 window[1][8] = cell;
443 ATH_MSG_DEBUG("Found the middle cell " << cell->getID() << " at eta " << cell->eta() << " phi " << cell->phi());
444 //Start defining where we are in eta.
445 etaMax = cell->eta();
446 }
447 } else {
448 //If we are not at the edge, and were not previously at the edge. Then...
449 if(std::abs(etaMax) < 2.475 && hashIdNext != hashIdDummy){
450 //Use the previous hashIDNext to look for the next cell in eta
451 m_larem_id->get_neighbours(hashIdNext,LArNeighbours::nextInEta,neighbourList);
452 ATH_MSG_DEBUG("Next in eta " << neighbourList[0] << " HashId " << hashId);
453 //Grab the next cell hashID in eta and store it for the next step.
454 hashIdNext = neighbourList[0];
455 //Try to retrieve the cell from the hash map
456 auto cellNext = cells.getCellFromHash(hashIdNext);
457 //Define how steps we are away from the central cell
458 shift = 8+etaOffset;
459 //If the hash map contained the next cell.
460 if(cellNext != nullptr){
461 ATH_MSG_DEBUG("Found a cell " << cellNext->getID() << " at eta " << cellNext->eta() << " phi " << cellNext->phi());
462 //update the eta position
463 etaMax = cellNext->eta();
464 //Put the found cell in the window
465 window[1][shift] = cellNext;
466 } else {
467 //We didn't find the cell in the hash map. Put a dummy in the window.
468 ATH_MSG_DEBUG("Putting in a next dummy with hashIdNext " << hashIdNext);
469 window[1][shift] = std::make_shared<GlobalLArCell>(hashIdNext,"",0);
470 //Potential issue if you cannot find the cell... but this cell would be the last in eta?
471 }
472 } else {
473 //We are off the edge of the detector. Put in a Dummy cell to keep the window going.
474 shift = 8+etaOffset;
475 ATH_MSG_DEBUG("No next in eta: Putting in an empty DUMMY");
476 window[1][shift] = std::make_shared<GlobalLArCell>(hashIdDummy,"",0);
477 }
478 //Now go inwards, as above, but with prevInEta, and no need to pad for the edge of the detector.
479 m_larem_id->get_neighbours(hashIdPrev,LArNeighbours::prevInEta,neighbourList);
480 ATH_MSG_DEBUG("Previous in eta " << neighbourList[0] << " hashId " << hashId);
481 hashIdPrev = neighbourList[0];
482 auto cellPrev = cells.getCellFromHash(hashIdPrev);
483 shift = 8-etaOffset;
484 if(cellPrev != nullptr){
485 ATH_MSG_DEBUG("Found a cell " << cellPrev->getID() << " at eta " << cellPrev->eta() << " phi " << cellPrev->phi());
486 window[1][shift] = cellPrev;
487 } else {
488 ATH_MSG_DEBUG("Putting in a previous dummy with hasIdPrev " << hashIdPrev);
489 window[1][shift] = std::make_shared<GlobalLArCell>(hashIdPrev,"",0);
490 }
491 }
492 }
493
494 //We now have the central row. Loop to fill the phi rows above and below in phi.
495 for(int phiOffset = 0; phiOffset <=1; phiOffset++){
496 ATH_MSG_DEBUG("Offset: " << phiOffset);
497 //First do nextInPhi
498 if(phiOffset == 0){
499 shift = 0;
500 //Loop over the middle row.
501 for(auto& windowCell:window[1]){
502 ATH_MSG_DEBUG("Cell ID " << shift << " is " << windowCell->getID());
503 //If this isn't a Dummy cell
504 if(windowCell->getID() != hashIdDummy){
505 //Find the cell hashID from its offline ID.
506 IdentifierHash hashIdCurrent = m_calocell_id->calo_cell_hash(static_cast<Identifier>(windowCell->getID()));
507 //There are cases where the CellID is the hashID. Update the hash to this.
508 if(windowCell->getID() <= maxIdentifierHash) hashIdCurrent = windowCell->getID();
509 //Proceed as in eta, finding next in Phi.
510 m_larem_id->get_neighbours(hashIdCurrent,LArNeighbours::nextInPhi,neighbourList);
511 ATH_MSG_DEBUG("Next in phi " << neighbourList[0] << " hashId " << hashIdCurrent);
512 //Find the hashID and use it to look up the cell in the hash map.
513 hashIdCurrent = neighbourList[0];
514 auto cellCurrent = cells.getCellFromHash(hashIdCurrent);
515 //If we find the cell in the hash map
516 if(cellCurrent != nullptr){
517 //Put the cell in the window.
518 ATH_MSG_DEBUG("Found a cell " << cellCurrent->getID() << " at eta " << cellCurrent->eta() << " phi " << cellCurrent->phi());
519 window[0][shift] = cellCurrent;
520 } else {
521 //Put a dummy cell. No need to get the ID right here.
522 ATH_MSG_DEBUG("No next in phi: Last HashIdCurrent " << hashIdCurrent);
523 window[0][shift] = std::make_shared<GlobalLArCell>(hashIdDummy,"",0);
524 }
525 shift++;
526 } else {
527 //We found a Dummy in the middle row, put a dummy in next phi too.
528 ATH_MSG_DEBUG("No next in phi: Putting in a DUMMY");
529 window[0][shift] = std::make_shared<GlobalLArCell>(hashIdDummy,"",0);
530 shift++;
531 }
532 }
533 } else {
534 //Repeat the above for the previous row in Phi
535 shift = 0;
536 for(auto& windowCell:window[1]){
537 ATH_MSG_DEBUG("Cell ID " << shift << " is " << windowCell->getID());
538 if(windowCell->getID() != hashIdDummy){
539 IdentifierHash hashIdCurrent = m_calocell_id->calo_cell_hash(static_cast<Identifier>(windowCell->getID()));
540 if(windowCell->getID() <= maxIdentifierHash) hashIdCurrent = windowCell->getID();
541 m_larem_id->get_neighbours(hashIdCurrent,LArNeighbours::prevInPhi,neighbourList);
542 ATH_MSG_DEBUG("Previous in phi " << neighbourList[0] << " hashId " << hashIdCurrent);
543 hashIdCurrent = neighbourList[0];
544 auto cellCurrent = cells.getCellFromHash(hashIdCurrent);
545 if(cellCurrent != nullptr){
546 ATH_MSG_DEBUG("Found a cell " << cellCurrent->getID() << " at eta " << cellCurrent->eta() << " phi " << cellCurrent->phi());
547 window[2][shift] = cellCurrent;
548 } else {
549 ATH_MSG_DEBUG("No prev in phi: Putting in a DUMMY");
550 window[2][shift] = std::make_shared<GlobalLArCell>(hashIdDummy,"",0);
551 }
552 shift++;
553 } else {
554 ATH_MSG_DEBUG("No prev in phi: Putting in a DUMMY");
555 window[2][shift] = std::make_shared<GlobalLArCell>(hashIdDummy,"",0);
556 shift++;
557 }
558 }
559 }
560 }
561 return StatusCode::SUCCESS;
562 }
563 // Function to find the maximum energy cell within a neighbourhood.
564 // Return its hashID to be used to seed another neighbourhood window.
566 std::vector<std::vector<std::shared_ptr<const GlobalLArCell>>>& window) const {
567
568 //Vector to hold each row's maximum
569 std::vector<std::shared_ptr<const GlobalLArCell>> maxima;
570 //Loop over the rows and find each maximum energy cell.
571 for(uint row = 0;row < window.size();row++){
572 auto max_cell = Egamma1_OnlineMapNbhood::findMax(window[row]);
573 maxima.push_back(max_cell);
574 ATH_MSG_DEBUG("Found a max cell " << max_cell->getID() << " et " << max_cell->getEnergy() << " eta " << max_cell->eta() << " phi " << max_cell->phi());
575 }
576 //If we have two equal maxima, then take the middle row to be consistent.
577 if((maxima[0]->getEnergy() == maxima[1]->getEnergy() && maxima[1]->getEnergy() >= maxima[2]->getEnergy())
578 || (maxima[1]->getEnergy() == maxima[2]->getEnergy() && maxima[1]->getEnergy() >= maxima[0]->getEnergy())){
579 ATH_MSG_DEBUG("Found the max cell " << maxima[1]->getID() << " et " << maxima[1]->getEnergy() << " eta " << maxima[1]->eta() << " phi " << maxima[1]->phi());
580 hashId = m_calocell_id->calo_cell_hash(static_cast<Identifier>(maxima[1]->getID()));
581 return StatusCode::SUCCESS;
582 } else {
583 //Otherwise just take the maximum cell.
584 auto maximum_cell = Egamma1_OnlineMapNbhood::findMax(maxima);
585 ATH_MSG_DEBUG("Found the max cell " << maximum_cell->getID() << " et " << maximum_cell->getEnergy() << " eta " << maximum_cell->eta() << " phi " << maximum_cell->phi());
586 hashId = m_calocell_id->calo_cell_hash(static_cast<Identifier>(maximum_cell->getID()));
587 return StatusCode::SUCCESS;
588 }
589 }
590
591 //Function to find the maximum energy cell in a vector of GlobalLArCells.
592 std::shared_ptr<const GlobalLArCell> Egamma1_OnlineMapNbhood::findMax(std::vector<std::shared_ptr<const GlobalLArCell>>& row) const {
593 auto it = std::max_element(std::begin(row),
594 std::end(row),
595 [](const auto& l,const auto& r) {
596 return l->getEnergy() < r->getEnergy();
597 });
598
599 std::shared_ptr<const GlobalLArCell> max_cell{*it};
600 return max_cell;
601 }
602}
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_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
unsigned int uint
static Double_t sc
int sign(int a)
const ServiceHandle< StoreGateSvc > & detStore() const
An algorithm that can be simultaneously executed in multiple threads.
This class initializes the Calo (LAr and Tile) offline identifiers.
const LArEM_ID * getEM_ID(void) const
value_type push_back(value_type pElem)
Add an element to the end of the collection.
ToolHandle< eFexRoIAlgTool > m_roiAlgTool
ToolHandle for the eFexRoI AlgTool.
SG::WriteHandleKey< std::vector< float > > m_eFEXphiKey
WriteHandle Key for the eFexRoI's phi (for valid windows, for DEBUG).
Egamma1_OnlineMapNbhood(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< bool > m_dumpTerse
Parameter to toggle dumping of brief information window information.
SG::WriteHandleKey< IOBitwise::eEmNbhoodTOBContainer > m_neighKey
WriteHandle Key for the resulting TOBs.
StatusCode findWindow(IdentifierHash, const GlobalSim::GlobalLArCellContainer &, std::vector< std::vector< std::shared_ptr< const GlobalSim::GlobalLArCell > > > &) const
Function to produce a window around an input seed cell.
std::shared_ptr< const GlobalLArCell > findMax(std::vector< std::shared_ptr< const GlobalLArCell > > &) const
Function to find the maximum energy cell in a vector of cells.
virtual StatusCode execute(const EventContext &) const override
execute function running for every event
SG::WriteHandleKey< std::vector< float > > m_eFEXetaKey
WriteHandle Key for the eFexRoI's eta (for valid windows, for DEBUG).
StatusCode findMaxima(IdentifierHash &, std::vector< std::vector< std::shared_ptr< const GlobalSim::GlobalLArCell > > > &) const
Function to find the maximum energy cell in a window.
SG::WriteHandleKey< std::vector< float > > m_FailedeFEXetaKey
WriteHandle Key for the eFexRoI's eta (for invalid windows, for DEBUG).
virtual StatusCode initialize() override
initialize function running before the first event
StatusCode findNeighborhoods_OnlineMap(const std::vector< const xAOD::eFexEMRoI * > &, const GlobalSim::GlobalLArCellContainer &, std::vector< bool > &, IOBitwise::eEmNbhoodTOBContainer &) const
Function to produce mutliple windows from a vector of incoming eFeX RoIs.
StatusCode findNeighborhood_OnlineMap(const xAOD::eFexEMRoI *, const GlobalSim::GlobalLArCellContainer &, bool &, IOBitwise::eEmNbhoodTOBContainer &) const
Function to produce a window from an incoming eFeX RoI.
SG::WriteHandleKey< std::vector< float > > m_FailedeFEXphiKey
WriteHandle Key for the eFexRoI's phi (for invalid windows, for DEBUG).
Gaudi::Property< bool > m_dump
Parameter to toggle dumping of full information window information.
SG::ReadHandleKey< GlobalSim::GlobalLArCellContainer > m_gblLArCellContainerKey
ReadHandle Key to the GlobalLArCellContainer.
bool findSeedCell(float, float, const GlobalSim::GlobalLArCellContainer &, Identifier &) const
Function to find the seed cell for a window from the eFeX RoI position.
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
ReadHandle Key for the EventInfo object.
bool findHalfStrips(int, float, float, const GlobalSim::GlobalLArCellContainer &, Identifier &) const
Function to search for seed cells according to local granularity.
Class to hold windows of LAr strip cells in a the neighbourhood of a eFexRoI.
This is a "hash" representation of an Identifier.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
float eta() const
setter for the above
int iPhi() const
Setter for the above.
float phi() const
Seed supercell index within central tower (0 -> 3).
int iEta() const
setter for the above
int r
Definition globals.cxx:22
DataVector< GlobalSim::IOBitwise::eEmNbhoodTOB > eEmNbhoodTOBContainer
AlgTool that to test whether expected the TIP values generated by data supplied by eEmMultTestBench c...
constexpr int maxIdentifierHash
std::pair< double, double > Coords
constexpr IdentifierHash hashIdDummy
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
eFexEMRoI_v1 eFexEMRoI
Define the latest version of the eFexEMRoI class.
Definition eFexEMRoI.h:17