ATLAS Offline Software
Loading...
Searching...
No Matches
eflowCaloObject.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5/********************************************************************
6
7NAME: eflowCaloObject.cxx
8PACKAGE: offline/Reconstruction/eflowRec
9
10AUTHORS: D.R.Tovey, M.Hodgkinson and T.Velz
11CREATED: 22nd November, 2004
12
13********************************************************************/
14
15#include "eflowCaloObject.h"
16#include "eflowRecTrack.h"
17#include "eflowRecCluster.h"
23
24#include "GaudiKernel/EventContext.h"
25
27
28void eflowCaloObject::addTrackClusterLinks(const std::vector<eflowTrackClusterLink*> &trackClusterLink) {
29 for (auto *ptr : trackClusterLink) {
31 }
32}
33
34 void eflowCaloObject::addTracks(const std::vector<eflowRecTrack*> &tracks) {
35 m_eflowRecTracks.insert(m_eflowRecTracks.end(), tracks.begin(), tracks.end());
36 }
37
38 void eflowCaloObject::addClusters(const std::vector<eflowRecCluster*> &clusters) {
39 m_eflowRecClusters.insert(m_eflowRecClusters.end(), clusters.begin(), clusters.end());
40 }
41
43 double expectedEnergy(0.0);
44 for(unsigned iTrack=0; iTrack < nTracks(); ++iTrack) {
45 if (!efRecTrack(iTrack)->isInDenseEnvironment()) expectedEnergy += efRecTrack(iTrack)->getEExpect();
46 }
47 return expectedEnergy;
48}
49
51 double expectedVariance(0.0);
52 for(unsigned iTrack=0; iTrack < nTracks(); ++iTrack) {
53 if (!efRecTrack(iTrack)->isInDenseEnvironment()) expectedVariance += efRecTrack(iTrack)->getVarEExpect();
54 }
55 return expectedVariance;
56}
57
59 double clusterEnergy(0.0);
60 for(unsigned iCluster=0; iCluster < nClusters(); ++iCluster) {
61 clusterEnergy += efRecCluster(iCluster)->getCluster()->e();
62 }
63 return clusterEnergy;
64}
65
66void eflowCaloObject::simulateShower(const EventContext& ctx, eflowLayerIntegrator *integrator, const eflowEEtaBinnedParameters* binnedParameters,
67const PFEnergyPredictorTool* energyP, bool useLegacyEnergyBinIndexing){
68
69 for (auto *thisEfRecTrack : m_eflowRecTracks) {
70
71 std::vector<eflowRecCluster*> matchedClusters;
72 const std::vector<eflowTrackClusterLink*>& links = thisEfRecTrack->getClusterMatches();
73 for (auto* itLink : links) {
74 matchedClusters.push_back(itLink->getCluster());
75 }
76
77 double trackEM1eta = thisEfRecTrack->getTrackCaloPoints().getEM1eta();
78 /* if a track is in the forward EM (2.5 < eta < 3.2) then there is no EM1 -> need to use EM2 */
79 if(trackEM1eta<-998.) trackEM1eta = thisEfRecTrack->getTrackCaloPoints().getEM2eta();
80 /* if a track is not in the EM region (3.2 < eta < 4.0) then should use FCAL0 */
81 if(trackEM1eta<-998.) trackEM1eta = thisEfRecTrack->getTrackCaloPoints().getFCAL0eta();
82
83 double trackE = thisEfRecTrack->getTrack()->e();
84
85 if (!binnedParameters->binExists(trackE, trackEM1eta)) {
86 thisEfRecTrack->setHasBin(false);
87 return;
88 }
89
90 /* Determine the LFI */
91 integrator->measureNewClus(ctx, matchedClusters, thisEfRecTrack);
92 eflowFirstIntENUM j1st = integrator->getFirstIntLayer();
93
94 /*Save j1st info */
95 thisEfRecTrack->setLayerHED(j1st);
96
97 /* Get parameters for j1st */
98 eflowRingSubtractionManager& cellSubtractionManager = thisEfRecTrack->getCellSubtractionManager();
99 cellSubtractionManager.getOrdering(binnedParameters, trackE, trackEM1eta, j1st,useLegacyEnergyBinIndexing);
100
101 /* Set expected energy in the eflowRecTrack object */
102 const double expectedEnergy = energyP ? energyP->nnEnergyPrediction(thisEfRecTrack) : cellSubtractionManager.fudgeMean() * thisEfRecTrack->getTrack()->e();
103 const double expectedEnergySigma = std::fabs(cellSubtractionManager.fudgeStdDev() * thisEfRecTrack->getTrack()->e());
104
105 const std::vector<eflowTrackClusterLink*>* bestClusters_015 = thisEfRecTrack->getAlternativeClusterMatches("cone_015");
106 const std::vector<eflowTrackClusterLink*>* bestClusters_02 = thisEfRecTrack->getAlternativeClusterMatches("cone_02");
107
108 //First we calculate how much energy is found in a cone of 0.15
109 float totalE_015 = 0.0;
110
111 //This pointer can be a nullptr if no clusters were matched to a track in dR < 0.15
112 if (bestClusters_015){
113 for (eflowTrackClusterLink* thisLink : *bestClusters_015){
114 eflowRecCluster* thisBestCluster = thisLink->getCluster();
115 if (thisBestCluster){
116 const xAOD::CaloCluster* theCluster = thisBestCluster->getCluster();
117 if (theCluster) {
118 if (theCluster->e()>0.0){
119 totalE_015 += theCluster->e();
120 }
121 }
122 }
123 }
124 }//if vector of 0.15 clusters exists
125
126 double pull_015 = NAN;
127 if (expectedEnergySigma > 1e-6 ) pull_015 = (totalE_015-expectedEnergy)/expectedEnergySigma;
128 thisEfRecTrack->setpull15(pull_015);
129
130 double trackPt = thisEfRecTrack->getTrack()->pt();
131 //If the looked up expected energy deposit was 0.0, then pull_015 is NAN. In that case we should not try to apply the 2D cut described below.
132 if (!std::isnan(pull_015)){
133 //We use a 2D cut in the pull_015 and log10 of track pt plane to define a dense environment - if too dense then we disable the charged shower subtraction
134 //The cut values are such that above a track pt of 40 GeV we are very agrressive about disabling the cell by cell charged shower subtraction.
135 //The specific cut values were found by optimising the jet resolutions in the run 2 data taking environment.
136 //Further details can be found in these slides from C. Young:
137 //https://indico.cern.ch/event/396923/contributions/949333/attachments/795878/1090871/Presentation.pdf
138 if (pull_015 > 0.0 + (log10(40000)-log10(trackPt))*33.2 && 0.0 != expectedEnergySigma && bestClusters_015 && bestClusters_02){
139 thisEfRecTrack->setSubtracted(); //this tricks eflowRec into thinking this track was subtracted, and hence no further subtraction will be done
140 thisEfRecTrack->setIsInDenseEnvironment();
141 //recalculate the LHED and the ordering and find the new expected E + sigma of expected E (the new LHED can change the latter two values we find in the look up tables)
142 //we use a larger cone of 0.2 for this
143 std::vector<eflowRecCluster*> theBestEfRecClusters_02;
144 for (eflowTrackClusterLink* thisLink : *bestClusters_02) if (thisLink->getCluster()->getCluster()->e() > 0.0) theBestEfRecClusters_02.push_back(thisLink->getCluster());
145 integrator->measureNewClus(ctx, theBestEfRecClusters_02, thisEfRecTrack);
146 j1st = integrator->getFirstIntLayer();
147 cellSubtractionManager.getOrdering(binnedParameters, trackE, trackEM1eta, j1st,useLegacyEnergyBinIndexing);
148 thisEfRecTrack->setEExpect(cellSubtractionManager.fudgeMean() * trackE, std::fabs(cellSubtractionManager.fudgeStdDev()*trackE)*std::fabs(cellSubtractionManager.fudgeStdDev()*trackE));
149 }
150 else {
151 thisEfRecTrack->setEExpect(expectedEnergy, expectedEnergySigma*expectedEnergySigma);
152 }//ok to do subtraction, and so we just set the usual expected E + sigma of expected E needed for subtraction
153 }
154 }
155}
float nnEnergyPrediction(const eflowRecTrack *ptr) const
void simulateShower(const EventContext &ctx, eflowLayerIntegrator *integrator, const eflowEEtaBinnedParameters *binnedParameters, const PFEnergyPredictorTool *energyP, bool useLegacyEnergyBinIndexing)
void addTracks(const std::vector< eflowRecTrack * > &tracks)
double getExpectedVariance() const
std::vector< eflowRecTrack * > m_eflowRecTracks
double getClusterEnergy() const
void addTrackClusterLinks(const std::vector< eflowTrackClusterLink * > &trackClusterLink)
void addClusters(const std::vector< eflowRecCluster * > &clusters)
void addTrackClusterLink(eflowTrackClusterLink *trackClusterLink)
unsigned nClusters() const
const eflowRecTrack * efRecTrack(int i) const
std::vector< eflowRecCluster * > m_eflowRecClusters
unsigned nTracks() const
double getExpectedEnergy() const
const eflowRecCluster * efRecCluster(int i) const
bool binExists(double e, double eta) const
Inherits from eflowEEtaBinBase.
This class calculates the LHED (Layer of Highest Energy Density) in a cluster or group of clusters.
void measureNewClus(const xAOD::CaloCluster *clus, const eflowTrackCaloPoints &trackCalo)
eflowFirstIntENUM getFirstIntLayer() const
This class extends the information about a xAOD::CaloCluster.
xAOD::CaloCluster * getCluster()
double getEExpect() const
double getVarEExpect() const
This stores information, a rank and ring thickness, about cell rings in an ordered way.
bool getOrdering(const eflowEEtaBinnedParameters *binnedParameters, double e, double eta, eflowFirstIntENUM j1st, bool useLegacyEnergyBinIndexing)
virtual double e() const
The total energy of the particle.
eflowFirstIntRegions::J1STLAYER eflowFirstIntENUM
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.