ATLAS Offline Software
egammaTopoClusterCopier.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
8 #include "xAODCore/ShallowCopy.h"
9 #include "StoreGate/ReadHandle.h"
10 #include "StoreGate/WriteHandle.h"
12 
13 #include <cmath>
14 #include <map>
15 
16 namespace{
17 // Special egamma EMFraction which includes presampler and E4 cells.
18 const SG::AuxElement::Accessor<float> s_acc_emfraction {"EMFraction"};
19 
20 //comparison function
21 bool greater(xAOD::CaloCluster const* a, xAOD::CaloCluster const* b) {
22  const double emfrac_a = s_acc_emfraction(*a);
23  const double emfrac_b = s_acc_emfraction(*b);
24  return (a->et() * emfrac_a) > (b->et() * emfrac_b);
25 }
26 
27 double addTileGapCellsEnergy(xAOD::CaloCluster* cluster) {
28  double eg_tilegap = 0;
29 
32 
33  for (; cell_itr != cell_end; ++cell_itr) {
34  const CaloCell* cell = *cell_itr;
35  if (!cell) { continue; }
36 
37  const CaloDetDescrElement *dde = cell->caloDDE();
38  if (!dde) { continue; }
39 
40  // Add TileGap3. Consider only E4 cell.
41  if (CaloCell_ID::TileGap3 == dde->getSampling()) {
42  double ddAbsEta = std::abs(dde->eta_raw());
43  if (ddAbsEta > 1.4 && ddAbsEta < 1.6) {
44  eg_tilegap += cell->e() * cell_itr.weight();
45  }
46  }
47  }
48 
49  return eg_tilegap;
50 }
51 
52 bool checkIfValidForCentral(
53  double aeta,
54  float etaCut,
55  double clusterE,
56  float ECut
57 ) {
58  return aeta <= etaCut && clusterE >= ECut;
59 }
60 
61 bool checkIfValidForFwd(
62  double aeta,
63  float etaCut,
64  double ETCut,
65  xAOD::CaloCluster *clus,
66  bool doForwardClusters,
67  bool hasITk
68 ) {
69  if (doForwardClusters) {
70  // LC variables are Local Hadronic Calorimeter calibrated and are included
71  // for compatibility with Run3.
72  const double clusterET = clus->et();
73  const double clusterETLC = clus->getSisterCluster()->et();
74  const double aetaLC = std::abs(clus->getSisterCluster()->eta());
75 
76  if (hasITk) {
77  // When we do actually ITK these should be EM.
78  return aeta >= etaCut && clusterET >= ETCut;
79  } else {
80  // Without ITK we need the LC.
81  return aetaLC >= etaCut && clusterETLC >= ETCut;
82  }
83  } else {
84  return false;
85  }
86 }
87 } // namespace
88 
90  ISvcLocator* pSvcLocator):
91  AthReentrantAlgorithm(name, pSvcLocator)
92 { }
93 
95  ATH_MSG_DEBUG("Initializing " << name() << "...");
96 
99 
102 
105 
106  ATH_MSG_DEBUG("Initialization successful");
107 
108  return StatusCode::SUCCESS;
109 }
110 
112  ATH_MSG_INFO("=====> Selected Topo cluster statistics ===========");
113  ATH_MSG_INFO(" All Clusters " << m_AllClusters );
114  ATH_MSG_INFO(" Central: Pass Preselection Clusters " << m_CentralPassPreSelection );
115  ATH_MSG_INFO(" Fwd: Pass Preselection Clusters " << m_FwdPassPreSelection );
116  ATH_MSG_INFO(" Shared: Pass Preselection Clusters " << m_SharedPassPreSelection );
117  ATH_MSG_INFO(" Central: Pass Selection " << m_CentralPassSelection );
118  ATH_MSG_INFO(" Fwd: Pass Selection " << m_FwdPassSelection );
119  ATH_MSG_INFO(" Shared: Pass Selection " << m_SharedPassSelection );
120  ATH_MSG_INFO("===================================================");
121 
122  return StatusCode::SUCCESS;
123 }
124 
125 StatusCode egammaTopoClusterCopier::execute(const EventContext& ctx) const {
129 
130  // Create a shallow copy, the elements of this can be modified, but no need to
131  // recreate the cluster.
132  std::pair<
133  std::unique_ptr<xAOD::CaloClusterContainer>,
134  std::unique_ptr<xAOD::ShallowAuxContainer>
135  > inputShallowcopy = xAOD::shallowCopyContainer(*inputTopoclusters, ctx);
136 
137  ATH_CHECK(outputTopoclustersShallow.record(
138  std::move(inputShallowcopy.first),
139  std::move(inputShallowcopy.second)
140  ));
141 
142  // Here it just needs to be a view copy, i.e the collection we create does not
143  // really own its elements.
144  auto viewCopy = std::make_unique<ConstDataVector<xAOD::CaloClusterContainer>>(SG::VIEW_ELEMENTS);
145 
146  // Declare and conditionally initialise forward cluster objects.
148  std::unique_ptr<ConstDataVector<xAOD::CaloClusterContainer>> fwdViewCopy;
149 
150  if (m_doForwardClusters) {
153  ctx
154  );
155 
156  fwdViewCopy = std::make_unique<ConstDataVector<xAOD::CaloClusterContainer>>(SG::VIEW_ELEMENTS);
157  }
158 
159  auto buff_AllClusters = m_AllClusters.buffer();
160  auto buff_CentralPassPreSelection = m_CentralPassPreSelection.buffer();
161  auto buff_CentralPassSelection = m_CentralPassSelection.buffer();
162  auto buff_FwdPassPreSelection = m_FwdPassPreSelection.buffer();
163  auto buff_FwdPassSelection = m_FwdPassSelection.buffer();
164  auto buff_SharedPassPreSelection = m_SharedPassPreSelection.buffer();
165  auto buff_SharedPassSelection = m_SharedPassSelection.buffer();
166 
167  // Loop over the output shallow copy.
168  for (xAOD::CaloCluster* clus : *outputTopoclustersShallow) {
170  "->CHECKING Cluster at eta,phi,et " <<
171  clus->eta() << " , " <<
172  clus->phi() << " , " <<
173  clus->et()
174  );
175 
176  ++buff_AllClusters;
177  s_acc_emfraction(*clus) = 0.0; // Always decorate
178 
179  const double clusterE = clus->e();
180  const double aeta = std::abs(clus->eta());
181 
182  const bool valid_for_central = checkIfValidForCentral(aeta, m_etaCut, clusterE, m_ECut);
183  const bool valid_for_fwd = checkIfValidForFwd(aeta, m_fwdEtaCut, m_fwdETCut, clus, m_doForwardClusters, m_hasITk);
184  if (valid_for_central) {
185  ++buff_CentralPassPreSelection;
186  } else if (valid_for_fwd) {
187  ++buff_FwdPassPreSelection;
188  } else {
189  continue;
190  }
191 
192  const bool valid_for_both = valid_for_central && valid_for_fwd;
193  if (valid_for_both) {
194  ++buff_FwdPassPreSelection; // since we count them only in the else above
195  ++buff_SharedPassPreSelection;
196  }
197 
198  if (!m_hasITk && m_doForwardClusters && valid_for_fwd) {
199  fwdViewCopy->push_back(clus->getSisterCluster());
200  ++buff_FwdPassSelection;
201  }
202 
203  // Add the relevant TileGap3/E4 cells.
204  double eg_tilegap = 0;
205  if (valid_for_central) {
206  if (aeta > 1.35 && aeta < 1.65 && clusterE > 0) {
207  eg_tilegap += addTileGapCellsEnergy(clus);
208  }
209  }
210 
211  const double emfrac= (clus->energyBE(0) + clus->energyBE(1) +
212  clus->energyBE(2) + clus->energyBE(3) + eg_tilegap) / clusterE;
213 
214  s_acc_emfraction(*clus) = emfrac;
215  if ((emfrac > m_EMFracCut && (clusterE * emfrac) > m_ECut) || xAOD::EgammaHelpers::isFCAL(clus)) {
217  "-->Selected Cluster at eta,phi,et,EMFraction " << clus->eta() <<
218  " , " << clus->phi() <<
219  " , " << clus->et() <<
220  " , " << emfrac
221  );
222 
223  if (valid_for_central) {
224  viewCopy->push_back(clus);
225  ++buff_CentralPassSelection;
226  }
227 
228  if (m_hasITk && valid_for_fwd) {
229  fwdViewCopy->push_back(clus);
230  ++buff_FwdPassSelection;
231  }
232 
233  if (valid_for_both) {
234  ++buff_SharedPassSelection;
235  }
236  }
237  } // End loop on clusters.
238 
239  // Sort in descenting em energy.
240  std::sort(viewCopy->begin(), viewCopy->end(), greater);
241 
243  "Cloned container has size: " << viewCopy->size() <<
244  " selected out of : " << inputTopoclusters->size()
245  );
246 
247  ATH_CHECK(outputTopoclusters.record(std::move(viewCopy)));
248 
249  if (m_doForwardClusters) {
250  if (m_hasITk) {
251  std::sort(fwdViewCopy->begin(), fwdViewCopy->end(), greater);
252  }
253 
255  "Cloned fwd container has size: " << fwdViewCopy->size() <<
256  " selected out of : " << inputTopoclusters->size()
257  );
258 
259  ATH_CHECK(outputFwdTopoclusters.record(std::move(fwdViewCopy)));
260  }
261 
262  return StatusCode::SUCCESS;
263 }
264 
egammaTopoClusterCopier::m_FwdPassPreSelection
Gaudi::Accumulators::Counter m_FwdPassPreSelection
Definition: egammaTopoClusterCopier.h:131
ShallowCopy.h
xAOD::CaloCluster_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition: CaloCluster_v1.cxx:256
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:66
egammaTopoClusterCopier::m_fwdEtaCut
Gaudi::Property< double > m_fwdEtaCut
Definition: egammaTopoClusterCopier.h:89
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
egammaTopoClusterCopier::egammaTopoClusterCopier
egammaTopoClusterCopier(const std::string &name, ISvcLocator *pSvcLocator)
Definition: egammaTopoClusterCopier.cxx:89
egammaTopoClusterCopier::m_etaCut
Gaudi::Property< float > m_etaCut
Definition: egammaTopoClusterCopier.h:82
xAOD::CaloCluster_v1::et
double et() const
Definition: CaloCluster_v1.h:856
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
egammaTopoClusterCopier::m_doForwardClusters
bool m_doForwardClusters
Private member flag to copy forward clusters.
Definition: egammaTopoClusterCopier.h:126
egammaTopoClusterCopier::m_outputFwdTopoCollection
SG::WriteHandleKey< ConstDataVector< xAOD::CaloClusterContainer > > m_outputFwdTopoCollection
Definition: egammaTopoClusterCopier.h:75
CaloCell_ID_FCS::TileGap3
@ TileGap3
Definition: FastCaloSim_CaloCell_ID.h:36
CxxUtils::fpcompare::greater
bool greater(double a, double b)
Compare two FP numbers, working around x87 precision issues.
Definition: fpcompare.h:140
CaloDetDescrElement::eta_raw
float eta_raw() const
cell eta_raw
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:350
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
egammaTopoClusterCopier::execute
virtual StatusCode execute(const EventContext &ctx) const override final
Definition: egammaTopoClusterCopier.cxx:125
egammaTopoClusterCopier::m_FwdPassSelection
Gaudi::Accumulators::Counter m_FwdPassSelection
Definition: egammaTopoClusterCopier.h:132
egammaTopoClusterCopier::m_outputTopoCollectionShallow
SG::WriteHandleKey< xAOD::CaloClusterContainer > m_outputTopoCollectionShallow
Definition: egammaTopoClusterCopier.h:61
WriteHandle.h
Handle class for recording to StoreGate.
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
EgammaxAODHelpers.h
xAOD::CaloCluster_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: CaloCluster_v1.cxx:251
CaloCluster.h
egammaTopoClusterCopier::m_AllClusters
Gaudi::Accumulators::Counter m_AllClusters
Definition: egammaTopoClusterCopier.h:128
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
xAOD::CaloCluster_v1::getSisterCluster
const CaloCluster_v1 * getSisterCluster() const
Get a pointer to a 'sister' cluster (eg the non-calibrated counterpart)
Definition: CaloCluster_v1.cxx:957
egammaTopoClusterCopier::m_EMFracCut
Gaudi::Property< float > m_EMFracCut
Definition: egammaTopoClusterCopier.h:110
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
egammaTopoClusterCopier::finalize
virtual StatusCode finalize() override final
Definition: egammaTopoClusterCopier.cxx:111
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
egammaTopoClusterCopier::m_SharedPassPreSelection
Gaudi::Accumulators::Counter m_SharedPassPreSelection
Definition: egammaTopoClusterCopier.h:133
egammaTopoClusterCopier::m_ECut
Gaudi::Property< float > m_ECut
Definition: egammaTopoClusterCopier.h:96
egammaTopoClusterCopier::initialize
virtual StatusCode initialize() override final
Definition: egammaTopoClusterCopier.cxx:94
egammaTopoClusterCopier.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
xAOD::CaloCluster_v1::cell_cend
const_cell_iterator cell_cend() const
Definition: CaloCluster_v1.h:803
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
xAOD::EgammaHelpers::isFCAL
bool isFCAL(const xAOD::CaloCluster *cluster)
return true if the cluster (or the majority of its energy) is in the FCAL0
Definition: EgammaxAODHelpers.cxx:46
egammaTopoClusterCopier::m_inputTopoCollection
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_inputTopoCollection
Definition: egammaTopoClusterCopier.h:54
xAOD::shallowCopyContainer
std::pair< std::unique_ptr< T >, std::unique_ptr< ShallowAuxContainer > > shallowCopyContainer(const T &cont, [[maybe_unused]] const EventContext &ctx)
Function making a shallow copy of a constant container.
Definition: ShallowCopy.h:110
CaloClusterStoreHelper.h
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
egammaTopoClusterCopier::m_outputTopoCollection
SG::WriteHandleKey< ConstDataVector< xAOD::CaloClusterContainer > > m_outputTopoCollection
Definition: egammaTopoClusterCopier.h:68
a
TList * a
Definition: liststreamerinfos.cxx:10
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
CaloDetDescrElement::getSampling
CaloCell_ID::CaloSample getSampling() const
cell sampling
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:395
egammaTopoClusterCopier::m_CentralPassSelection
Gaudi::Accumulators::Counter m_CentralPassSelection
Definition: egammaTopoClusterCopier.h:130
egammaTopoClusterCopier::m_fwdETCut
Gaudi::Property< double > m_fwdETCut
Definition: egammaTopoClusterCopier.h:103
egammaTopoClusterCopier::m_hasITk
Gaudi::Property< bool > m_hasITk
Private member flag to do the track matching.
Definition: egammaTopoClusterCopier.h:118
xAOD::CaloCluster_v1::energyBE
float energyBE(const unsigned layer) const
Get the energy in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:630
xAOD::CaloCluster_v1::cell_cbegin
const_cell_iterator cell_cbegin() const
Definition: CaloCluster_v1.h:795
ReadHandle.h
Handle class for reading from StoreGate.
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
egammaTopoClusterCopier::m_CentralPassPreSelection
Gaudi::Accumulators::Counter m_CentralPassPreSelection
Definition: egammaTopoClusterCopier.h:129
egammaTopoClusterCopier::m_SharedPassSelection
Gaudi::Accumulators::Counter m_SharedPassSelection
Definition: egammaTopoClusterCopier.h:134