9#include "CaloGeoHelpers/CaloSampling.h"
29 CellAccum (
double& the_posNorm,
30 std::array<double,CaloSampling::Unknown>& the_posSamNorm,
34 const bool useGPUCriteria =
false)
40 EtaMaxEnergyInSample(),
41 PhiMaxEnergyInSample(),
50 posNorm (the_posNorm),
51 posSamNorm (the_posSamNorm),
52 nBarrel (the_nBarrel),
53 nEndcap (the_nEndcap),
54 timeNorm (the_timeNorm)
57 for (
size_t i = 0;
i < (size_t) CaloSampling::Unknown; ++
i) {
58 MaxEnergyInSample[
i] = std::numeric_limits<double>::lowest();
62 double EnergyInSample[CaloSampling::Unknown];
64 double EtaInSample[CaloSampling::Unknown];
65 double PhiInSample[CaloSampling::Unknown];
66 double MaxEnergyInSample[CaloSampling::Unknown];
67 double EtaMaxEnergyInSample[CaloSampling::Unknown];
68 double PhiMaxEnergyInSample[CaloSampling::Unknown];
69 bool PresenceInSample[CaloSampling::Unknown];
72 double theNewSecondTime;
79 std::array<double,CaloSampling::Unknown>& posSamNorm;
87 double operator() (
const CaloClusterCellLink::const_iterator& it)
const {
return it.weight();}
93 double operator() (
const CaloClusterCellLink::const_iterator&)
const {
return 1; }
100template <
class WEIGHT>
108 double fabsweight = fabs (weight);
110 double theEnergyNoWeight =
cell.e();
114 double theAbsEnergy =
weight * fabs(theEnergyNoWeight);
117 accum.PresenceInSample[sam] =
true;
118 double cellEta = dde->
eta();
119 double cellPhi = dde->
phi();
125 if (accum.phi0 < -900) {
126 thePhi = accum.phi0 = cellPhi;
129 thePhi =
proxim (cellPhi, accum.phi0);
131 accum.theNewEta += theAbsEnergy * cellEta;
132 accum.theNewPhi += theAbsEnergy * thePhi;
133 if (useGPUCriteria) {
134 if ( accum.MaxEnergyInSample[sam] < theEnergy || (accum.MaxEnergyInSample[sam] == theEnergy && accum.maxCell < (
int) cellIt.
index()) ) {
135 accum.MaxEnergyInSample[sam] =
theEnergy;
136 accum.EtaMaxEnergyInSample[sam] = cellEta;
137 accum.PhiMaxEnergyInSample[sam] = cellPhi;
138 accum.maxCell = (int) cellIt.
index();
142 if ( accum.MaxEnergyInSample[sam] < theEnergy ) {
143 accum.MaxEnergyInSample[sam] =
theEnergy;
144 accum.EtaMaxEnergyInSample[sam] = cellEta;
145 accum.PhiMaxEnergyInSample[sam] = cellPhi;
149 accum.posSamNorm[sam] += theAbsEnergy;
150 accum.posNorm += theAbsEnergy;
152 accum.EtaInSample[sam] += theAbsEnergy * cellEta;
153 accum.PhiInSample[sam] += theAbsEnergy * thePhi;
155 if ( theEnergy != 0 && weight != 0)
159 case CaloSampling::PreSamplerE:
160 case CaloSampling::EME1:
161 case CaloSampling::EME2:
162 case CaloSampling::EME3:
163 case CaloSampling::HEC0:
164 case CaloSampling::HEC1:
165 case CaloSampling::HEC2:
166 case CaloSampling::HEC3:
167 case CaloSampling::FCAL0:
168 case CaloSampling::FCAL1:
169 case CaloSampling::FCAL2:
170 case CaloSampling::MINIFCAL0:
171 case CaloSampling::MINIFCAL1:
172 case CaloSampling::MINIFCAL2:
173 case CaloSampling::MINIFCAL3:
182 if (sam != CaloSampling::PreSamplerB &&
183 sam != CaloSampling::PreSamplerE)
185 unsigned int pmask = dde->
is_tile() ? 0x8080 : 0x2000;
188 if (
cell.provenance() & pmask ) {
190 double theTimeNorm = fabsweight *
theEnergy * theEnergyNoWeight;
191 accum.theNewTime += theTimeNorm *
cell.time();
192 accum.theNewSecondTime += theTimeNorm *
cell.time() *
cell.time();
193 accum.timeNorm += theTimeNorm;
200template <
class WEIGHT>
202void accumCells (
const CaloClusterCellLink* cccl, CellAccum& accum,
const WEIGHT& w,
const bool useGPUCriteria =
false) {
213 for (;
it!=it_e;++
it) {
215 accumCell(it,accum,w, useGPUCriteria);
238 if (!cccl || cccl->
size()==0)
return;
243 double timeNorm = 0.;
245 std::array<double,CaloSampling::Unknown> posSamNorm{};
247 CellAccum accum (posNorm, posSamNorm, nBarrel, nEndcap, timeNorm, useGPUCriteria);
250 accumCells (cccl, accum, AccumWeight(), useGPUCriteria);
252 accumCells (cccl, accum, AccumNoWeight(), useGPUCriteria);
254 if ( posNorm != 0. ) {
255 double inorm = 1 / posNorm;
256 clu->
setEta(accum.theNewEta * inorm);
264 clu->
setE(accum.theNewEnergy);
267 if ( timeNorm != 0. ) {
268 clu->
setTime(accum.theNewTime/timeNorm);
281 uint32_t samplingPattern=0;
282 for(
int i=0;i<(int)CaloSampling::Unknown;i++) {
283 if (accum.PresenceInSample[i])
284 samplingPattern |= (0x1U<<i);
296 if ( !updateLayers )
return;
299 for(
int i=0;i<(int)CaloSampling::Unknown;i++) {
300 if ( !accum.PresenceInSample[i] )
continue;
301 if ( posSamNorm[i] != 0 ) {
302 const double inorm = 1 / posSamNorm[i];
303 accum.EtaInSample[i] *= inorm;
310 for(
int i=0;i<(int)CaloSampling::Unknown;i++) {
311 if ( !accum.PresenceInSample[i] )
continue;
314 clu->
setEnergy(sam,accum.EnergyInSample[i]);
316 clu->
setEta(sam,accum.EtaInSample[i]);
317 clu->
setPhi(sam,accum.PhiInSample[i]);
319 clu->
setEmax(sam,accum.MaxEnergyInSample[i]);
320 clu->
setEtamax(sam,accum.EtaMaxEnergyInSample[i]);
321 clu->
setPhimax(sam,accum.PhiMaxEnergyInSample[i]);
CaloPhiRange class declaration.
Data object for each calorimeter readout cell.
const_iterator to loop over cells belonging to a cluster
unsigned index() const
Accessor for the index of the cell in the CaloCellContainer.
Bookkeeping of cells that make up a cluster Simplified replacement for CaloCellLink,...
const_iterator end() const
const end method
size_t size() const
size method
const_iterator begin() const
const begin method
static void calculateKine(xAOD::CaloCluster *clu, const bool useweight=true, const bool updateLayers=true, const bool useGPUCriteria=false)
Helper class to calculate cluster kinematics based on cells.
This class groups all DetDescr information related to a CaloCell.
bool is_tile() const
cell belongs to Tile
float eta() const
cell eta
float phi() const
cell phi
static double fix(double phi)
void setSecondTime(flt_t stime)
Set second moment of cell timing distribution.
bool setPhi(const CaloSample sampling, const float phi)
Set in a given sampling. Returns false if the sample isn't part of the cluster.
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
flt_t time() const
Access cluster time.
void setTime(flt_t)
Set cluster time.
bool setPhimax(const CaloSample sampling, const float phiMax)
Set the phi of the cell with the highest energy in a particular sampling.
bool setEta(const CaloSample sampling, const float eta)
Set in a given sampling. Returns false if the sample isn't part of the cluster.
bool setEmax(const CaloSample sampling, const float eMax)
Set the Energy of the cell with the highest energy in a particular sampling.
bool setEnergy(const CaloSample sampling, const float e)
Set energy for a given sampling. Returns false if the sample isn't part of the cluster.
void setSamplingPattern(const unsigned sp, const bool clearSamplingVars=false)
Set sampling pattern (one bit per sampling.
bool setEtamax(const CaloSample sampling, const float etaMax)
Set the eta of the cell with the highest energy in a particular sampling.
void clearSamplingData()
Clear the sampling data.
unsigned samplingPattern() const
Access to sampling pattern (one bit per sampling) (Method may be removed later)
void setM(flt_t)
Set Mass for the current signal state.
void nextDDE(Iter iter, Iter endIter)
Prefetch next CaloDDE.
void prefetchObj(const T *ptr)
Generic prefetch of the object of specific types (sizes).
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
double proxim(double b, double a)