ATLAS Offline Software
Egamma1_LArStrip_Fex_RowAware.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 /*
6  This algorithm outputs Calorimeter strip data in the region of
7  eFex RoIs.
8 */
9 
11 #include "../IO/LArStripNeighborhoodDumper.h"
12 #include "../IO/eEmNbhoodTOB.h"
13 
14 #include "CaloEvent/CaloCell.h"
15 
17 
18 #include <fstream>
19 #include <vector>
20 #include <algorithm>
21 #include <optional>
22 
23 namespace GlobalSim {
24 
25  std::optional<std::vector<std::size_t>> wrap5(std::size_t center) {
26  if (center > 63) {
27  return std::optional<std::vector<std::size_t>>{};
28  }
29 
30  if (center == 63) {
31  return std::make_optional(std::vector<std::size_t>({61ul, 62ul, 63ul, 0ul, 1ul}));
32  }
33 
34  if (center == 0) {
35  return std::make_optional(std::vector<std::size_t>({62ul, 63ul, 0ul, 1ul, 2ul}));
36  }
37 
38  return std::make_optional(std::vector<std::size_t>(
39  {center-2,
40  center-1,
41  center,
42  center+1,
43  center+2}));
44  }
45 
46  Egamma1_LArStrip_Fex_RowAware::Egamma1_LArStrip_Fex_RowAware(const std::string& name, ISvcLocator* pSvcLocator ) :
47  AthReentrantAlgorithm(name, pSvcLocator){
48  }
49 
50 
52  ATH_MSG_INFO ("Initializing " << name());
53 
54  CHECK(m_cellProducer.retrieve());
55  CHECK(m_roiAlgTool.retrieve());
56  CHECK(m_neighKey.initialize());
59 
60  return StatusCode::SUCCESS;
61  }
62 
63 
64  StatusCode Egamma1_LArStrip_Fex_RowAware::execute(const EventContext& ctx) const {
65  // Read in a CaloCell container. Ask producers to create
66  // vectors of CaloCells to be examined.
67 
68  ATH_MSG_DEBUG ("Executing");
69 
71  if(!eventInfo.isValid()) {
72  ATH_MSG_ERROR ("Error obtaining EventInfo object");
73  return StatusCode::FAILURE;
74  }
75 
76  std::vector<const CaloCell*> cells;
77  CHECK(m_cellProducer->cells(cells, ctx));
78  ATH_MSG_DEBUG(cells.size() <<"Cells read in");
79 
80  std::vector<const xAOD::eFexEMRoI*> rois;
81  CHECK(m_roiAlgTool->RoIs(rois, ctx));
82  ATH_MSG_DEBUG(rois.size() << " RoI(s) read in");
83 
84  // find cells in the neighborhood of RoIs.
85  // A neighborhood is a collection of CellData objects which
86  // contain cell eta, phi and Et.
87 
88  auto neighborhoodTOBs = std::make_unique<IOBitwise::IeEmNbhoodTOBContainer>();
89  auto phimax = std::make_unique<std::vector<int>>();
90 
91  CHECK(findNeighborhoods_RowAware(rois, cells, *neighborhoodTOBs, *phimax));
92 
95 
97  if(m_dump || m_dumpTerse){
98  if (m_dump) {
99  CHECK(dumper.dump(name(), *eventInfo, *neighborhoodTOBs));
100  }
101 
102  if (m_dumpTerse) {
103  CHECK(dumper.dumpTerse(name(), *eventInfo, *neighborhoodTOBs));
104  }
105  }
106 
107  CHECK(h_neighborhoodTOBs.record(std::move(neighborhoodTOBs)));
108  CHECK(h_phimax.record(std::move(phimax)));
109 
110  return StatusCode::SUCCESS;
111  }
112 
113  StatusCode
114  Egamma1_LArStrip_Fex_RowAware::findNeighborhoods_RowAware(const std::vector<const xAOD::eFexEMRoI*>& rois,
115  const std::vector<const CaloCell*>& cells,
116  IOBitwise::IeEmNbhoodTOBContainer& neighborhoodTOBs,
117  std::vector<int>& phimax) const{
118 
119  for (const auto& roi : rois) {
120  CHECK(findNeighborhood_RowAware(roi, cells, neighborhoodTOBs, phimax));
121  }
122 
123  return StatusCode::SUCCESS;
124  }
125 
126 
127  StatusCode
129  const std::vector<const CaloCell*>& cells,
130  IOBitwise::IeEmNbhoodTOBContainer& neighborhoodTOBs,
131  std::vector<int>& phimax) const {
132 
133  // this member function constructs an LArStripNeighborhood.
134  //
135  // A neighourhood is constructed from StripData objects constructed
136  // from CalCells (strips) in the vicinity of an EM RoI the following manner:
137  //
138  // - the cell in the vicinity of the RoI is identified. The neighboorhood
139  // strips are the strups centered on the maximum energy strip.
140  //
141  // In more detail:
142  // A rectangular eta-phi subset of all strips is made.
143  // This subset constains the cells needed for the maximum energy search
144  // and for any subsequent neigborhood strip selection.
145  //
146  // The eta window for the initial selection ismade with half-width of
147  // 0.05 + 8.5* DeltaEta where DeltaEta = 0.003125, the nominal strip width
148  // in eta. A cut-oof off eta = +-1.4 is applied in the selection.
149  //
150  // Phi selection consists of calculating a phi index for the the RoI,
151  // then requiring selected strips to be have a phi indix within +=1 of
152  // the RoI phi index.
153  //
154  // The strips used to identigy the max energy strip the are within +-1 of the
155  // as the phi index of the RoI, and eta that lies within 0.1 in eta to the RoI.
156  //
157  // The strips selected for the Neighborhood have eta within +- 8.5 DeltaEta
158  // of the max energy strip, and +- 1 of the max RoI strip phi Index.
159 
160  auto cells_near_roi = std::vector<const CaloCell*>();
161 
162  ATH_MSG_DEBUG("roi eta " << roi->eta() << " phi " << roi->phi());
163 
164  // lambda function to calculate the phi index of a eta-phi point
165  auto phi_ind = [](const auto& c) {
166  constexpr double dphi = std::numbers::pi/32;
167  std::size_t iphi = 32 + int(std::floor(c->phi()/dphi));
168  return iphi > 63 ?
169  std::optional<std::size_t>() : std::make_optional(iphi);
170  };
171 
172  const std::optional<std::size_t> roi_phi_index_opt = phi_ind(roi);
173  if (not roi_phi_index_opt.has_value()) {
174  return StatusCode::FAILURE;
175  }
176  const std::size_t roi_phi_index = *roi_phi_index_opt;
177 
178  // obtain adjacent phi indices
179  auto roi_phi_indices = *wrap5(roi_phi_index);
180 
181  // container for strips close to RoI in eta
182  auto close = std::deque<std::vector<const CaloCell*>>(5);
183  for (auto& v :close) {v.reserve(100);}
184 
185  //One ROI is 0.1 wide in eta, this is the half width
186  constexpr double half_deta_roi{0.05};
187  //One cell in the barrel is 0.003125, this is the half width of the 17 cell window
188  constexpr double half_deta_neigh{8.5*0.003125};
189  //To define the ±eta limit of our window, we need to sum the above
190  constexpr double half_deta_fid{half_deta_roi + half_deta_neigh};
191 
192 
193  double etalim_low = std::max(roi->eta()-half_deta_fid, -1.4);
194  double etalim_high = std::min(roi->eta()+half_deta_fid, 1.4);
195 
196 
197  // double loop. outer: all strips. inner: adjacent roi indices.
198  for (const auto& cell : cells) {
199  auto icell = *phi_ind(cell);
200  std::size_t pos{0};
201  for(const auto& iroi : roi_phi_indices) {
202  auto c_eta = cell->eta();
203  if (iroi == icell and c_eta >= etalim_low and c_eta < etalim_high) {
204  close[pos].push_back(cell);
205  break;
206  }
207  ++pos;
208  }
209  }
210 
211  // select the cells within a a tower width of the RoI. Then find the
212  // cell in this selction with the highest energy
213  auto roi_cells = std::deque<std::vector<const CaloCell*>>(5);
215 
216  for (std::size_t i{0ul}; i != close.size(); ++i) {
217  roi_cells[i].reserve(close[i].size());
218  std::copy_if(std::begin(close[i]),
219  std::end(close[i]),
220  std::back_inserter(roi_cells[i]),
221  [&roi](const auto& c) {
222  return std::abs(c->eta() - roi->eta()) < half_deta_roi;
223  });
224  //Work out where the max is in the central block.
225  if(i > 0 && i < 4){
226  auto it = std::max_element(std::begin(roi_cells[i]),
227  std::end(roi_cells[i]),
228  [](const auto& l,const auto& r) {
229  return l->e() < r->e();
230  });
231  ATH_MSG_DEBUG("max cell row "
232  << i << " position "
233  << std::distance(std::begin(roi_cells[i]), it)
234  << " :" << **it);
235  roi_max_it.push_back(it);
236  }
237  }
238 
239  auto max_row = std::max_element(std::begin(roi_max_it),
240  std::end(roi_max_it),
241  [](const auto& l,const auto& r) {
242  return (*l)->e() < (*r)->e();
243  });
244 
245  int max_row_pos = std::distance( roi_max_it.begin(), max_row );
246 
247  phimax.push_back(max_row_pos);
248 
249  ATH_MSG_DEBUG("max cell row "
250  << ' ' << std::distance( roi_max_it.begin(), max_row )+1);
251 
252  //If the maximum is not in the centre row, we need to re-seed
253  switch(max_row_pos)
254  {
255  case 0:
256  {
257  close.pop_back();
258  close.pop_back();
259  break;
260  }
261  case 1:
262  {
263  close.pop_front();
264  close.pop_back();
265  break;
266  }
267  case 2:
268  {
269  close.pop_front();
270  close.pop_front();
271  break;
272  }
273  }
274 
275  ATH_MSG_DEBUG("popped ");
276 
277  // set up Cell containers for the neighborhood. One container
278  // per adjacent RoI phi indices.
279  auto neigh_cells = std::vector<std::vector<const CaloCell*>>(3);
280 
281  const CaloCell* max_cell{*(*max_row)};
282  const auto max_cell_eta = max_cell->eta();
283 
284  ATH_MSG_DEBUG("Got the max cell");
285 
286  for (std::size_t iv{0ul}; iv != close.size(); ++iv) {
287  std::copy_if(std::begin(close[iv]),
288  std::end(close[iv]),
289  std::back_inserter(neigh_cells[iv]),
290  [&max_cell_eta, &half_deta_neigh](const auto& c){
291  return abs(c->eta()-max_cell_eta) < half_deta_neigh;
292  });
293  }
294 
295  ATH_MSG_DEBUG("Made our neighbourhood");
296 
297  auto max_neigh_cell_it = std::find(std::begin(neigh_cells[1]),
298  std::end(neigh_cells[1]),
299  max_cell);
300  if (max_neigh_cell_it == std::end(neigh_cells[1])){
301  ATH_MSG_ERROR("Lost the max cell");
302  return StatusCode::FAILURE;
303  }
304 
305  auto max_neigh_cell_pos{std::distance(std::begin(neigh_cells[1]),
306  max_neigh_cell_it)};
307 
308  ATH_MSG_DEBUG("Rediscovered our neighbourhood max");
309 
310  auto toStripData = [](const auto& fromCells){
311  auto stripdata = std::vector<StripData>();
312  stripdata.reserve(fromCells.size());
313  std::transform(std::begin(fromCells),
314  std::end(fromCells),
315  back_inserter(stripdata),
316  [](const auto& c) {
317  return StripData(c->eta(),
318  c->phi(),
319  c->e());});
320  return stripdata;
321  };
322 
323  auto low = toStripData(neigh_cells[0]);
324  auto center = toStripData(neigh_cells[1]);
325  auto high = toStripData(neigh_cells[2]);
326 
327  Coords roi_c{roi->eta(), roi->phi()};
328  Coords cell_c{max_cell->eta(), max_cell->phi()};
329 
330  ATH_MSG_DEBUG("Fill with strip data");
331 
332  LArStripNeighborhood neighborhood = LArStripNeighborhood(low, center, high, roi_c, cell_c, max_neigh_cell_pos);
333 
334  neighborhoodTOBs.push_back(std::make_unique<IOBitwise::eEmNbhoodTOB>(*roi, neighborhood));
335 
336  return StatusCode::SUCCESS;
337  }
338 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
beamspotman.r
def r
Definition: beamspotman.py:672
GlobalSim::Egamma1_LArStrip_Fex_RowAware::execute
virtual StatusCode execute(const EventContext &) const override
Definition: Egamma1_LArStrip_Fex_RowAware.cxx:64
RunTileCalibRec.cells
cells
Definition: RunTileCalibRec.py:281
GlobalSim::Egamma1_LArStrip_Fex_RowAware::Egamma1_LArStrip_Fex_RowAware
Egamma1_LArStrip_Fex_RowAware(const std::string &name, ISvcLocator *pSvcLocator)
Definition: Egamma1_LArStrip_Fex_RowAware.cxx:46
GlobalSim::StripData
Definition: Global/GlobalSimulation/src/IO/StripData.h:16
GlobalSim::Egamma1_LArStrip_Fex_RowAware::findNeighborhood_RowAware
StatusCode findNeighborhood_RowAware(const xAOD::eFexEMRoI *, const std::vector< const CaloCell * > &, IOBitwise::IeEmNbhoodTOBContainer &, std::vector< int > &) const
Definition: Egamma1_LArStrip_Fex_RowAware.cxx:128
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
WriteCellNoiseToCool.icell
icell
Definition: WriteCellNoiseToCool.py:339
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
GlobalSim::Egamma1_LArStrip_Fex_RowAware::m_cellProducer
ToolHandle< ICaloCellsProducer > m_cellProducer
Definition: Egamma1_LArStrip_Fex_RowAware.h:48
Egamma1_LArStrip_Fex_RowAware.h
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
skel.it
it
Definition: skel.GENtoEVGEN.py:407
GlobalSim::Egamma1_LArStrip_Fex_RowAware::initialize
virtual StatusCode initialize() override
Definition: Egamma1_LArStrip_Fex_RowAware.cxx:51
CaloCell.h
GlobalSim::Coords
std::pair< double, double > Coords
Definition: LArStripNeighborhood.h:25
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:157
xAOD::eFexEMRoI_v1
Class describing a LVL1 eFEX EM region of interest.
Definition: eFexEMRoI_v1.h:33
GlobalSim::Egamma1_LArStrip_Fex_RowAware::findNeighborhoods_RowAware
StatusCode findNeighborhoods_RowAware(const std::vector< const xAOD::eFexEMRoI * > &, const std::vector< const CaloCell * > &, IOBitwise::IeEmNbhoodTOBContainer &, std::vector< int > &) const
Definition: Egamma1_LArStrip_Fex_RowAware.cxx:114
pi
#define pi
Definition: TileMuonFitter.cxx:65
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
GlobalSim::Egamma1_LArStrip_Fex_RowAware::m_phimaxKey
SG::WriteHandleKey< std::vector< int > > m_phimaxKey
Definition: Egamma1_LArStrip_Fex_RowAware.h:81
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
GlobalSim
AlgTool that to test whether expected the TIP values generated by data supplied by eEmMultTestBench c...
Definition: dump.h:8
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
GlobalSim::Egamma1_LArStrip_Fex_RowAware::m_neighKey
SG::WriteHandleKey< IOBitwise::IeEmNbhoodTOBContainer > m_neighKey
Definition: Egamma1_LArStrip_Fex_RowAware.h:74
lumiFormat.i
int i
Definition: lumiFormat.py:85
GlobalSim::Egamma1_LArStrip_Fex_RowAware::m_dump
Gaudi::Property< bool > m_dump
Definition: Egamma1_LArStrip_Fex_RowAware.h:61
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
AnalysisUtils::copy_if
Out copy_if(In first, const In &last, Out res, const Pred &p)
Definition: IFilterUtils.h:30
GlobalSim::Egamma1_LArStrip_Fex_RowAware::m_eventInfoKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
Definition: Egamma1_LArStrip_Fex_RowAware.h:41
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
detail::ul
unsigned long ul
Definition: PrimitiveHelpers.h:46
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DataVector
Derived DataVector<T>.
Definition: DataVector.h:795
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
GlobalSim::wrap5
std::optional< std::vector< std::size_t > > wrap5(std::size_t center)
Definition: Egamma1_LArStrip_Fex_RowAware.cxx:25
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
xAOD::eFexEMRoI_v1::eta
float eta() const
setter for the above
EventInfo.h
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
python.PyAthena.v
v
Definition: PyAthena.py:154
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
GlobalSim::Egamma1_LArStrip_Fex_RowAware::m_roiAlgTool
ToolHandle< eFexRoIAlgTool > m_roiAlgTool
Definition: Egamma1_LArStrip_Fex_RowAware.h:56
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
GlobalSim::LArStripNeighborhoodDumper
Definition: LArStripNeighborhoodDumper.h:14
TriggerTest.rois
rois
Definition: TriggerTest.py:23
GlobalSim::Egamma1_LArStrip_Fex_RowAware::m_dumpTerse
Gaudi::Property< bool > m_dumpTerse
Definition: Egamma1_LArStrip_Fex_RowAware.h:67
xAOD::eFexEMRoI_v1::phi
float phi() const
Seed supercell index within central tower (0 -> 3)
GlobalSim::LArStripNeighborhood
Class to hold windows of LAr strip cells in a the neighbourhood of a eFexRoI.
Definition: LArStripNeighborhood.h:37
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
python.compressB64.c
def c
Definition: compressB64.py:93
CaloCell::eta
virtual double eta() const override final
get eta (through CaloDetDescrElement)
Definition: CaloCell.h:382