ATLAS Offline Software
eflowLayerIntegrator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /********************************************************************
6 
7 NAME: eflowLayerIntegrator.h
8 PACKAGE: offline/Reconstruction/eflowRec
9 
10 AUTHORS: M.Hodgkinson, R Duxfield (based on R.Duxfields Root package)
11 CREATED: 18th Aug, 2005
12 
13 ********************************************************************/
14 
15 //Athena Headers
20 #include "eflowRec/eflowDatabase.h"
24 #include "eflowRec/eflowRecTrack.h"
26 
27 #include "CaloDetDescr/CaloDetDescrElement.h"
28 #include "CaloEvent/CaloCell.h"
29 
31 
32 eflowLayerIntegrator::eflowLayerIntegrator(double stdDev, double error, double rMaxOverStdDev, bool isHLLHC) :
33  m_rMax(rMaxOverStdDev * stdDev),
34  m_isHLLHC(isHLLHC),
35  m_allClustersIntegral(eflowCalo::nRegions, 0.0),
36  m_nUnitCellPerWindowOverCellEtaPhiArea(eflowCalo::nRegions),
37  m_integrator(std::make_unique<eflowCellIntegrator<0> >(stdDev, error)),
38  m_integratorLookup(std::make_unique<eflowCellIntegrator<1> >(stdDev, error)) {
40 
41  /* Set up density conversion factors */
42  double emX0PerUnitLengthToTheMinus3 = pow(database.getEmX0PerUnitLength(), -3.0);
43  double hadX0PerUnitLengthToTheMinus3 = pow(database.getHadX0PerUnitLength(), -3.0);
44  for (int i = 0; i < eflowCalo::nRegions; i++) {
47  emX0PerUnitLengthToTheMinus3 :
48  hadX0PerUnitLengthToTheMinus3;
49  if(i==13) m_densityConversion[i] = pow(database.getFCalX0PerUnitLength(0), -3.0);
50  if(i==14) m_densityConversion[i] = pow(database.getFCalX0PerUnitLength(1), -3.0);
51  if(i==15) m_densityConversion[i] = pow(database.getFCalX0PerUnitLength(2), -3.0);
52  }
53 
54  /* More setup */
55  double nUnitCellsPerWindow = M_PI * stdDev * stdDev / (database.getEtaUnit() * database.getPhiUnit());
56  std::vector<double> cellEtaWidth = database.getCellEtaWidth();
57  std::vector<double> cellPhiWidth = database.getCellPhiWidth();
58  for (int i = 0; i < eflowCalo::nRegions; i++){
60  nUnitCellsPerWindow / (cellEtaWidth[i] * cellPhiWidth[i]);
61  }
62 }
63 
65  : m_rMax (originalEflowLayerIntegrator.m_rMax),
66  m_isHLLHC (originalEflowLayerIntegrator.m_isHLLHC),
67  m_allClustersIntegral (originalEflowLayerIntegrator.m_allClustersIntegral),
68  m_nUnitCellPerWindowOverCellEtaPhiArea (originalEflowLayerIntegrator.m_nUnitCellPerWindowOverCellEtaPhiArea),
69  m_integrator (std::make_unique<eflowCellIntegrator<0> >(*originalEflowLayerIntegrator.m_integrator)),
70  m_integratorLookup (std::make_unique<eflowCellIntegrator<1> >(*originalEflowLayerIntegrator.m_integratorLookup))
71 {
72  for (int i = 0; i < eflowCalo::nRegions; i++){
73  m_densityConversion[i] = originalEflowLayerIntegrator.m_densityConversion[i];
75  }
76 }
77 
79  if (this == &originalEflowLayerIntegrator) return *this;
80  //if not assigning to self, then we copy the data to the new object
81  else {
82  m_rMax = originalEflowLayerIntegrator.m_rMax;
83  m_isHLLHC = originalEflowLayerIntegrator.m_isHLLHC;
84  m_allClustersIntegral = originalEflowLayerIntegrator.m_allClustersIntegral;
86  m_integrator = std::make_unique<eflowCellIntegrator<0> >(*originalEflowLayerIntegrator.m_integrator);
87  m_integratorLookup = std::make_unique<eflowCellIntegrator<1> >(*originalEflowLayerIntegrator.m_integratorLookup);
88 
89  for (int i = 0; i < eflowCalo::nRegions; i++){
90  m_densityConversion[i] = originalEflowLayerIntegrator.m_densityConversion[i];
92  }
93  return *this;
94  }//if not assigning to self, then we have copied the data to the new object
95 }
96 
98 
100  for (int iLayer = 0; iLayer < eflowCalo::nRegions; iLayer++) {
101  m_allClustersIntegral[iLayer] = trackCalo.haveLayer((eflowCaloENUM)iLayer) ? 0.0 : eflowTrackCaloPoints::defaultEta();
102  }
103  /* Calculate the caloDepthArray */
104  double em2Eta = trackCalo.getEM2eta();
105  if (!m_isHLLHC) {
106  if ( fabs(em2Eta) > 2.5 ) em2Eta = 2.49; //sometimes track extrapolator returns e.g. 2.51 for em2Eta, which causes depth array to be filled with zeroes.
107  }
108  else{
109  if(em2Eta<-998.) em2Eta = trackCalo.getFCAL0eta();
110  if ( fabs(em2Eta) > 4.0 ) { em2Eta = 3.99; } //sometimes track extrapolator returns e.g. 4.01 for em2Eta, which causes depth array to be filled with zeroes.
111  }
112 
113  m_caloModel.calcDepthArray(em2Eta, 1.0e-4);
114 }
115 
116 void eflowLayerIntegrator::addToAllClustersIntegral(const std::vector<double>& clusterIntegral) {
117  assert(clusterIntegral.size() == m_allClustersIntegral.size());
118 
119  if (clusterIntegral.size() != m_allClustersIntegral.size()){
120  std::cerr << " eflowLayerIntegrator ERROR: cluster integral sizes do not match" << std::endl;
121  return;
122  }
123 
124  for (int i = 0; i < eflowCalo::nRegions; i++) {
126  m_allClustersIntegral[i] += clusterIntegral[i];
127  }
128  }
129 }
130 
131 void eflowLayerIntegrator::measureNewClus(const std::vector<xAOD::CaloCluster*>& clusVec, const eflowTrackCaloPoints& trackCalo) {
133 
134  for (xAOD::CaloCluster* cluster : clusVec) {
135  measureCluster(cluster, trackCalo);
136  }
137 }
138 
139 void eflowLayerIntegrator::measureNewClus(const std::vector<eflowRecCluster*>& efRecClusters, eflowRecTrack* track) {
140  resetAllClustersIntegralForNewTrack(track->getTrackCaloPoints());
141 
142  const EventContext& ctx = Gaudi::Hive::currentContext();
143  for (eflowRecCluster* cluster : efRecClusters) {
145  }
146 }
147 
150 
151  measureCluster(trackClusterLink);
152 }
153 
156 
157  measureCluster(clus, trackCalo);
158 }
159 
161  if (trackClusterLink->getClusterIntegral().empty()){
162  /* The track-cluster pair hasn't been integrated yet. Integrate as usual and store the results */
163  measureCluster(trackClusterLink->getCluster()->getCluster(), trackClusterLink->getTrack()->getTrackCaloPoints());
164  trackClusterLink->setClusterIntegral(m_singleClusterIntegral);
165  if (trackClusterLink->getTrack()->getCaloDepthArray().empty()) {
166  trackClusterLink->getTrack()->setCaloDepthArray(m_caloModel.getDepthArray());
167  }
168  } else {
169  /* The track-cluster pair has already been integrated. Take integral from the TrackClusterLink and add to total integral */
170  addToAllClustersIntegral(trackClusterLink->getClusterIntegral());
171  }
172 }
173 
176 
177  const CaloClusterCellLink* theCellLink = clus->getCellLinks();
178 
179  if (theCellLink){
180 
181  CaloClusterCellLink::const_iterator itCell = theCellLink->begin();
182  CaloClusterCellLink::const_iterator itCellEnd = theCellLink->end();
183 
184  for (; itCell != itCellEnd; ++itCell) {
185  measureCell(*itCell, trackCalo);
186  }
187  }//if valid cell link
188 
190 
191 }
192 
194  const CaloDetDescrElement* caloDetDescrElement = cell->caloDDE();
195  if (!caloDetDescrElement) return;
196  //very rarely a calorimeter cell has zero volume - in such cases one cannot calculate an energy fensity.
197  //This is expected to happen for certain cells, for example presampler barrel or some tile gap cells.
198  //See https://its.cern.ch/jira/browse/ATR-20919 for discussion of this bug.
199  if ( caloDetDescrElement->volume() < 1e-6 ) return;
200 
201  eflowCaloENUM layer = eflowCalo::translateSampl(caloDetDescrElement->getSampling());
202  if (eflowCalo::Unknown == layer) { return; }
203 
204  const double extrapTrackEta = trackCalo.getEta(layer);
205  const double extrapTrackPhi = trackCalo.getPhi(layer);
206  if (extrapTrackEta == eflowTrackCaloPoints::defaultEta() ||
207  extrapTrackPhi == eflowTrackCaloPoints::defaultPhi()) {
208  return;
209  }
210 
211  const double etaWidth = caloDetDescrElement->deta();
212  const double phiWidth = caloDetDescrElement->dphi();
213 
214  const double dEta = cell->eta() - extrapTrackEta;
215  const double dPhi = xAOD::P4Helpers::deltaPhi(cell->phi(), extrapTrackPhi);
216  const double dr = sqrt(dEta * dEta + dPhi * dPhi);
217 
218  if ( fabs(dr - std::max(etaWidth, phiWidth)) <= m_rMax || dr <= m_rMax ) {
219 
220  eflowRange etaRange(dEta - etaWidth/2.0, dEta + etaWidth/2.0);
222 
223  const double weight = m_integratorLookup->integrate(etaRange, phiRange);
224 
225  m_singleClusterIntegral[layer] += weight * cell->energy() / caloDetDescrElement->volume();
226  }
227 
228 }
229 
231 
232  const double* depthArray = m_caloModel.getDepthArray();
233 
234  double xPrev = 0.0;
235  double yPrev = 0.0;
237  double maxGradient = -10.0;
238 
239  for (int layer = 0; layer < eflowCalo::nRegions; ++layer){
240 
242 
243  double convertedDensity = m_allClustersIntegral[layer] * m_densityConversion[layer];
245 
246  const double dx = depthArray[depthLayer+1] - xPrev;
247  const double dy = convertedDensity - yPrev;
248  xPrev = depthArray[depthLayer+1];
249  yPrev = convertedDensity;
250  const double gradient = dy / dx;
251 
252  if (gradient > maxGradient) {
253  maxGradient = gradient;
254  result = layer;
255  }
256  }
257 
259 }
CaloDetDescrElement::deta
float deta() const
cell deta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:356
eflowRecCluster
This class extends the information about a xAOD::CaloCluster.
Definition: eflowRecCluster.h:40
eflowCaloRegions.h
eflowCalo::EME3
@ EME3
Definition: eflowCaloRegions.h:46
eflowLayerIntegrator::addToAllClustersIntegral
void addToAllClustersIntegral(const std::vector< double > &clusterIntegral)
Definition: eflowLayerIntegrator.cxx:116
eflowTrackCaloPoints::defaultPhi
static double defaultPhi()
Definition: eflowTrackCaloPoints.cxx:29
eflowCellIntegrator
Class that controls the 2D integration.
Definition: eflowCellIntegrator.h:154
eflowLayerIntegrator::eflowLayerIntegrator
eflowLayerIntegrator(double stdDev, double error, double rMaxOverStdDev, bool isHLLHC=false)
Definition: eflowLayerIntegrator.cxx:32
eflowLayerIntegrator::m_integratorLookup
std::unique_ptr< eflowCellIntegrator< 1 > > m_integratorLookup
Definition: eflowLayerIntegrator.h:75
eflowDepthCalculator::calcDepthArray
const double * calcDepthArray(double eta, double filler=0.0)
Definition: eflowDepthCalculator.cxx:152
eflowLayerIntegrator
This class calculates the LHED (Layer of Highest Energy Density) in a cluster or group of clusters.
Definition: eflowLayerIntegrator.h:35
get_generator_info.result
result
Definition: get_generator_info.py:21
eflowTrackCaloPoints
This class stores a map of calorimeter layers and track parameters (the result of the track extrapola...
Definition: eflowTrackCaloPoints.h:30
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
max
#define max(a, b)
Definition: cfImp.cxx:41
eflowCellIntegrator.h
eflowRecTrack::getCaloDepthArray
const std::vector< double > & getCaloDepthArray() const
Definition: eflowRecTrack.h:77
eflowCalo
This defines the eflowCalo enum, which is used to label calorimeter layers in a simplified scheme whi...
Definition: eflowCaloRegions.h:25
make_unique
std::unique_ptr< T > make_unique(Args &&... args)
Definition: SkimmingToolEXOT5.cxx:23
eflowLayerIntegrator::m_densityConversion
double m_densityConversion[eflowCalo::nRegions]
Definition: eflowLayerIntegrator.h:70
LArCellBinning.etaRange
etaRange
Filling Eta range.
Definition: LArCellBinning.py:128
xAODP4Helpers.h
eflowCalo::Unknown
@ Unknown
Definition: eflowCaloRegions.h:50
eflowDatabase.h
eflowRecTrack::setCaloDepthArray
void setCaloDepthArray(const double *depthArray)
Definition: eflowRecTrack.cxx:88
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
M_PI
#define M_PI
Definition: ActiveFraction.h:11
eflowLayerIntegrator::m_isHLLHC
bool m_isHLLHC
Definition: eflowLayerIntegrator.h:63
CaloCell.h
xAOD::P4Helpers::deltaPhi
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition: xAODP4Helpers.h:69
eflowDepthCalculator::getDepthArray
const double * getDepthArray() const
Definition: eflowDepthCalculator.h:45
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:112
eflowLayerIntegrator::m_nUnitCellPerWindowOverCellEtaPhiArea
std::vector< double > m_nUnitCellPerWindowOverCellEtaPhiArea
Definition: eflowLayerIntegrator.h:72
eflowTrackCaloPoints.h
eflowLayerIntegrator::m_singleClusterIntegral
std::vector< double > m_singleClusterIntegral
Definition: eflowLayerIntegrator.h:66
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
eflowLayerIntegrator::measureNewClus
void measureNewClus(const xAOD::CaloCluster *clus, const eflowTrackCaloPoints &trackCalo)
Definition: eflowLayerIntegrator.cxx:154
eflowRecTrack
This class extends the information about a xAOD::Track.
Definition: eflowRecTrack.h:45
eflowFirstIntRegions::translateCalo
static J1STLAYER translateCalo(eflowCaloENUM layer)
Definition: eflowCaloRegions.cxx:84
eflowLayerIntegrator::resetAllClustersIntegralForNewTrack
void resetAllClustersIntegralForNewTrack(const eflowTrackCaloPoints &trackCalo)
Definition: eflowLayerIntegrator.cxx:99
eflowLayerIntegrator.h
eflowRecTrack.h
eflowTrackCaloPoints::haveLayer
bool haveLayer(eflowCalo::LAYER layer) const
Definition: eflowTrackCaloPoints.h:61
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
eflowTrackCaloPoints::getEM2eta
double getEM2eta() const
Definition: eflowTrackCaloPoints.h:51
eflowLayerIntegrator::measureCell
void measureCell(const CaloCell *cell, const eflowTrackCaloPoints &trackCalo)
Definition: eflowLayerIntegrator.cxx:193
eflowTrackCaloPoints::getPhi
double getPhi(eflowCalo::LAYER layer) const
Definition: eflowTrackCaloPoints.h:44
lumiFormat.i
int i
Definition: lumiFormat.py:92
python.subdetectors.mmg.database
database
Definition: mmg.py:6
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
TauGNNUtils::Variables::Track::dPhi
bool dPhi(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:530
eflowTrackCaloPoints::getFCAL0eta
double getFCAL0eta() const
Definition: eflowTrackCaloPoints.h:53
eflowRecCluster::getCluster
xAOD::CaloCluster * getCluster()
Definition: eflowRecCluster.h:49
eflowCalo::EMB1
@ EMB1
Definition: eflowCaloRegions.h:45
eflowRecCluster.h
xAOD::CaloCluster_v1::getCellLinks
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
Definition: CaloCluster_v1.cxx:905
eflowLayerIntegrator::m_rMax
double m_rMax
Definition: eflowLayerIntegrator.h:60
CaloDetDescrElement::volume
float volume() const
cell volume
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:381
eflowCalo::nRegions
static const int nRegions
Definition: eflowCaloRegions.h:45
eflowDepthCalculator.h
eflowRecTrack::getTrackCaloPoints
const eflowTrackCaloPoints & getTrackCaloPoints() const
Definition: eflowRecTrack.h:55
eflowLayerIntegrator::m_caloModel
eflowDepthCalculator m_caloModel
Definition: eflowLayerIntegrator.h:68
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
CaloDetDescrElement::dphi
float dphi() const
cell dphi
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:358
eflowLayerIntegrator::~eflowLayerIntegrator
~eflowLayerIntegrator()
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
eflowDatabase
Stores calorimeter cell eta and phi widths, a X0 per unit length in the EM and HAD calorimeters.
Definition: eflowDatabase.h:24
eflowCalo::LAYER
LAYER
Definition: eflowCaloRegions.h:36
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
LegendreWeights.h
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
xAOD::phiWidth
phiWidth
Definition: RingSetConf_v1.cxx:612
eflowLayerIntegrator::getFirstIntLayer
eflowFirstIntENUM getFirstIntLayer() const
Definition: eflowLayerIntegrator.cxx:230
eflowDepthCalculator::DEPTHLAYER
DEPTHLAYER
Definition: eflowDepthCalculator.h:47
eflowLayerIntegrator::operator=
eflowLayerIntegrator & operator=(const eflowLayerIntegrator &originalEflowLayerIntegrator)
Definition: eflowLayerIntegrator.cxx:78
eflowTrackCaloPoints::defaultEta
static double defaultEta()
Definition: eflowTrackCaloPoints.cxx:28
eflowLayerIntegrator::m_allClustersIntegral
std::vector< double > m_allClustersIntegral
Definition: eflowLayerIntegrator.h:65
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
LArCellBinning.phiRange
phiRange
Filling Phi ranges.
Definition: LArCellBinning.py:107
eflowLayerIntegrator::m_integrator
std::unique_ptr< eflowCellIntegrator< 0 > > m_integrator
Definition: eflowLayerIntegrator.h:74
eflowTrackCaloPoints::getEta
double getEta(eflowCalo::LAYER layer) const
Definition: eflowTrackCaloPoints.h:43
TauGNNUtils::Variables::Track::dEta
bool dEta(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:525
error
Definition: IImpactPoint3dEstimator.h:70
eflowCalo::translateSampl
static LAYER translateSampl(CaloCell_ID::CaloSample sampl)
Definition: eflowCaloRegions.cxx:45
eflowRangeBase< double >
eflowLayerIntegrator::measureCluster
void measureCluster(eflowTrackClusterLink *trackClusterLink)
Definition: eflowLayerIntegrator.cxx:160
eflowDepthCalculator::depthIndex
static DEPTHLAYER depthIndex(eflowCaloENUM layer)
Definition: eflowDepthCalculator.cxx:96
eflowCaloENUM
eflowCalo::LAYER eflowCaloENUM
Definition: eflowCaloRegions.h:49
eflowFirstIntRegions::J1STLAYER
J1STLAYER
Definition: eflowCaloRegions.h:58