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 = std::vector<std::vector<const CaloCell*>>(3);
174  for (auto& v :close) {v.reserve(100);}
175 
176 
177  constexpr double half_deta_roi{0.05};
178  constexpr double half_deta_neigh{8.5*0.0031};
179  constexpr double half_deta_fid{half_deta_roi + half_deta_neigh};
180 
181 
182  double etalim_low = std::max(roi->eta()-half_deta_fid, -1.4);
183  double etalim_high = std::min(roi->eta()+half_deta_fid, 1.4);
184 
185 
186  // double loop. outer: all strips. inner: adjacent roi indices.
187  for (const auto& cell : cells) {
188  auto icell = *phi_ind(cell);
189  std::size_t pos{0};
190  for(const auto& iroi : roi_phi_indices) {
191  auto c_eta = cell->eta();
192  if (iroi == icell and c_eta >= etalim_low and c_eta < etalim_high) {
193  close[pos].push_back(cell);
194  break;
195  }
196  ++pos;
197  }
198  }
199 
200 
201  for (const auto& v : close) {ATH_MSG_DEBUG("size close " << v.size());}
202 
203  // select the cells within a a tower width of the RoI. Then find the
204  // cell in this selction with the highest energy
205  auto roi_cells = std::vector<const CaloCell*> ();
206  roi_cells.reserve(close[1].size());
207  std::copy_if(std::begin(close[1]),
208  std::end(close[1]),
209  std::back_inserter(roi_cells),
210  [&roi](const auto& c) {
211  return std::abs(c->eta() - roi->eta()) < half_deta_roi;
212  });
213 
214 
215  auto it = std::max_element(std::begin(roi_cells),
216  std::end(roi_cells),
217  [](const auto& l,const auto& r) {
218  return l->e() < r->e();
219  });
220 
221  if (it == std::end(roi_cells)) {
222  ATH_MSG_ERROR("max_cell not found");
223  return StatusCode::FAILURE;
224  }
225 
226  ATH_MSG_DEBUG("max cell pos "
227  << std::distance(std::begin(roi_cells), it)
228  << ' ' << **it);
229 
230  // set up Cell containers for the neighborhood. One container
231  // per adjacent RoI phi indices.
232  auto neigh_cells = std::vector<std::vector<const CaloCell*>>(3);
233 
234  const CaloCell* max_cell{*it};
235  const auto max_cell_eta = max_cell->eta();
236 
237 
238  for (std::size_t iv{0ul}; iv != close.size(); ++iv) {
239  std::copy_if(std::begin(close[iv]),
240  std::end(close[iv]),
241  std::back_inserter(neigh_cells[iv]),
242  [&max_cell_eta, &half_deta_neigh](const auto& c){
243  return abs(c->eta()-max_cell_eta) < half_deta_neigh;
244  });
245  }
246 
247  auto max_neigh_cell_it = std::find(std::begin(neigh_cells[1]),
248  std::end(neigh_cells[1]),
249  max_cell);
250  if (max_neigh_cell_it == std::end(neigh_cells[1])){
251  ATH_MSG_ERROR("Lost the max cell");
252  return StatusCode::FAILURE;
253  }
254 
255  auto max_neigh_cell_pos{std::distance(std::begin(neigh_cells[1]),
256  max_neigh_cell_it)};
257 
258  auto toStripData = [](const auto& fromCells){
259  auto stripdata = std::vector<StripData>();
260  stripdata.reserve(fromCells.size());
261  std::transform(std::begin(fromCells),
262  std::end(fromCells),
263  back_inserter(stripdata),
264  [](const auto& c) {
265  return StripData(c->eta(),
266  c->phi(),
267  c->e());});
268  return stripdata;
269  };
270 
271  auto low = toStripData(neigh_cells[0]);
272  auto center = toStripData(neigh_cells[1]);
273  auto high = toStripData(neigh_cells[2]);
274 
275  Coords roi_c{roi->eta(), roi->phi()};
276  Coords cell_c{max_cell->eta(), max_cell->phi()};
277 
278 
279  neighborhoods.push_back(std::make_unique<LArStripNeighborhood>(low,
280  center,
281  high,
282  roi_c,
283  cell_c,
284  max_neigh_cell_pos));
285 
286  return StatusCode::SUCCESS;
287  }
288 
289  StatusCode
291  const LArStripNeighborhoodContainer& neighborhoods) const {
292 
293  std::ofstream out(name() + "_" +
294  std::to_string(eventInfo.eventNumber()) +
295  ".log");
296 
297  out << "run " << eventInfo.runNumber()
298  << " evt " << eventInfo.eventNumber()
299  << " is simulation " << std::boolalpha
301  << " weight " << eventInfo.mcEventWeight() << '\n';
302 
303  for (const auto& nbhd : neighborhoods) {
304  out << *nbhd << '\n';
305  }
306 
307  out.close();
308 
309  return StatusCode::SUCCESS;
310  }
311 
312  void dump_stripdataVector(const StripDataVector& sdv, std::ostream& os) {
313 
314  for(const auto& sd : sdv) {
315  os << sd.m_eta << ' ';
316  }
317  os << '\n';
318 
319 
320  for(const auto& sd : sdv) {
321  os << sd.m_phi << ' ';
322  }
323  os << '\n';
324 
325  for(const auto & sd : sdv) {
326  os << sd.m_e << ' ';
327  }
328  os << '\n';
329  os << '\n';
330  }
331 
333  std::ostream& os){
334  dump_stripdataVector(n->phi_low(), os);
335  dump_stripdataVector(n->phi_center(), os);
336  dump_stripdataVector(n->phi_high(), os);
337  }
338 
339  StatusCode
341  const LArStripNeighborhoodContainer& neighborhoods) const {
342 
343  std::ofstream out(name() + "_" +
344  std::to_string(eventInfo.eventNumber()) +
345  "_terse.log");
346  out << "run " << eventInfo.runNumber()
347  << " evt " << eventInfo.eventNumber()
348  << " is simulation " << std::boolalpha
350  << " weight " << eventInfo.mcEventWeight() << '\n';
351 
352  for (const auto& n : neighborhoods) {dump_n(n, out);}
353 
354 
355  out.close();
356 
357  return StatusCode::SUCCESS;
358  }
359 }
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
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
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
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:340
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: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
GlobalSim::dump_stripdataVector
void dump_stripdataVector(const StripDataVector &sdv, std::ostream &os)
Definition: Egamma1_LArStrip_Fex.cxx:312
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Egamma1_LArStrip_Fex.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
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:290
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:332
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.