ATLAS Offline Software
Egamma1_LArStrip_Fex.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 /*
6  This algorithm outputs Calorimeter strip data in the region of
7  eFex RoIs.
8 */
9 
10 #include "Egamma1_LArStrip_Fex.h"
11 #include "CaloEvent/CaloCell.h"
12 
14 
15 #include <fstream>
16 #include <vector>
17 #include <algorithm>
18 #include <optional>
19 
20 namespace GlobalSim {
21 
22  std::optional<std::vector<std::size_t>> wrap3(std::size_t center) {
23  if (center > 63) {
24  return std::optional<std::vector<std::size_t>>{};
25  }
26 
27  if (center == 63) {
28  return std::make_optional(std::vector<std::size_t>({62ul, 63ul, 0ul}));
29  }
30 
31  if (center == 0) {
32  return std::make_optional(std::vector<std::size_t>({63ul, 0ul, 1ul}));
33  }
34 
35  return std::make_optional(std::vector<std::size_t>(
36  {center-1,
37  center,
38  center+1}));
39  }
40 
41  Egamma1_LArStrip_Fex::Egamma1_LArStrip_Fex(const std::string& name, ISvcLocator* pSvcLocator ) :
42  AthReentrantAlgorithm(name, pSvcLocator){
43  }
44 
45 
47  ATH_MSG_INFO ("Initializing " << name());
48 
49  CHECK(m_cellProducer.retrieve());
50  CHECK(m_roiAlgTool.retrieve());
51  CHECK(m_neighKey.initialize());
53 
54 
55  return StatusCode::SUCCESS;
56  }
57 
58 
59  StatusCode Egamma1_LArStrip_Fex::execute(const EventContext& ctx) const {
60  // Read in a CaloCell container. Ask producers to create
61  // vectors of CaloCells to be examined.
62 
63  ATH_MSG_DEBUG ("Executing");
64 
66  if(!eventInfo.isValid()) {
67  ATH_MSG_ERROR ("Error obtaining EventInfo object");
68  return StatusCode::FAILURE;
69  }
70 
71  std::vector<const CaloCell*> cells;
72  CHECK(m_cellProducer->cells(cells, ctx));
73  ATH_MSG_DEBUG(cells.size() <<" cells read in");
74 
75  std::vector<const xAOD::eFexEMRoI*> rois;
76  CHECK(m_roiAlgTool->RoIs(rois, ctx));
77  ATH_MSG_DEBUG(rois.size() << " RoI(s) read in");
78 
79  // find cells in the neighborhood of RoIs.
80  // A neighborhood is a collection of CellData objects which
81  // contain cell eta, phi and Et.
82 
83  auto neighborhoods = std::make_unique<LArStripNeighborhoodContainer>();
84 
85  CHECK(findNeighborhoods(rois, cells, *neighborhoods));
86 
88 
89  if (m_dump) {
90  CHECK(dump(*eventInfo, *neighborhoods));
91  }
92 
93  if (m_dumpTerse) {
94  CHECK(dumpTerse(*eventInfo, *neighborhoods));
95  }
96 
97 
98  CHECK(h_write.record(std::move(neighborhoods)));
99 
100  ATH_MSG_INFO(evtStore()->dump());
101 
102  return StatusCode::SUCCESS;
103  }
104 
105  StatusCode
106  Egamma1_LArStrip_Fex::findNeighborhoods(const std::vector<const xAOD::eFexEMRoI*>& rois,
107  const std::vector<const CaloCell*>& cells,
108  LArStripNeighborhoodContainer& neighborhoods) const{
109 
110  for (const auto& roi : rois) {
111  CHECK(findNeighborhood(roi, cells, neighborhoods));
112  }
113 
114  return StatusCode::SUCCESS;
115  }
116 
117 
118  StatusCode
120  const std::vector<const CaloCell*>& cells,
121  LArStripNeighborhoodContainer& neighborhoods) const {
122 
123  // this member function constructs an LArStripNeighborhood.
124  //
125  // A neighourhood is constructed from StripData objects constructed
126  // from CalCells (strips) in the vicinity of an EM RoI the following manner:
127  //
128  // - the cell in the vicinity of the RoI is identified. The neighboorhood
129  // strips are the strups centered on the maximum energy strip.
130  //
131  // In more detail:
132  // A rectangular eta-phi subset of all strips is made.
133  // This subset constains the cells needed for the maximum energy search
134  // and for any subsequent neigborhood strip selection.
135  //
136  // The eta window for the initial selection ismade with half-width of
137  // 0.05 + 8.5* DeltaEta where DeltaEta = 0.0031, the nominal strip width
138  // in eta. A cut-oof off eta = +-1.4 is applied in the selection.
139  //
140  // Phi selection consists of calculating a phi index for the the RoI,
141  // then requiring selected strips to be have a phi indix within +=1 of
142  // the RoI phi index.
143  //
144  // The strips used to identigy the max energy strip have the same phi index
145  // as the RoI, and eta that lies witun 0.1 in eta to the RoI.
146  //
147  // The strips selected for the Neighborhood have eta within +- 8.5 DeltaEta
148  // of the max energy strip, and +- 1 of the RoI strip phi Index.
149 
150 
151 
152 
153  auto cells_near_roi = std::vector<const CaloCell*>();
154 
155  // lambda function to calculate the phi index of a eta-phi point
156  auto phi_ind = [](const auto& c) {
157  constexpr double dphi = std::numbers::pi/32;
158  std::size_t iphi = 32 + int(std::floor(c->phi()/dphi));
159  return iphi > 63 ?
160  std::optional<std::size_t>() : std::make_optional(iphi);
161  };
162 
163  // calculate roi phi index
164  auto roi_phi_index = *phi_ind(roi);
165 
166  // obtain adjacent phi indices
167  auto roi_phi_indices = *wrap3(roi_phi_index);
168  for (const auto& i : roi_phi_indices) {
169  ATH_MSG_DEBUG("roi index " << i);
170  }
171 
172  // container for strips close to RoI in eta
173  auto close =
174  std::vector<std::vector<const CaloCell*>>(3,
175  std::vector<const CaloCell*>());
176  for (auto& v :close) {v.reserve(100);}
177 
178 
179  constexpr double half_deta_roi{0.05};
180  constexpr double half_deta_neigh{8.5*0.0031};
181  constexpr double half_deta_fid{half_deta_roi + half_deta_neigh};
182 
183 
184  double etalim_low = std::max(roi->eta()-half_deta_fid, -1.4);
185  double etalim_high = std::min(roi->eta()+half_deta_fid, 1.4);
186 
187 
188  // double loop. outer: all strips. inner: adjacent roi indices.
189  for (const auto& cell : cells) {
190  auto icell = *phi_ind(cell);
191  std::size_t pos{0};
192  for(const auto& iroi : roi_phi_indices) {
193  auto c_eta = cell->eta();
194  if (iroi == icell and c_eta >= etalim_low and c_eta < etalim_high) {
195  close[pos].push_back(cell);
196  break;
197  }
198  ++pos;
199  }
200  }
201 
202 
203  for (const auto& v : close) {ATH_MSG_DEBUG("size close " << v.size());}
204 
205  // select the cells within a a tower width of the RoI. Then find the
206  // cell in this selction with the highest energy
207  auto roi_cells = std::vector<const CaloCell*> ();
208  roi_cells.reserve(close[1].size());
209  std::copy_if(std::begin(close[1]),
210  std::end(close[1]),
211  std::back_inserter(roi_cells),
212  [&roi](const auto& c) {
213  return std::abs(c->eta() - roi->eta()) < half_deta_roi;
214  });
215 
216 
217  auto it = std::max_element(std::begin(roi_cells),
218  std::end(roi_cells),
219  [](const auto& l,const auto& r) {
220  return l->e() < r->e();
221  });
222 
223  if (it == std::end(roi_cells)) {
224  ATH_MSG_ERROR("max_cell not found");
225  return StatusCode::FAILURE;
226  }
227 
228  ATH_MSG_DEBUG("max cell pos "
229  << std::distance(std::begin(roi_cells), it)
230  << ' ' << **it);
231 
232  // set up Cell containers for the neighborhood. One container
233  // per adjacent RoI phi indices.
234  auto neigh_cells =
235  std::vector<std::vector<const CaloCell*>>(3,
236  std::vector<const CaloCell*>());
237 
238 
239  const CaloCell* max_cell{*it};
240  const auto max_cell_eta = max_cell->eta();
241 
242 
243  for (std::size_t iv{0ul}; iv != close.size(); ++iv) {
244  std::copy_if(std::begin(close[iv]),
245  std::end(close[iv]),
246  std::back_inserter(neigh_cells[iv]),
247  [&max_cell_eta, &half_deta_neigh](const auto& c){
248  return abs(c->eta()-max_cell_eta) < half_deta_neigh;
249  });
250  }
251 
252  auto max_neigh_cell_it = std::find(std::begin(neigh_cells[1]),
253  std::end(neigh_cells[1]),
254  max_cell);
255  if (max_neigh_cell_it == std::end(neigh_cells[1])){
256  ATH_MSG_ERROR("Lost the max cell");
257  return StatusCode::FAILURE;
258  }
259 
260  auto max_neigh_cell_pos{std::distance(std::begin(neigh_cells[1]),
261  max_neigh_cell_it)};
262 
263  auto toStripData = [](const auto& fromCells){
264  auto stripdata = std::vector<StripData>();
265  stripdata.reserve(fromCells.size());
266  std::transform(std::begin(fromCells),
267  std::end(fromCells),
268  back_inserter(stripdata),
269  [](const auto& c) {
270  return StripData(c->eta(),
271  c->phi(),
272  c->e());});
273  return stripdata;
274  };
275 
276  auto low = toStripData(neigh_cells[0]);
277  auto center = toStripData(neigh_cells[1]);
278  auto high = toStripData(neigh_cells[2]);
279 
280  Coords roi_c{roi->eta(), roi->phi()};
281  Coords cell_c{max_cell->eta(), max_cell->phi()};
282 
283 
284  neighborhoods.push_back(std::make_unique<LArStripNeighborhood>(low,
285  center,
286  high,
287  roi_c,
288  cell_c,
289  max_neigh_cell_pos));
290 
291  return StatusCode::SUCCESS;
292  }
293 
294  StatusCode
296  const LArStripNeighborhoodContainer& neighborhoods) const {
297 
298  std::ofstream out(name() + "_" +
299  std::to_string(eventInfo.eventNumber()) +
300  ".log");
301 
302  out << "run " << eventInfo.runNumber()
303  << " evt " << eventInfo.eventNumber()
304  << " is simulation " << std::boolalpha
306  << " weight " << eventInfo.mcEventWeight() << '\n';
307 
308  for (const auto& nbhd : neighborhoods) {
309  out << *nbhd << '\n';
310  }
311 
312  out.close();
313 
314  return StatusCode::SUCCESS;
315  }
316 
317  void dump_stripdataVector(const StripDataVector& sdv, std::ostream& os) {
318 
319  for(const auto& sd : sdv) {
320  os << sd.m_eta << ' ';
321  }
322  os << '\n';
323 
324 
325  for(const auto& sd : sdv) {
326  os << sd.m_phi << ' ';
327  }
328  os << '\n';
329 
330  for(const auto & sd : sdv) {
331  os << sd.m_e << ' ';
332  }
333  os << '\n';
334  os << '\n';
335  }
336 
338  std::ostream& os){
339  dump_stripdataVector(n->phi_low(), os);
340  dump_stripdataVector(n->phi_center(), os);
341  dump_stripdataVector(n->phi_high(), os);
342  }
343 
344  StatusCode
346  const LArStripNeighborhoodContainer& neighborhoods) const {
347 
348  std::ofstream out(name() + "_" +
349  std::to_string(eventInfo.eventNumber()) +
350  "_terse.log");
351  out << "run " << eventInfo.runNumber()
352  << " evt " << eventInfo.eventNumber()
353  << " is simulation " << std::boolalpha
355  << " weight " << eventInfo.mcEventWeight() << '\n';
356 
357  for (const auto& n : neighborhoods) {dump_n(n, out);}
358 
359 
360  out.close();
361 
362  return StatusCode::SUCCESS;
363  }
364 }
beamspotman.r
def r
Definition: beamspotman.py:676
GlobalSim::wrap3
std::optional< std::vector< std::size_t > > wrap3(std::size_t center)
Definition: Egamma1_LArStrip_Fex.cxx:22
RunTileCalibRec.cells
cells
Definition: RunTileCalibRec.py:271
GlobalSim::StripData
Definition: Global/GlobalSimulation/src/IO/StripData.h:16
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
max
#define max(a, b)
Definition: cfImp.cxx:41
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
xAOD::EventInfo_v1::eventNumber
uint64_t eventNumber() const
The current event's event number.
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
GlobalSim::Egamma1_LArStrip_Fex::m_cellProducer
ToolHandle< ICaloCellsProducer > m_cellProducer
Definition: Egamma1_LArStrip_Fex.h:45
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
skel.it
it
Definition: skel.GENtoEVGEN.py:396
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
GlobalSim::Egamma1_LArStrip_Fex::initialize
virtual StatusCode initialize() override
Definition: Egamma1_LArStrip_Fex.cxx:46
CaloCell.h
GlobalSim::Coords
std::pair< double, double > Coords
Definition: LArStripNeighborhood.h:26
GlobalSim::Egamma1_LArStrip_Fex::dumpTerse
StatusCode dumpTerse(const xAOD::EventInfo &eventInfo, const LArStripNeighborhoodContainer &) const
Definition: Egamma1_LArStrip_Fex.cxx:345
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
xAOD::eFexEMRoI_v1
Class describing a LVL1 eFEX EM region of interest.
Definition: eFexEMRoI_v1.h:33
GlobalSim::Egamma1_LArStrip_Fex::findNeighborhood
StatusCode findNeighborhood(const xAOD::eFexEMRoI *, const std::vector< const CaloCell * > &, LArStripNeighborhoodContainer &) const
Definition: Egamma1_LArStrip_Fex.cxx:119
xAOD::EventInfo_v1::IS_SIMULATION
@ IS_SIMULATION
true: simulation, false: data
Definition: EventInfo_v1.h:151
xAOD::EventInfo_v1::runNumber
uint32_t runNumber() const
The current event's run number.
pi
#define pi
Definition: TileMuonFitter.cxx:65
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
GlobalSim::Egamma1_LArStrip_Fex::m_neighKey
SG::WriteHandleKey< LArStripNeighborhoodContainer > m_neighKey
Definition: Egamma1_LArStrip_Fex.h:72
python.selector.AtlRunQuerySelectorLhcOlc.sd
sd
Definition: AtlRunQuerySelectorLhcOlc.py:612
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
GlobalSim
AlgTool to obtain a selection of eFex RoIs read in from the event store.
Definition: dump.h:8
GlobalSim::Egamma1_LArStrip_Fex::m_dump
Gaudi::Property< bool > m_dump
Definition: Egamma1_LArStrip_Fex.h:59
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
beamspotman.n
n
Definition: beamspotman.py:731
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
GlobalSim::Egamma1_LArStrip_Fex::m_eventInfoKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
Definition: Egamma1_LArStrip_Fex.h:37
GlobalSim::Egamma1_LArStrip_Fex::Egamma1_LArStrip_Fex
Egamma1_LArStrip_Fex(const std::string &name, ISvcLocator *pSvcLocator)
Definition: Egamma1_LArStrip_Fex.cxx:41
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
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:45
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
GlobalSim::dump_stripdataVector
void dump_stripdataVector(const StripDataVector &sdv, std::ostream &os)
Definition: Egamma1_LArStrip_Fex.cxx:317
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
min
#define min(a, b)
Definition: cfImp.cxx:40
Egamma1_LArStrip_Fex.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
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
GlobalSim::Egamma1_LArStrip_Fex::m_dumpTerse
Gaudi::Property< bool > m_dumpTerse
Definition: Egamma1_LArStrip_Fex.h:65
EventInfo.h
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
python.PyAthena.v
v
Definition: PyAthena.py:154
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
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
TriggerTest.rois
rois
Definition: TriggerTest.py:23
GlobalSim::Egamma1_LArStrip_Fex::findNeighborhoods
StatusCode findNeighborhoods(const std::vector< const xAOD::eFexEMRoI * > &, const std::vector< const CaloCell * > &, LArStripNeighborhoodContainer &) const
Definition: Egamma1_LArStrip_Fex.cxx:106
GlobalSim::Egamma1_LArStrip_Fex::dump
StatusCode dump(const xAOD::EventInfo &eventInfo, const LArStripNeighborhoodContainer &) const
Definition: Egamma1_LArStrip_Fex.cxx:295
xAOD::EventInfo_v1::mcEventWeight
float mcEventWeight(size_t i=0) const
The weight of one specific MC event used in the simulation.
Definition: EventInfo_v1.cxx:203
xAOD::eFexEMRoI_v1::phi
float phi() const
Seed supercell index within central tower (0 -> 3)
GlobalSim::Egamma1_LArStrip_Fex::m_roiAlgTool
ToolHandle< eFexRoIAlgTool > m_roiAlgTool
Definition: Egamma1_LArStrip_Fex.h:54
GlobalSim::LArStripNeighborhood
Definition: LArStripNeighborhood.h:28
GlobalSim::StripDataVector
std::vector< StripData > StripDataVector
Definition: LArStripNeighborhood.h:24
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
GlobalSim::dump_n
void dump_n(const LArStripNeighborhood *n, std::ostream &os)
Definition: Egamma1_LArStrip_Fex.cxx:337
GlobalSim::Egamma1_LArStrip_Fex::execute
virtual StatusCode execute(const EventContext &) const override
Definition: Egamma1_LArStrip_Fex.cxx:59
xAOD::EventInfo_v1::eventType
bool eventType(EventType type) const
Check for one particular bitmask value.