ATLAS Offline Software
MissingETObjectCollectionMaker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3  */
4 
8 #include "TopEvent/EventTools.h"
10 
11 
14 #include "xAODMuon/MuonContainer.h"
16 #include "xAODJet/JetContainer.h"
20 #include "xAODCore/ShallowCopy.h"
22 
23 namespace top {
25  asg::AsgTool(name),
26  m_config(nullptr),
27 
28  m_specifiedSystematics(),
29  m_recommendedSystematics(),
30 
31  m_MET_core("setMe"),
32  m_met_maker("met::METMaker"),
33  m_met_systematics("met::METSystematicsTool"),
34  m_metSignif("metSignificance"){
35  declareProperty("config", m_config);
36  declareProperty("METMaker", m_met_maker);
37  declareProperty("met_systematics", m_met_systematics);
38  declareProperty("metSignificance", m_metSignif);
39  }
40 
42  ATH_MSG_INFO(" top::MissingETObjectCollectionMaker initialize");
43 
44  top::check(m_met_maker.retrieve(), "Failed to retrieve met maker tool");
45  top::check(m_met_systematics.retrieve(), "Failed to retrieve met systematic tool");
46  if (m_config->METSignificance()) top::check(m_metSignif.retrieve(), "Failed to retrieve metSignificance!");
47 
48  std::string jet_collection = m_config->sgKeyJets();
49  jet_collection.erase(jet_collection.length() - 4); //erase "Jets" from jet collection name
50 
51  m_MET_core = "MET_Core_" + jet_collection;
52 
54  const std:: string& syststr = m_config->systematics();
55  std::set<std::string> syst;
56 
57  if (!m_config->isSystNominal(syststr) && !m_config->isSystAll(syststr)) {
58  bool ok = m_config->getSystematicsList(syststr, syst);
59  if (!ok) {
60  ATH_MSG_ERROR(" top::MissingETObjectCollectionMaker could not determine systematic list");
61  return StatusCode::FAILURE;
62  }
63  //here the idea is that if the user specifies AllXXX, we leave syst as an empty string, so that all recommended CP
64  // systematics are then used
65  if (m_config->contains(syst, "AllMET")) {
66  syst.clear();
67  }
68  }
69 
71 
72  m_config->systematicsMET(specifiedSystematics());
73 
74  return StatusCode::SUCCESS;
75  }
76 
78  // met core contains the soft terms we need to add to our met calculation
79  const xAOD::MissingETContainer* xaod_met_core(nullptr);
80 
81  top::check(evtStore()->retrieve(xaod_met_core, m_MET_core), "Failed to retrieve MET Core");
82 
83  if (m_config->doTightEvents()) {
84  // All the tight systematic events
85  const xAOD::SystematicEventContainer* systEvents(nullptr);
86  if (executeNominal) {
87  top::check(evtStore()->retrieve(systEvents,
88  m_config->sgKeyTopSystematicEvents() + "Nominal"),
89  "Failed to retrieve nominal TopEvents");
90  } else {
91  top::check(evtStore()->retrieve(systEvents,
92  m_config->sgKeyTopSystematicEvents()), "Failed to retrieve TopEvents");
93  }
94  for (auto x : *systEvents) {
96  if (!executeNominal && m_config->isSystNominal(m_config->systematicName(x->hashValue()))) continue;
97  if (executeNominal && !m_config->isSystNominal(m_config->systematicName(x->hashValue()))) continue;
98  top::check(recalculateEventMET(x, xaod_met_core), "Failed to recalculate MET for event");
99  if(m_config->writeMETBuiltWithLooseObjects()) top::check(recalculateEventMET(x, xaod_met_core, true, "WithLooseObjects"), "Failed to recalculate MET using loose leptons for event");
100  }
101  } // tight events
102  if (m_config->doLooseEvents()) {
103  // All the loose systematic events
104  const xAOD::SystematicEventContainer* systEventsLoose(nullptr);
105  if (executeNominal) {
106  top::check(evtStore()->retrieve(systEventsLoose,
107  m_config->sgKeyTopSystematicEventsLoose() + "Nominal"),
108  "Failed to retrieve nominal TopEventsLoose");
109  } else {
110  top::check(evtStore()->retrieve(systEventsLoose,
111  m_config->sgKeyTopSystematicEventsLoose()),
112  "Failed to retrieve TopEventsLoose");
113  }
114 
115  for (auto x : *systEventsLoose) {
117  if (!executeNominal && m_config->isSystNominal(m_config->systematicName(x->hashValue()))) continue;
118  if (executeNominal && !m_config->isSystNominal(m_config->systematicName(x->hashValue()))) continue;
119  top::check(recalculateEventMET(x, xaod_met_core), "Failed to recalculate MET for loose event");
120  if(m_config->writeMETBuiltWithLooseObjects()) top::check(recalculateEventMET(x, xaod_met_core, true, "WithLooseObjects"), "Failed to recalculate MET using loose leptons for event");
121  }
122  } // Loose events
123 
124  return StatusCode::SUCCESS;
125  }
126 
128  const xAOD::MissingETContainer* xaod_met_core,
129  const bool forceUseLooseObjects,
130  const std::string& outputContainerSuffix) {
131  // decoration for objects that pass pre OR selection
132  std::string passPreORSelection = "passPreORSelection";
133  std::string jet_collection = m_config->sgKeyJets();
134  jet_collection.erase(jet_collection.length() - 4); //erase "Jets" from jet collection name
135 
136  const bool is_loose_event = (event->isLooseEvent() == 1 ? true : false);
137 
138  // default behaviour for top analysis - use the "Tight" definitions
139  bool looseLeptonOR(is_loose_event);
140  if (m_config->doOverlapRemovalOnLooseLeptonDef() || (is_loose_event && m_config->useLooseObjectsInMETInLooseTree()) || (!is_loose_event && m_config->useLooseObjectsInMETInNominalTree()) || forceUseLooseObjects) {
141  looseLeptonOR = true;
142  // change decoration we check
143  passPreORSelection = "passPreORSelectionLoose";
144  }
145 
146  const std::size_t hash = event->hashValue();
147 
148  // Make a new MET container that we are going to use
149  xAOD::MissingETContainer* new_met_container = new xAOD::MissingETContainer();
150  xAOD::MissingETAuxContainer* new_met_aux_container = new xAOD::MissingETAuxContainer();
151  new_met_container->setStore(new_met_aux_container);
152 
153  const xAOD::MissingETAssociationMap* metMap(nullptr);
154  const std::string metAssocKey = "METAssoc_" + jet_collection;
155  top::check(evtStore()->retrieve(metMap, metAssocKey), "Failed to retrive MET map");
156  xAOD::MissingETAssociationHelper metHelper(metMap);
157 
158  // Reset all the met map associations
159  metHelper.resetObjSelectionFlags();
160 
161  // Apparently we need to add objects to the METMaker in a specific order
162  // Start by retrieving jet container, we need it to perform e-jet ghost-matching
163  // 1. Electrons
164  const xAOD::ElectronContainer* xaod_el(nullptr);
165  if (m_config->useElectrons()) {
166  // Get all calibrated electrons
167  top::check(evtStore()->retrieve(xaod_el, m_config->sgKeyElectrons(hash)), "Failed to retrieve Electrons");
168 
169  // Add those that pass pre-overlap removal selection to met_electrons
171  for (const auto *el: *xaod_el)
172  if (el->isAvailable<char>(passPreORSelection)
173  && el->auxdata<char>(passPreORSelection) == 1) met_electrons.push_back(el);
174 
175  // Recalculate electron MET term using electrons that pass overlap removal
176  top::check(m_met_maker->rebuildMET("RefEle",
178  new_met_container,
179  met_electrons.asDataVector(),
180  metHelper),
181  "Failed to rebuild electron MET term");
182  }
183 
184  // 2. Photons
185  if (m_config->usePhotons()) {
186  // Get calibrated photons
187  const xAOD::PhotonContainer* xaod_photon(nullptr);
188  top::check(evtStore()->retrieve(xaod_photon, m_config->sgKeyPhotons(hash)), "Failed to retrieve Photons");
189 
190  // Add those that pass pre-overlap removal to met_photons
192  for (const auto *photon: *xaod_photon)
193  if (photon->isAvailable<char>(passPreORSelection)
194  && photon->auxdata<char>(passPreORSelection) == 1) met_photons.push_back(photon);
195 
196  top::check(m_met_maker->rebuildMET("RefPhoton",
198  new_met_container,
199  met_photons.asDataVector(),
200  metHelper),
201  "Failed to rebuild photon MET term");
202  }
203 
204  // 3. Taus
205  if (m_config->useTaus()) {
206  // Get calibrated taus
207  const xAOD::TauJetContainer* xaod_tau(nullptr);
208  top::check(evtStore()->retrieve(xaod_tau, m_config->sgKeyTaus(hash)), "Failed to retrieve Taus");
209 
210  // Add those that pass pre-overlap removal to met_taus
212  for (const auto *tau: *xaod_tau)
213  if (tau->isAvailable<char>(passPreORSelection)
214  && tau->auxdata<char>(passPreORSelection) == 1) met_taus.push_back(tau);
215 
216  top::check(m_met_maker->rebuildMET("RefTau",
218  new_met_container,
219  met_taus.asDataVector(),
220  metHelper),
221  "Failed to rebuild tau MET term");
222  }
223 
224  xAOD::JetContainer* xaod_jet(nullptr);
225  top::check(evtStore()->retrieve(xaod_jet, m_config->sgKeyJets(hash, looseLeptonOR)), "Failed to retrieve Jets");
226  // 4. Muons
227  const xAOD::MuonContainer* xaod_mu(nullptr); // Need these for ghost matching
228  if (m_config->useMuons()) {
229  // Get calibrated muons
230  top::check(evtStore()->retrieve(xaod_mu, m_config->sgKeyMuons(hash)), "Failed to retrieve Muons");
231  if (not xaod_mu){
232  return StatusCode::FAILURE;
233  }
234  // Add those that pass pre-overlap removal to met_muons
236  for (const auto *mu: *xaod_mu)
237  if (mu->isAvailable<char>(passPreORSelection)
238  && mu->auxdata<char>(passPreORSelection) == 1) met_muons.push_back(mu);
239 
240  // Recalculate muon MET term using muons that pass overlap removal
241  top::check(m_met_maker->rebuildMET("RefMuon",
243  new_met_container,
244  met_muons.asDataVector(),
245  metHelper),
246  "Failed to rebuild muon MET term");
247 
248  // Muon-jet ghost association
249  // performed after muon handing to METUtility, but before jets
250  if (xaod_jet) {
251  met::addGhostMuonsToJets(*xaod_mu, *xaod_jet);
252  }
253  } else {
255  top::check(m_met_maker->rebuildMET("RefMuon",
257  new_met_container,
258  met_muons.asDataVector(),
259  metHelper),
260  "Failed to rebuild muon MET term");
261  }
262 
263 
264  // 5. Jets
265  // We do not perfom any selection on jets here. Give them all to the METMaker, it does its own thing
266  top::check(m_met_maker->rebuildJetMET("RefJet",
267  "SoftClus",
268  "PVSoftTrk",
269  new_met_container,
270  xaod_jet,
271  xaod_met_core,
272  metHelper,
273  m_config->doJVTinMET()),
274  "Failed to rebuild jet MET term");
275 
276 
277 
278  for (const auto & systematic : m_specifiedSystematics) {
279  if (systematic.hash() == event->hashValue() && systematic.hash() != m_config->nominalHashValue()) {
281  top::check(m_met_systematics->applySystematicVariation(systematic), "Failed to applySystematicVariation");
282 
283  // code lifted and modified from:
284  // https://svnweb.cern.ch/trac/atlasoff/browser/Reconstruction/MET/METUtilities/tags/METUtilities-00-01-43/util/example_METMaker_METSystematicsTool.cxx
285 
286  //get the soft cluster term, and applyCorrection
287  xAOD::MissingET* softClusMet = (*new_met_container)["SoftClus"];
288  if (softClusMet != nullptr) { //check we retrieved the clust term
289  m_met_systematics->setRandomSeed(static_cast<int>(1e6*softClusMet->phi()));
290  top::check(m_met_systematics->applyCorrection(*softClusMet, metHelper), "Failed to applyCorrection");
291  }
292 
293  xAOD::MissingET* softTrkMet = (*new_met_container)["PVSoftTrk"];
294  if (softTrkMet != nullptr) { //check we retrieved the soft trk
295  m_met_systematics->setRandomSeed(static_cast<int>(1e6*softTrkMet->phi()));
296  top::check(m_met_systematics->applyCorrection(*softTrkMet, metHelper), "Failed to applyCorrection");
297  }
298  }
299  }
300 
301  // This will sum up all the contributions we've made so far e.g.
302  // Total MET = RefEle + RefPhoton + RefTau + RefMuon + RefJet + PVSoftTrk (Track Soft Term)
303  top::check(met::buildMETSum("FinalTrk",
304  new_met_container,
306  "Failed to rebuild Final Track MET");
307  if(m_config->METSignificance()){
308  const xAOD::EventInfo* eventInfo(nullptr);
309  top::check(evtStore()->retrieve(eventInfo, m_config->sgKeyEventInfo()), "failded to retrieve event info obj");
310  // met significance
311  top::check(m_metSignif->varianceMET(new_met_container, eventInfo->averageInteractionsPerCrossing(), "RefJet", "PVSoftTrk","FinalTrk"), "Failed to execute MetSignificance::varianceMET!");
312 
313  for (auto mets : *new_met_container){
314  mets->auxdecor<float>("metSigET") = m_metSignif->GetMETOverSqrtSumET();
315  mets->auxdecor<float>("metSigHT") = m_metSignif->GetMETOverSqrtHT();
316  mets->auxdecor<float>("metSig") = m_metSignif->GetSignificance();
317  mets->auxdecor<float>("metSigRho") = m_metSignif->GetRho();
318  mets->auxdecor<float>("metSigVarL") = m_metSignif->GetVarL();
319  mets->auxdecor<float>("metSigVarT") = m_metSignif->GetVarT();
320  }
321  }
322 
323  /************************************************************
324  // We are only going to build a single MET Sum now for clarity. The final argument is the soft term we
325  // want to use. The recommended one is the track soft term (TST) as above.
326 
327  top::check(mer::buildMETSum("FinalClus", new_met_container, MissingETBase::Source::EMTopo),
328  "Failed to rebuild Final Cluster MET");
329  ************************************************************/
330 
331  // Save corrected xAOD Container to StoreGate / TStore
332  std::string outputSGKey = m_config->sgKeyMissingEt(hash);
333  if (is_loose_event) outputSGKey = m_config->sgKeyMissingEtLoose(hash);
334 
335  outputSGKey+=outputContainerSuffix;
336  const std::string outputSGKeyAux = outputSGKey + "Aux.";
337 
338  StatusCode save = evtStore()->tds()->record(new_met_container, outputSGKey);
339  StatusCode saveAux = evtStore()->tds()->record(new_met_aux_container, outputSGKeyAux);
340 
341  if (save.isFailure() || saveAux.isFailure()) {
342  return StatusCode::FAILURE;
343  }
344 
345 
346  return StatusCode::SUCCESS;
347  }
348 
349  void MissingETObjectCollectionMaker::specifiedSystematics(const std::set<std::string>& specifiedSystematics) {
351  const std::vector<CP::SystematicSet> systList = CP::make_systematics_vector(
352  m_met_systematics->recommendedSystematics());
353 
354  for (auto s : systList) {
355 
356  if(!m_config->getTreeFilter()->filterTree(s.name())) continue; // Applying tree filter
357 
360  if (s.name().find("SoftCalo") == std::string::npos) {
361  m_recommendedSystematics.push_back(s);
362  if (s.name() == "") {
363  m_specifiedSystematics.push_back(s);
364  }
365 
367  if (m_config->isMC()) {
369  if (!m_config->isSystNominal(m_config->systematics())) {
370  if (specifiedSystematics.size() == 0) {
371  m_specifiedSystematics.push_back(s);
372  }
373  if (specifiedSystematics.size() > 0) {
374  for (auto i : specifiedSystematics) {
376  if (!filter.filterTree(s.name())) {
377  m_specifiedSystematics.push_back(s);
378  }
379  }
380  }
381  }
382  }
383  }
384  }
386  m_recommendedSystematics.unique();
387  m_specifiedSystematics.sort();
388  m_specifiedSystematics.unique();
389  }
390 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
ShallowCopy.h
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
xAOD::Electron
Electron_v1 Electron
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Electron.h:17
top
TopConfig A simple configuration that is NOT a singleton.
Definition: AnalysisTrackingHelper.cxx:58
xAOD::MissingETAuxContainer
MissingETAuxContainer_v1 MissingETAuxContainer
Definition: MissingETAuxContainer.h:16
top::MissingETObjectCollectionMaker::m_metSignif
ToolHandle< IMETSignificance > m_metSignif
Definition: MissingETObjectCollectionMaker.h:75
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CP::make_systematics_vector
std::vector< CP::SystematicSet > make_systematics_vector(const SystematicSet &systematics)
utility functions for working with systematics
Definition: SystematicsUtil.cxx:25
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
xAOD::MissingET_v1::phi
float phi() const
Returns .
TreeFilter.h
asg
Definition: DataHandleTestTool.h:28
xAOD::MissingETContainer
MissingETContainer_v1 MissingETContainer
Definition: Event/xAOD/xAODMissingET/xAODMissingET/MissingETContainer.h:16
top::MissingETObjectCollectionMaker::recalculateMET
StatusCode recalculateMET(const bool executeNominal)
Definition: MissingETObjectCollectionMaker.cxx:77
MissingETBase::Types::bitmask_t
uint64_t bitmask_t
Type for status word bit mask.
Definition: MissingETBase.h:39
x
#define x
top::MissingETObjectCollectionMaker::m_met_systematics
ToolHandle< IMETSystematicsTool > m_met_systematics
Definition: MissingETObjectCollectionMaker.h:74
xAOD::MissingETAssociationMap_v1
Definition: MissingETAssociationMap_v1.h:29
EventTools.h
A few functions for doing operations on particles / events. Currently holds code for dR,...
ConstDataVector::asDataVector
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
covarianceTool.filter
filter
Definition: covarianceTool.py:514
top::TreeFilter
Definition: TreeFilter.h:13
met::buildMETSum
StatusCode buildMETSum(const std::string &totalName, xAOD::MissingETContainer *metCont)
Definition: METHelpers.cxx:64
top::MissingETObjectCollectionMaker::m_MET_core
std::string m_MET_core
Definition: MissingETObjectCollectionMaker.h:71
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
top::MissingETObjectCollectionMaker::m_met_maker
ToolHandle< IMETMaker > m_met_maker
Definition: MissingETObjectCollectionMaker.h:73
checkTP.save
def save(self, fileName="./columbo.out")
Definition: checkTP.py:178
METHelpers.h
met::addGhostMuonsToJets
void addGhostMuonsToJets(const xAOD::MuonContainer &muons, xAOD::JetContainer &jets)
Definition: METHelpers.cxx:34
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
ElectronContainer.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
MissingETAuxContainer.h
xAOD::MissingET_v1
Principal data object for Missing ET.
Definition: MissingET_v1.h:25
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
top::check
void check(bool thingToCheck, const std::string &usefulFailureMessage)
Print an error message and terminate if thingToCheck is false.
Definition: EventTools.cxx:15
xAOD::MissingETAuxContainer_v1
Auxiliary data store for xAOD::MissingETContainer.
Definition: MissingETAuxContainer_v1.h:20
TauJetContainer.h
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
top::MissingETObjectCollectionMaker::m_recommendedSystematics
std::list< CP::SystematicSet > m_recommendedSystematics
Definition: MissingETObjectCollectionMaker.h:69
top::MissingETObjectCollectionMaker::specifiedSystematics
virtual const std::list< CP::SystematicSet > & specifiedSystematics() const
Definition: MissingETObjectCollectionMaker.h:53
xAOD::EventInfo_v1::averageInteractionsPerCrossing
float averageInteractionsPerCrossing() const
Average interactions per crossing for all BCIDs - for out-of-time pile-up.
Definition: EventInfo_v1.cxx:397
xAOD::MissingETContainer_v1
Container for xAOD::MissingET_v1 objects.
Definition: MissingETContainer_v1.h:21
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
MissingETObjectCollectionMaker.h
ConstDataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
TopConfig.h
xAOD::MissingETAssociationHelper
Definition: MissingETAssociationHelper.h:26
top::MissingETObjectCollectionMaker::MissingETObjectCollectionMaker
MissingETObjectCollectionMaker(const std::string &name)
Definition: MissingETObjectCollectionMaker.cxx:24
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
MuonContainer.h
xAOD::Photon
Photon_v1 Photon
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Photon.h:17
Muon
struct TBPatternUnitContext Muon
top::MissingETObjectCollectionMaker::recalculateEventMET
StatusCode recalculateEventMET(const xAOD::SystematicEvent *event, const xAOD::MissingETContainer *met_core, const bool forceUseLooseObjects=false, const std::string &outputContainerSuffix="")
Definition: MissingETObjectCollectionMaker.cxx:127
MissingETBase::Source::Signal::Track
@ Track
Indicator for MET contribution from reconstructed charged particle tracks.
xAOD::photon
@ photon
Definition: TrackingPrimitives.h:199
xAOD::SystematicEvent
SystematicEvent A simple xAOD class which we can persist into a mini-xAOD The xAOD EDM is way too com...
Definition: SystematicEvent.h:27
JetContainer.h
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
ConstDataVector
DataVector adapter that acts like it holds const pointers.
Definition: ConstDataVector.h:76
xAODType::Tau
@ Tau
The object is a tau (jet)
Definition: ObjectType.h:49
top::MissingETObjectCollectionMaker::m_config
std::shared_ptr< top::TopConfig > m_config
Definition: MissingETObjectCollectionMaker.h:66
top::MissingETObjectCollectionMaker::m_specifiedSystematics
std::list< CP::SystematicSet > m_specifiedSystematics
Definition: MissingETObjectCollectionMaker.h:68
top::MissingETObjectCollectionMaker::initialize
StatusCode initialize()
Dummy implementation of the initialisation function.
Definition: MissingETObjectCollectionMaker.cxx:41
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
xAOD::MissingETAssociationHelper::resetObjSelectionFlags
void resetObjSelectionFlags()
Definition: MissingETAssociationHelper.h:44
SystematicEventContainer.h
PhotonContainer.h
MissingETContainer.h
SystematicsUtil.h