ATLAS Offline Software
Loading...
Searching...
No Matches
GepClusteringAlg.cxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4
5/*
6 This algorithm creates clusters from CaloCells, and writes them out
7 as Caloclusters. The clustering strategy is carried out by helper objects.
8 The strategy used is chosen accoeding to string set at configure time. *
9*/
10
11#include "./GepClusteringAlg.h"
12
13// concrete cluster maker classes:
14#include "./WFSClusterMaker.h"
16
18#include "CaloGeoHelpers/CaloSampling.h"
20
21#include <cmath>
22#include <vector>
23
24GepClusteringAlg::GepClusteringAlg( const std::string& name, ISvcLocator* pSvcLocator ) :
25AthReentrantAlgorithm( name, pSvcLocator ){
26 }
27
28
30 ATH_MSG_INFO ("Initializing " << name() << "...");
31 ATH_MSG_INFO ("Clustering alg " << m_clusterAlg);
32
33 // Initialize read and write handles
34 CHECK(m_eventInfoKey.initialize());
35 CHECK(m_outputCaloClustersKey.initialize());
36 CHECK(m_gepCellsKey.initialize());
37
38 return StatusCode::SUCCESS;
39}
40
41
42StatusCode GepClusteringAlg::execute(const EventContext& ctx) const {
43 // Feed the specified cell map to a cluster creation algorithm and writes
44 // them out
45
46 ATH_MSG_DEBUG ("Executing " << name() << "...");
47
48 auto h_eventInfo = SG::makeHandle(m_eventInfoKey, ctx);
49 CHECK(h_eventInfo.isValid());
50 ATH_MSG_DEBUG("eventNumber=" << h_eventInfo->eventNumber() );
51
52 auto h_gepCellsMap = SG::makeHandle(m_gepCellsKey, ctx);
53 CHECK(h_gepCellsMap.isValid());
54 auto gepCellsMap = *h_gepCellsMap;
55
56 ATH_MSG_DEBUG("Read in " << gepCellsMap.size() << " GEP cells");
57
58 // container for CaloCluster wrappers for Gep Clusters
61 CHECK(h_outputCaloClusters.record(std::make_unique<xAOD::CaloClusterContainer>(),
62 std::make_unique<xAOD::CaloClusterAuxContainer>()));
63
64 // Run a cluster algorithm
65 std::unique_ptr<Gep::IClusterMaker> clusterMaker{};
66
67 // Instantiate a cluster creater object
68 if( m_clusterAlg == "WFS" ){
69 clusterMaker.reset(new Gep::WFSClusterMaker());
70 }
71
72 if( m_clusterAlg == "GEPBasic" ){
73 clusterMaker.reset(new Gep::BasicGepClusterMaker());
74 }
75
76 if( !clusterMaker ){
77 ATH_MSG_ERROR( "Unknown clusterMaker" + m_clusterAlg );
78 return StatusCode::FAILURE;
79 }
80
81 ATH_MSG_DEBUG( "Running " << clusterMaker->getName() << " cluster algorithm." );
82
83 // pass them to the cluster maker
84 auto pCellMap = gepCellsMap.getCellMap();
85 std::vector<Gep::Cluster> customClusters = clusterMaker->makeClusters(pCellMap);
86
87 ATH_MSG_DEBUG( "Clustering completed." );
88 ATH_MSG_DEBUG("No of clusters: " << customClusters.size());
89 if (!customClusters.empty()){
90 ATH_MSG_DEBUG("Cluster 0 Energy: " << (customClusters[0]).vec.E());
91 }
92
93 // Store the Gep clusters to a CaloClusters, and write out.
94 h_outputCaloClusters->reserve(customClusters.size());
95
96 for(const auto& gepclus: customClusters){
97
98 // make a unique_ptr, but keep hold of the bare pointer
99 auto caloCluster = std::make_unique<xAOD::CaloCluster>();
100 auto *ptr = caloCluster.get();
101
102 // store the calCluster to fix up the Aux container:
103 h_outputCaloClusters->push_back(std::move(caloCluster));
104
105 // this invalidates the unque_ptr, but can use the bare ptr
106 // to update the calo cluster.
107 ptr->setE(gepclus.vec.E());
108 ptr->setEta(gepclus.vec.Eta());
109 ptr->setPhi(gepclus.vec.Phi());
110 ptr->setTime(gepclus.time);
111
112 // Below are modifications to add per layer energy for clusters:
113 // Accumulate per-sampling (layer) transverse energy from the cluster's cells
114 // and store it on the cluster as energy (E = Et * cosh(eta)), mirroring
115 // GepCellTowerAlg. The cluster itself carries only cell links, so downstream
116 // PU-suppressed copies (EtaSK / SK) -- which drop the cell links -- would
117 // otherwise have no way to expose per-layer Et. Storing it here lets them
118 // recover it via eSample(); dividing back by cosh(eta) reproduces the same
119 // cell-Et sum used for the un-suppressed clusters.
120 const double clusEta = gepclus.vec.Eta();
121 std::vector<float> layerEnergies(static_cast<int>(CaloSampling::Unknown), 0.f);
122 for (auto cell_id : gepclus.cell_id) {
123 const auto& cell = pCellMap->at(cell_id);
124 if (cell.sampling < static_cast<unsigned int>(CaloSampling::Unknown))
125 layerEnergies[cell.sampling] += cell.et;
126 }
127 uint32_t samplingPattern = 0;
128 for (int i = 0; i < static_cast<int>(CaloSampling::Unknown); ++i)
129 if (layerEnergies[i] != 0) samplingPattern |= (0x1U << i);
130 ptr->clearSamplingData();
131 ptr->setSamplingPattern(samplingPattern);
132 for (int i = 0; i < static_cast<int>(CaloSampling::Unknown); ++i) {
133 if (layerEnergies[i] != 0)
134 ptr->setEnergy(static_cast<CaloSampling::CaloSample>(i),
135 layerEnergies[i] * std::cosh(clusEta));
136 }
137
139
140 for (auto cell_id : gepclus.cell_id)
141 cccl->addCell(pCellMap->at(cell_id).index, 1.0);
142
143 ptr->addCellLink(std::make_unique<CaloClusterCellLink>(*cccl));
144 }
145
146
147 return StatusCode::SUCCESS;
148}
149
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
Definition of CaloDetDescrManager.
std::vector< size_t > vec
#define CHECK(...)
Evaluate an expression and check for errors.
An algorithm that can be simultaneously executed in multiple threads.
GepClusteringAlg(const std::string &name, ISvcLocator *pSvcLocator)
virtual StatusCode execute(const EventContext &) const override
Gaudi::Property< std::string > m_clusterAlg
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
SG::ReadHandleKey< Gep::GepCellMap > m_gepCellsKey
virtual StatusCode initialize() override
SG::WriteHandleKey< xAOD::CaloClusterContainer > m_outputCaloClustersKey
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())