ATLAS Offline Software
PUSplitPufitFex.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3  */
4 /******************************************************************************
5  * @package Trigger/TrigAlgorithms/TrigEFMissingET
6  * @file PUSplitPufitFex.cxx
7  *
8  * Implementation of pileup-split pufit fex class
9  * @author Jon Burr
10  *****************************************************************************/
11 
12 #include "PUSplitPufitFex.h"
18 
19 namespace HLT
20 {
21  namespace MET
22  {
23  double PUSplitPufitFex::getSigma(const SignedKinematics &kin) const
24  {
25  return m_caloNoise * m_caloNoise + kin.absPt() * m_caloStoch * m_caloStoch;
26  }
27 
28  PUSplitPufitFex::PUSplitPufitFex(const std::string &name, ISvcLocator *pSvcLocator)
29  : FexBase(name, pSvcLocator)
30  {
31  }
32 
34  {
35  CHECK(m_inputKey.initialize());
36 
37  // Update the decor keys if necessary
38  if (m_inputCategoryKey.key().find(".") == std::string::npos)
39  m_inputCategoryKey = m_inputKey.key() + "." + m_inputCategoryKey.key();
40  else if (SG::contKeyFromKey(m_inputCategoryKey.key()) != m_inputKey.key())
41  {
42  ATH_MSG_ERROR("Input category key does not match the input key!");
43  return StatusCode::FAILURE;
44  }
45  CHECK(m_inputCategoryKey.initialize());
46  return initializeBase({"NeutralForward", "ChargedHS", "ChargedPU", "UncorrSelNF"});
47  }
48 
51  const EventContext &context,
52  MonGroupBuilder &) const
53  {
54  // Retrieve the input
55  auto input = SG::makeHandle(m_inputKey, context);
56  if (!input.isValid())
57  {
58  ATH_MSG_ERROR("Failed to retrieve " << m_inputKey);
59  return StatusCode::FAILURE;
60  }
61  auto categoryAcc = SG::makeHandle<int>(m_inputCategoryKey, context);
62 
63  // Create the gridset
64  PUSplitGridSet gridset(m_maxEta, m_nEtaBins, m_nPhiBins);
65 
66  // Fill the grids from the input objects
67  for (const xAOD::IParticle *ipart : *input)
68  {
70  SignedKinematics kin = SignedKinematics::fromEnergyEtaPhi(
71  ipart->e(), ipart->eta(), ipart->phi());
72  switch (type)
73  {
75  gridset.get<PUClassification::NeutralForward>() += kin;
76  break;
78  gridset.get<PUClassification::ChargedHS>() += kin;
79  break;
81  gridset.get<PUClassification::ChargedPU>() += kin;
82  break;
83  default:
84  ATH_MSG_ERROR("Invalid PU category: " << type);
85  return StatusCode::FAILURE;
86  }
87  }
88 
89  // Calculate the mean and variance from the 'nominal' grid
90  double mean;
91  double variance;
93  gridset[NoDisplacement], m_neutralThresholdMode, m_trimFraction, mean, variance);
94  // Calculate the threshold
95  double threshold = mean + m_nSigma * sqrt(variance);
96 
97  // Mask towers above the threshold
98  std::size_t count = 0;
99  for (PUSplitGrid &grid : gridset.grids)
100  for (PUSplitGrid::Tower &tower : grid)
101  if (tower.sumEt(m_neutralThresholdMode) > threshold)
102  {
103  tower.mask(true);
104  ++count;
105  }
106  if (msgLvl(MSG::DEBUG))
107  {
108  ATH_MSG_DEBUG("NeutralForward: " << gridset[NoDisplacement].get<PUClassification::NeutralForward>().sum());
109  ATH_MSG_DEBUG("ChargedHS: " << gridset[NoDisplacement].get<PUClassification::ChargedHS>().sum());
110  ATH_MSG_DEBUG("ChargedPU: " << gridset[NoDisplacement].get<PUClassification::ChargedPU>().sum());
111  ATH_MSG_DEBUG("Mean, variance, threshold = " << mean << ", " << variance << ", " << threshold);
112  ATH_MSG_DEBUG(count << "/" << gridset[NoDisplacement].get<1>().nTowers() << " towers above threshold");
113  }
114 
115 
116  // Select the right grid
118  gridset, m_neutralThresholdMode);
119  const PUSplitGrid &grid = gridset[displacement];
120 
121  // Build the background sum, the masked tower kinematics (used for their
122  // directions), the list of the expected pileup values in each masked tower
123  // and the variances on each of those expected values
124  PufitUtils::CovarianceSum pileupSum;
125  std::vector<SignedKinematics> masked;
126  masked.reserve(count);
127  std::vector<double> means;
128  means.reserve(count);
129  std::vector<double> variances(count, variance);
130 
131  for (const PUSplitGrid::Tower &tower : grid)
132  {
133  const SignedKinematics &cPUKin = tower.get<PUClassification::ChargedPU>();
134  if (!tower.masked())
135  {
136  // If the tower is masked, then add its neutral component to the background sum
137  const SignedKinematics &kin = tower.get<PUClassification::NeutralForward>();
138  pileupSum.add(kin, getSigma(kin));
139  }
140  else
141  {
142  masked.push_back(tower.kinematics(PUClassification::NFcHS));
143  // Add the expected pileup contribution. Optionally, exclude the cPU
144  // component from this as this is already accounted
145  if (m_subtractCPUFromMean)
146  means.push_back(mean - cPUKin.pt());
147  else
148  means.push_back(mean);
149  }
150  // cPU elements always count as background
151  // (There's a possible TODO here - maybe this should only be done when subtractCPUFromMean is true?)
152  pileupSum.add(cPUKin, getSigma(cPUKin));
153  }
154 
155  if (msgLvl(MSG::VERBOSE))
156  {
157  ATH_MSG_VERBOSE("Pileup sum = " << pileupSum.sum);
158  ATH_MSG_VERBOSE("Pileup covariance = " << pileupSum.covariance);
159  ATH_MSG_VERBOSE("Mean background energy = " << mean);
160  ATH_MSG_VERBOSE("Background energy variance = " << variance);
161  ATH_MSG_VERBOSE("Constraint importance = " << m_constraintImportance);
162  ATH_MSG_VERBOSE("Masked tower directions (sin, cos): ");
163  for (const SignedKinematics &kin : masked)
164  ATH_MSG_VERBOSE(" (" << kin.sinPhi() << ", " << kin.cosPhi() << ")");
165  }
166  // Fill components
167  grid.get<PUClassification::NeutralForward>().sum(PufitGrid::SumStrategy::All).fillMETComponent(0, met);
168  grid.get<PUClassification::ChargedHS>().sum(PufitGrid::SumStrategy::All).fillMETComponent(1, met);
169  grid.get<PUClassification::ChargedPU>().sum(PufitGrid::SumStrategy::All).fillMETComponent(2, met);
170  grid.get<PUClassification::NeutralForward>().sum(PufitGrid::SumStrategy::Masked).fillMETComponent(3, met);
171 
172  // Now build the final sum
173  METComponent sum;
174  // Add the NF components of all masked towers
175  sum += grid.get<PUClassification::NeutralForward>().sum(PufitGrid::SumStrategy::Masked);
176  // Add the cHS components of all towers
178 
179  if (variance != 0)
180  {
181  ATH_MSG_DEBUG("Calculate corrections");
182  std::vector<SignedKinematics> corrections = PufitUtils::pufit(
183  pileupSum.sum,
184  pileupSum.covariance,
185  means,
186  variances,
187  masked,
188  m_constraintImportance);
189 
190  ATH_MSG_DEBUG("Before corrections: " << sum);
191  // Add the corrections
192  for (const SignedKinematics &kin : corrections)
193  {
194  ATH_MSG_DEBUG("Correction: (px, py, pz, et) = (" << kin.px() << ", " << kin.py() << ", " << kin.pz() << ", " << kin.et() << ")");
195  sum += kin;
196  }
197  }
198  else
199  ATH_MSG_DEBUG("Tower variance is 0 => there were no towers in the trimmed mean calculation with energy > 0. Skip the corrections");
200  ATH_MSG_DEBUG("Final MET: " << sum);
201  sum.fillMET(met);
202 
203  return StatusCode::SUCCESS;
204  }
205  } // namespace MET
206 } // namespace HLT
METComponent.h
SG::contKeyFromKey
std::string contKeyFromKey(const std::string &key)
Extract the container part of key.
Definition: DecorKeyHelpers.cxx:26
HLT::MET::PufitUtils::pufit
Eigen::VectorXd pufit(const Eigen::Vector2d &pileupSum, const Eigen::Matrix2d &pileupCovariance, const Eigen::VectorXd &towerExpectations, const Eigen::VectorXd &towerVariances, const Eigen::VectorXd &correctionDirections, double constraintImportance)
Perform the pile-up fit.
Definition: PufitUtils.cxx:114
PUClassification.NeutralForward
NeutralForward
Definition: PUClassification.py:8
mean
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
Definition: dependence.cxx:254
HLT::MET::PUSplitPufitFex::m_caloStoch
Gaudi::Property< float > m_caloStoch
The coefficient of the stochastic term in the calo resolution estimate.
Definition: PUSplitPufitFex.h:105
initialize
void initialize()
Definition: run_EoverP.cxx:894
PUClassification.ChargedHS
ChargedHS
Definition: PUClassification.py:12
HLT::MET::PUClassification::PUClassification
PUClassification
Definition: PUClassification.h:17
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:40
PUClassification.NFcHS
NFcHS
Definition: PUClassification.py:15
DecorKeyHelpers.h
Some common helper functions used by decoration handles.
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
HLT::MET::NoDisplacement
@ NoDisplacement
The grid is not shifted.
Definition: PeriodicGridBase.h:25
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:270
HLT::MET::GridDisplacement
GridDisplacement
Enum to describe the positioning of the grid.
Definition: PeriodicGridBase.h:23
PUSplitGrid.h
HLT::MET::PUSplitPufitFex::getSigma
double getSigma(const SignedKinematics &kin) const
Calculate the estimate on the variance of a tower.
Definition: PUSplitPufitFex.cxx:35
met
Definition: IMETSignificance.h:24
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
HLT::MET::SignedKinematics
Class to describe the kinematics of an object that can have negative energies.
Definition: SignedKinematics.h:42
HLT
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...
Definition: HLTResultReader.h:26
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
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
PufitUtils.h
TCS::MET
@ MET
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/L1TopoCommon/Types.h:16
HLT::MET::PufitUtils::selectGrid
GridDisplacement selectGrid(const PufitGridSet &grids)
Select the grid with the highest masked sumEt.
Definition: PufitUtils.cxx:95
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
PUClassification.ChargedPU
ChargedPU
Definition: PUClassification.py:10
HLT::MET::PufitUtils::trimmedMeanAndVariance
void trimmedMeanAndVariance(const std::vector< double > &sorted, double trimFraction, double &mean, double &variance)
Calculate the trimmed mean and variance for a vector of tower sumEts.
Definition: PufitUtils.cxx:35
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
threshold
Definition: chainparser.cxx:74
xAOD::TrigMissingET_v1
Class holding the Missing ET trigger fex results.
Definition: TrigMissingET_v1.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
DEBUG
#define DEBUG
Definition: page_access.h:11
ReadDecorHandle.h
Handle class for reading a decoration on an object.
PUSplitPufitFex.h
met::fillMET
StatusCode fillMET(xAOD::MissingET *&met, xAOD::MissingETContainer *metCont, const std::string &metKey, const MissingETBase::Types::bitmask_t metSource)
Definition: METHelpers.cxx:123
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
HLT::MET::PUSplitPufitFex::PUSplitPufitFex
PUSplitPufitFex(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Definition: PUSplitPufitFex.cxx:40
xAOD::JetInput::Tower
@ Tower
Definition: JetContainerInfo.h:58
HLT::MET::PufitMultiGridSet
Helper struct to forward the SignedKinematics operators nicely.
Definition: PufitMultiGrid.h:316
PUClassification.All
All
Definition: PUClassification.py:17
HLT::MET::PUSplitPufitFex::m_caloNoise
Gaudi::Property< float > m_caloNoise
The coefficient of the noise term in the calo resolution estimate.
Definition: PUSplitPufitFex.h:101