ATLAS Offline Software
CaloClusterROIPhiRZContainerMaker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3  */
4 
7 
10 
12 #include "TrkSurfaces/Surface.h"
13 
14 
15 #include <stdexcept>
16 #include <algorithm>
17 #include <cstdint>
18 
19 namespace {
20  constexpr float PI_F = static_cast<float>(M_PI);
21 }
22 
23 namespace InDet {
25  ISvcLocator* pSvcLocator):
26  AthReentrantAlgorithm(name, pSvcLocator)
27 {
28 }
29 
30 // ================================================================
32 = default;
33 
34 // =================================================================
36 {
38  ATH_CHECK( m_calosurf.retrieve() );
40 
41  if (m_outputClusterContainerName.empty()) {
42  ATH_MSG_FATAL( "No OutputROIContainerName given.");
43  return StatusCode::FAILURE;
44  }
46  ATH_MSG_FATAL( "Too many OutputROIContainerNames given.");
47  return StatusCode::FAILURE;
48  }
49  if (m_minPtEm.size() != m_phiWidth.size() || m_minPtEm.size() != m_outputClusterContainerName.size() ) {
50  ATH_MSG_FATAL( "Number of entries in minPt, phiWidth must match number of entries in OutputROIContainerName.");
51  return StatusCode::FAILURE;
52  }
53  m_outputIndex.reserve(m_minPtEm.size());
55  for (unsigned int idx=0; idx<m_minPtEm.size(); ++idx) {
56  m_outputIndex.push_back(idx);
58  }
59  std::sort(m_outputIndex.begin(),m_outputIndex.end(), [this](unsigned int idx_a, unsigned int idx_b) { return this->m_minPtEm[idx_a] < this->m_minPtEm[idx_b];});
60  m_sortedMinPtEm.reserve( m_outputIndex.size());
61  for (unsigned int idx : m_outputIndex) {
62  m_sortedMinPtEm.push_back( m_minPtEm[idx] );
63  }
64 
65  m_allClusters=0;
67 
70  m_outputSorted.reserve( m_outputIndex.size() );
71  m_outputUnsorted.reserve( m_outputIndex.size() );
72  for (unsigned int output_i=0; output_i<m_outputIndex.size(); ++output_i) {
73  if (m_phiWidth[m_outputIndex[output_i]]>0.) {
74  m_outputSorted.push_back(output_i);
75  }
76  else {
77  m_outputUnsorted.push_back(output_i);
78  }
79  ATH_MSG_DEBUG( "ROIPhiRZ container " << m_outputClusterContainerName[ m_outputIndex[output_i] ]
80  << " : " << m_minPtEm[m_outputIndex[output_i] ] << " MeV " << ( m_phiWidth[m_outputIndex[output_i]]>0. ? " order by phi " : " unordered" ) );
81  }
82  return StatusCode::SUCCESS;
83 }
84 
85 
86 
87 // ====================================================================
89 {
90  //
91  // finalize method
92  //
93  ATH_MSG_DEBUG ("AllClusters " << m_allClusters << " selected " << m_selectedClusters << " max ROIs per event " << m_maxNROIs);
94 
95  return StatusCode::SUCCESS;
96 }
97 
98 // ======================================================================
100 {
101 
102  if (m_inputClusterContainerName.key().empty()) {
103  return StatusCode::SUCCESS;
104  }
105 
106  // retrieve cluster containers, return `failure' if not existing
108  ATH_CHECK(inputClusterContainer.isValid());
109 
111  ATH_CHECK(caloMgrHandle.isValid());
112  const CaloDetDescrManager *caloMgr = caloMgrHandle.cptr();
113 
114  unsigned int all_clusters{};
115  unsigned int selected_clusters{};
116  ROIPhiRZContainer rois; // temporary ROI container
117  std::vector<unsigned int > n_rois; // number of ROIs per output container
118  n_rois.resize(m_outputIndex.size(),0);
119 
120  std::vector<uint8_t > max_output;// the outputs are ordered by the pt-cut, this is the index of the last output which passed the pt-cut per ROI
121  rois.reserve( inputClusterContainer->size());
122  max_output.resize(inputClusterContainer->size());
123 
124  // create ROIs.
125  // first they are only stored in the temporary container
126  for(const xAOD::CaloCluster* cluster : *inputClusterContainer )
127  {
128  all_clusters++;
129  if (m_egammaCaloClusterSelector->passSelection(cluster,*caloMgr))
130  {
131  selected_clusters++;
132  addROI(*cluster, *caloMgr, rois, max_output, n_rois);
133  }
134  }
135  // This may happen if a ROI close to +-pi gets duplicated...
136  // so don't warn. See ATLASRECTS-7160.
137  //if (rois.size() > inputClusterContainer->size() ) {
138  // ATH_MSG_INFO( "Did not reserve enough storage for " << m_outputClusterContainerName[m_outputIndex[0]].key() );
139  //}
140 
141 
142  // create ROI output container
143  std::vector< SG::WriteHandle<ROIPhiRZContainer> > output_rois;
144  output_rois.reserve(m_outputIndex.size());
145  for (unsigned int output_idx : m_outputIndex) {
146  unsigned int the_size = n_rois[output_rois.size()];
147  output_rois.emplace_back( m_outputClusterContainerName[output_idx], ctx);
148  ATH_CHECK( output_rois.back().record( std::make_unique<ROIPhiRZContainer>() ) );
149  output_rois.back()->reserve( the_size);
150  }
151 
152  if (!m_outputSorted.empty()) {
153  // sort ROIs by phi
154  std::vector<unsigned int> roi_order;
155  roi_order.reserve( rois.size() );
156  for (unsigned int idx=0; idx< rois.size(); ++idx) { roi_order.push_back( idx ); }
157  std::sort(roi_order.begin(),roi_order.end(),[&rois](unsigned int a, unsigned int b) { return rois[a][0] < rois[b][0]; });
158  // copy ROIs in sort order to output container which are to be sorted
159  for (unsigned int roi_i : roi_order) {
160  for (unsigned int output_i : m_outputSorted) {
161  if (output_i>=max_output[roi_i]) break;
162  output_rois[output_i]->push_back( rois[ roi_i ] );
163  }
164  }
165  }
166 
167  // copy ROIs in original order to output container which should have the original order
168  // also remove duplicates
169  if (!m_outputUnsorted.empty()) {
170  for (unsigned int roi_unordered_i=0; roi_unordered_i < rois.size(); ++roi_unordered_i) {
171  for (unsigned int output_i : m_outputUnsorted) {
172  if (output_i>=max_output[roi_unordered_i]) break;
173  if (std::abs(rois[ roi_unordered_i ][0])<PI_F or (rois[ roi_unordered_i ][0] == PI_F)) {
174  output_rois[output_i]->push_back( rois[ roi_unordered_i ] );
175  }
176  }
177  }
178  }
179 
180  // gather statistics
181  {
182  unsigned int max_size;
183  do {
184  max_size = m_maxNROIs;
185  } while (rois.size()>max_size && ! m_maxNROIs.compare_exchange_weak(max_size, rois.size()));
186  }
187  m_allClusters += all_clusters;
188  m_selectedClusters += selected_clusters;
189  return StatusCode::SUCCESS;
190 }
191 
193  const Trk::Surface &surf)
194 {
195 
196  Amg::Vector3D surfRefPoint = surf.globalReferencePoint();
197 
198  double eta = cluster.eta();
199  double theta = 2 * atan(exp(-eta)); // -log(tan(theta/2));
200  double tantheta = tan(theta);
201  double phi = cluster.phi();
202 
203  if (xAOD::EgammaHelpers::isBarrel(&cluster)) {
204  // Two corindate in a cyclinder are
205  // Trk::locRPhi = 0 (ie phi)
206  // Trk::locZ = 1(ie z)
207  double r = surfRefPoint.perp();
208  double z = tantheta == 0 ? 0. : r / tantheta;
212  } else {
213  // Local paramters of a disk are
214  // Trk::locR = 0
215  // Trk::locPhi = 1
216  double z = surfRefPoint.z();
217  double r = z * tantheta;
221  }
222 }
223 
224 
226  const CaloDetDescrManager &caloDDMgr,
227  ROIPhiRZContainer &output_rois,
228  std::vector<uint_fast8_t> &max_output,
229  std::vector<unsigned int> &n_rois) const {
230 
231  double energy = cluster.e();
232 
233  // do we want to make energy be EM energy only?
234  if (m_EMEnergyOnly) {
235  static const SG::AuxElement::ConstAccessor<float> acc("EMFraction");
236  double emFrac(0.);
237  if (acc.isAvailable(cluster)) {
238  emFrac = acc(cluster);
240  emFrac)) {
241  ATH_MSG_ERROR("EM energy requested, but No EM fraction momement stored");
242  return;
243  }
244  energy *= emFrac;
245  }
246 
247  std::unique_ptr<const Trk::Surface> surface( getCaloSurface(cluster, caloDDMgr) );
248  if (!surface) {
249  ATH_MSG_ERROR( "Failed to create surface for cluster");
250  return;
251  }
252 
253  const Trk::LocalParameters localParams( getClusterLocalParameters(cluster, *surface) );
254 
255  Amg::Vector3D global_position( surface->localToGlobal( localParams) );
256  double et = energy * std::sin(global_position.theta());
257  if ( et >= m_sortedMinPtEm[0]){
258  unsigned int roi_idx=output_rois.size();
259  output_rois.addROI(global_position, m_maxPhiWidth);
260 
261  unsigned int n_duplicates = output_rois.size()-roi_idx-1;
262  if (n_duplicates>0) {
263  m_duplicateROI += n_duplicates;
264  }
265 
266  unsigned int output_idx=0;
267  for ( ; output_idx<m_outputIndex.size(); ++output_idx) {
268  if (et < m_sortedMinPtEm[output_idx]) break;
269  n_rois[output_idx] += n_duplicates+1;
270  }
271  // addROI may duplicate the ROI at phi - 2 pi
272  // So, have to set the last output_idx for all newly added ROIs
273  if (max_output.size() < output_rois.size()) {
274  max_output.resize (output_rois.size());
275  }
276  for (; roi_idx < output_rois.size(); ++roi_idx) {
277  max_output[roi_idx]=output_idx;
278  }
279 
280  }
281  else {
282  ATH_MSG_DEBUG("Skip selected cluster " << energy << " * " << std::sin(global_position.theta()) << " = " << energy * std::sin(global_position.theta())<< " >= " << m_sortedMinPtEm[0] );
283  }
284 }
285 }
xAOD::CaloCluster_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition: CaloCluster_v1.cxx:256
beamspotman.r
def r
Definition: beamspotman.py:676
Trk::LocalParameters
Definition: LocalParameters.h:98
InDet::CaloClusterROIPhiRZContainerMaker::m_minPtEm
Gaudi::Property< std::vector< float > > m_minPtEm
Definition: CaloClusterROIPhiRZContainerMaker.h:97
et
Extra patterns decribing particle interation process.
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
InDet::CaloClusterROIPhiRZContainerMaker::m_caloMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Name of the CaloDetDescrManager condition object.
Definition: CaloClusterROIPhiRZContainerMaker.h:80
InDet::CaloClusterROIPhiRZContainerMaker::m_outputClusterContainerName
SG::WriteHandleKeyArray< ROIPhiRZContainer > m_outputClusterContainerName
Name of the ROI output collection.
Definition: CaloClusterROIPhiRZContainerMaker.h:74
InDet::CaloClusterROIPhiRZContainerMaker::m_maxNROIs
std::atomic_uint m_maxNROIs
Definition: CaloClusterROIPhiRZContainerMaker.h:108
max
#define max(a, b)
Definition: cfImp.cxx:41
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
Surface.h
InDet::CaloClusterROIPhiRZContainerMaker::m_selectedClusters
std::atomic_uint m_selectedClusters
Definition: CaloClusterROIPhiRZContainerMaker.h:106
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
ROIPhiRZContainer
container for phi sorted ROIs defined by phi, r and z.
Definition: ROIPhiRZContainer.h:50
InDet
Primary Vertex Finder.
Definition: VP1ErrorUtils.h:36
Trk::locRPhi
@ locRPhi
Definition: ParamDefs.h:40
M_PI
#define M_PI
Definition: ActiveFraction.h:11
InDet::CaloClusterROIPhiRZContainerMaker::m_egammaCaloClusterSelector
ToolHandle< IegammaCaloClusterSelector > m_egammaCaloClusterSelector
Tool to filter the calo clusters.
Definition: CaloClusterROIPhiRZContainerMaker.h:88
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
InDet::CaloClusterROIPhiRZContainerMaker::m_maxPhiWidth
float m_maxPhiWidth
Definition: CaloClusterROIPhiRZContainerMaker.h:103
Trk::locR
@ locR
Definition: ParamDefs.h:44
Trk::Surface::globalReferencePoint
virtual const Amg::Vector3D & globalReferencePoint() const
Returns a global reference point on the surface, for PlaneSurface, StraightLineSurface,...
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
InDet::CaloClusterROIPhiRZContainerMaker::getClusterLocalParameters
static Trk::LocalParameters getClusterLocalParameters(const xAOD::CaloCluster &cluster, const Trk::Surface &surf)
Definition: CaloClusterROIPhiRZContainerMaker.cxx:192
InDet::CaloClusterROIPhiRZContainerMaker::execute
StatusCode execute(const EventContext &ctx) const override
Definition: CaloClusterROIPhiRZContainerMaker.cxx:99
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
InDet::CaloClusterROIPhiRZContainerMaker::finalize
StatusCode finalize() override
Definition: CaloClusterROIPhiRZContainerMaker.cxx:88
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
Trk::DefinedParameter
std::pair< double, ParamDefs > DefinedParameter
Definition: DefinedParameter.h:27
InDet::CaloClusterROIPhiRZContainerMaker::m_sortedMinPtEm
std::vector< float > m_sortedMinPtEm
Definition: CaloClusterROIPhiRZContainerMaker.h:102
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
xAOD::EgammaHelpers::isBarrel
bool isBarrel(const xAOD::Egamma *eg)
return true if the cluster is in the barrel
Definition: EgammaxAODHelpers.cxx:33
InDet::CaloClusterROIPhiRZContainerMaker::m_outputUnsorted
std::vector< unsigned int > m_outputUnsorted
Definition: CaloClusterROIPhiRZContainerMaker.h:101
InDet::CaloClusterROIPhiRZContainerMaker::addROI
void addROI(const xAOD::CaloCluster &cluster, const CaloDetDescrManager &caloDDMgr, ROIPhiRZContainer &output_rois, std::vector< uint_fast8_t > &max_output, std::vector< unsigned int > &n_rois) const
Definition: CaloClusterROIPhiRZContainerMaker.cxx:225
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
EgammaxAODHelpers.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Trk::locZ
@ locZ
local cylindrical
Definition: ParamDefs.h:42
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
xAOD::CaloCluster_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: CaloCluster_v1.cxx:251
InDet::CaloClusterROIPhiRZContainerMaker::m_outputIndex
std::vector< unsigned int > m_outputIndex
Definition: CaloClusterROIPhiRZContainerMaker.h:99
CaloCluster.h
z
#define z
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
InDet::CaloClusterROIPhiRZContainerMaker::m_duplicateROI
std::atomic_uint m_duplicateROI
Definition: CaloClusterROIPhiRZContainerMaker.h:107
ROIPhiRZContainer::addROI
void addROI(const Amg::Vector3D &global_position, float roi_phi_width)
Definition: ROIPhiRZContainer.h:63
AthenaPoolTestRead.acc
acc
Definition: AthenaPoolTestRead.py:16
InDet::CaloClusterROIPhiRZContainerMaker::initialize
StatusCode initialize() override
Definition: CaloClusterROIPhiRZContainerMaker.cxx:35
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::CaloCluster_v1::retrieveMoment
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
Definition: CaloCluster_v1.cxx:738
InDet::CaloClusterROIPhiRZContainerMaker::CaloClusterROIPhiRZContainerMaker
CaloClusterROIPhiRZContainerMaker(const std::string &name, ISvcLocator *pSvcLocator)
Definition: CaloClusterROIPhiRZContainerMaker.cxx:24
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
ROIPhiRZContainer.h
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
InDet::CaloClusterROIPhiRZContainerMaker::m_calosurf
ToolHandle< ICaloSurfaceBuilder > m_calosurf
Tool to build calorimeter layer surfaces.
Definition: CaloClusterROIPhiRZContainerMaker.h:84
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CaloClusterROIPhiRZContainerMaker.h
InDet::CaloClusterROIPhiRZContainerMaker::m_inputClusterContainerName
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_inputClusterContainerName
Name of the cluster intput collection.
Definition: CaloClusterROIPhiRZContainerMaker.h:70
xAOD::CaloCluster_v1::ENG_FRAC_EM
@ ENG_FRAC_EM
Energy fraction in EM calorimeters.
Definition: CaloCluster_v1.h:139
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
Trk::locPhi
@ locPhi
local polar
Definition: ParamDefs.h:45
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
LocalParameters.h
InDet::CaloClusterROIPhiRZContainerMaker::m_outputSorted
std::vector< unsigned int > m_outputSorted
Definition: CaloClusterROIPhiRZContainerMaker.h:100
InDet::CaloClusterROIPhiRZContainerMaker::getCaloSurface
const Trk::Surface * getCaloSurface(const xAOD::CaloCluster &cluster, const CaloDetDescrManager &caloDDMgr) const
Definition: CaloClusterROIPhiRZContainerMaker.h:46
InDet::CaloClusterROIPhiRZContainerMaker::m_EMEnergyOnly
Gaudi::Property< bool > m_EMEnergyOnly
Definition: CaloClusterROIPhiRZContainerMaker.h:91
InDet::CaloClusterROIPhiRZContainerMaker::~CaloClusterROIPhiRZContainerMaker
~CaloClusterROIPhiRZContainerMaker()
a
TList * a
Definition: liststreamerinfos.cxx:10
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
TriggerTest.rois
rois
Definition: TriggerTest.py:23
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:75
InDet::CaloClusterROIPhiRZContainerMaker::m_phiWidth
Gaudi::Property< std::vector< float > > m_phiWidth
Definition: CaloClusterROIPhiRZContainerMaker.h:94
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
Trk::Surface::localToGlobal
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const =0
Specified by each surface type: LocalToGlobal method without dynamic memory allocation.
InDet::CaloClusterROIPhiRZContainerMaker::m_allClusters
std::atomic_uint m_allClusters
Definition: CaloClusterROIPhiRZContainerMaker.h:105