![Logo](../../ATLAS-Logo-Square-Blue-RGB.png) |
ATLAS Offline Software
|
Go to the documentation of this file.
32 #include <boost/tokenizer.hpp>
33 #include <boost/algorithm/string/replace.hpp>
35 #ifndef XAOD_STANDALONE // For now metadata is Athena-only
57 if (muons.
empty())
return StatusCode::SUCCESS;
60 if (writeMuon.at(
muon->index())){
71 return StatusCode::SUCCESS;
81 if (
static_cast<int>(acc_lrtFilter(*idtrack) ) ){
82 std::unique_ptr<xAOD::Muon> copyMuon = std::make_unique<xAOD::Muon>(*
muon);
86 copy->push_back( std::move(copyMuon) );
91 std::unique_ptr<xAOD::Muon> copyMuon = std::make_unique<xAOD::Muon>(*
muon);
94 copy->push_back( std::move(copyMuon) );
98 return StatusCode::SUCCESS;
105 return StatusCode::FAILURE;
109 auto outputCol = std::make_unique<xAOD::MuonContainer>();
110 std::unique_ptr<xAOD::MuonAuxContainer> outputAuxCol;
111 outputAuxCol = std::make_unique<xAOD::MuonAuxContainer>();
112 outputCol->setStore(outputAuxCol.get());
115 if (
bool(
m_muLRT) && !lrtmuonkey.empty() &&
evtStore()->contains<xAOD::MuonContainer>(lrtmuonkey)){
119 if (
evtStore()->contains<xAOD::MuonContainer>(
"StdWithLRTMuons")) {
120 ATH_MSG_DEBUG(
"Merged prompt/LRT container already created in TStore");
122 ATH_MSG_DEBUG(
"Creating merged prompt/LRT container in TStore");
129 auto filtered_muons = std::make_unique<xAOD::MuonContainer>();
130 std::unique_ptr<xAOD::MuonAuxContainer> filtered_muons_aux = std::make_unique<xAOD::MuonAuxContainer>();
131 filtered_muons->setStore(filtered_muons_aux.get());
135 std::vector<bool> writePromptMuon;
136 std::vector<bool> writeLRTMuon;
153 }
else if (!lrtmuonkey.empty()) {
154 if (
evtStore()->contains<xAOD::MuonContainer>(lrtmuonkey) ==
false &&
bool(
m_muLRT) ==
true)
ATH_MSG_WARNING(
"prompt/LRT OR procedure attempted but " << lrtmuonkey <<
" not in ROOT file, check config!");
158 if (
m_isPHYSLITE && muonkey.find(
"AnalysisMuons")==std::string::npos){
159 ATH_MSG_ERROR(
"You are running on PHYSLITE derivation. Please change the Muons container to 'AnalysisMuons'");
160 return StatusCode::FAILURE;
164 if (
bool(
m_muLRT) &&
evtStore()->contains<xAOD::MuonContainer>(lrtmuonkey)){
171 if (containerToBeCopied !=
nullptr) {
173 muons = containerToBeCopied;
183 copy = shallowcopy.first;
184 copyaux = shallowcopy.second;
189 ATH_MSG_DEBUG(
"Not retrieving muon collection, using existing one provided by user");
203 return StatusCode::SUCCESS;
210 dec_baseline(
input) =
false;
211 dec_selected(
input) = 0;
212 dec_signal(
input) =
false;
213 dec_isol(
input) =
false;
214 dec_isolHighPt(
input) =
false;
215 dec_passedHighPtCuts(
input) =
false;
216 dec_passSignalID(
input) =
false;
219 dec_DFCommonJetDr(
input) = -2.0;
220 }
else if (!
input.isAvailable<
float>(
"DFCommonJetDr")) {
221 dec_dRJet(
input) = -2.0;
225 if (
input.pt() < 3
e3 )
return StatusCode::SUCCESS;
242 double primvertex_z =
pv ?
pv->z() : 0;
245 if (
input.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
246 track =
input.trackParticle(xAOD::Muon::CombinedTrackParticle);
247 if (!
track)
return StatusCode::SUCCESS;
255 dec_z0sinTheta(
input) = (
track->z0() +
track->vz() - primvertex_z) * TMath::Sin(
input.p4().Theta());
264 dec_d0sig(
input) = -99.;
267 float d0sigError = -99.;
268 ATH_MSG_WARNING(
"FillMuon : Exception caught from d0significance() calculation. Setting dummy decoration d0sig=" << d0sigError );
269 dec_d0sig(
input) = d0sigError;
276 unsigned char nBLHits(0), nPixHits(0), nPixelDeadSensors(0), nPixHoles(0),
277 nSCTHits(0), nSCTDeadSensors(0), nSCTHoles(0), nTRTHits(0), nTRTOutliers(0);
299 ATH_MSG_INFO(
"MUON bHit: " <<
static_cast<int>( nBLHits ));
300 ATH_MSG_INFO(
"MUON pHit: " <<
static_cast<int>( nPixHits ));
301 ATH_MSG_INFO(
"MUON pDead:" <<
static_cast<int>( nPixelDeadSensors ));
302 ATH_MSG_INFO(
"MUON pHole:" <<
static_cast<int>( nPixHoles ));
304 ATH_MSG_INFO(
"MUON sDead:" <<
static_cast<int>( nSCTDeadSensors ));
305 ATH_MSG_INFO(
"MUON sHole:" <<
static_cast<int>( nSCTHoles ));
306 ATH_MSG_INFO(
"MUON tHit: " <<
static_cast<int>( nTRTHits ));
307 ATH_MSG_INFO(
"MUON tOut: " <<
static_cast<int>( nTRTOutliers ));
310 input.trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
321 if (
input.pt() <=
ptcut || std::abs(
input.eta()) >= etacut)
return StatusCode::SUCCESS;
329 dec_baseline(
input) =
true;
330 dec_selected(
input) = 2;
338 return StatusCode::SUCCESS;
344 if (!acc_baseline(
input))
return false;
345 if (!acc_passSignalID(
input))
return false;
348 if ( etacut==DUMMYDEF ){
351 else if ( std::abs(
input.eta()) > etacut )
return false;
353 if (z0cut > 0.0 && std::abs(acc_z0sinTheta(
input)) > z0cut)
return false;
354 if (acc_d0sig(
input) != 0) {
355 if (d0sigcut > 0.0 && std::abs(acc_d0sig(
input)) > d0sigcut)
return false;
366 dec_signal(
input) =
true;
370 <<
" signal? " <<
static_cast<int>(acc_signal(
input))
371 <<
" isolation? " <<
static_cast<int>(acc_isol(
input))
372 <<
" passedHighPtCuts? " <<
static_cast<int>(acc_passedHighPtCuts(
input)));
375 <<
" signal? " <<
static_cast<int>( acc_signal(
input))
376 <<
" isolation? " <<
static_cast<int>( acc_isol(
input)));
380 return acc_signal(
input);
390 ATH_MSG_DEBUG(
"No HighPt check supported for muons below 3GeV! False.");
391 dec_passedHighPtCuts(
input) =
false;
396 isHighPt =
bool(m_muonSelectionHighPtTool->accept(
input));
397 dec_passedHighPtCuts(
input) = isHighPt;
406 dec_bad(
input) =
false;
409 dec_bad_highPt(
input) =
false;
412 if (
input.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
413 track =
input.trackParticle(xAOD::Muon::CombinedTrackParticle);
414 if (!
track)
return false;
419 ATH_MSG_WARNING(
"Non-SAF muon without a track; cannot test IsBadMuon criteria");
426 bool isbad = Rerr > qopcut;
427 bool isbadHighPt = Rerr > qopcut;
435 dec_bad(
input) = isbad;
436 dec_bad_highPt(
input) = isbadHighPt;
445 dec_cosmic(
input) =
false;
448 if (
input.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
449 track =
input.trackParticle(xAOD::Muon::CombinedTrackParticle);
451 ATH_MSG_VERBOSE(
"WARNING: SAF muon without CB track found. Not possible to check cosmic muon criteria");
458 ATH_MSG_WARNING(
"Non-SAF muon without primary track particle found. Not possible to check cosmic muon criteria");
463 double mu_d0 =
track->d0();
465 double primvertex_z =
pv ?
pv->z() : 0;
466 double mu_z0_exPV =
track->z0() +
track->vz() - primvertex_z;
468 bool isCosmicMuon = (std::abs(mu_z0_exPV) >= z0cut || std::abs(mu_d0) >= d0cut);
471 ATH_MSG_VERBOSE(
"COSMIC PV Z = " << primvertex_z <<
", track z0 = " << mu_z0_exPV <<
", track d0 = " << mu_d0);
474 dec_cosmic(
input) = isCosmicMuon;
486 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: Reco getEfficiencyScaleFactor out of validity range");
494 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: TTVA getEfficiencyScaleFactor out of validity range");
500 float sf_badHighPt(1.);
501 if(
m_muId == 4 && doBadMuonHP){
503 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: BadMuonHighPt getEfficiencyScaleFactor out of validity range");
515 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: high-pt Iso getEfficiencyScaleFactor out of validity range");
519 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: Iso getEfficiencyScaleFactor out of validity range");
527 dec_effscalefact(
mu) =
sf;
537 ATH_MSG_WARNING(
"Problem retrieving signal muon trigger efficiency for " << trigExpr );
548 if (trigExpr.empty() || sfmuons.
empty())
return 1.;
554 const char *
tmp = trigExpr.c_str();
555 while( (
tmp = strstr(
tmp,
"mu")) ){
560 bool isdimuon = (trigExpr.find(
"2mu") != std::string::npos);
561 bool isOR = (trigExpr.find(
"OR") != std::string::npos);
563 if((!isdimuon && mulegs<2) || (isdimuon && sfmuons.
size()==2) || (mulegs>=2 && isOR)){
571 else if(mulegs!=2 && isOR){
572 ATH_MSG_WARNING(
"SF for " << trigExpr <<
" are only supported for two muon events!");
576 std::string newtrigExpr = TString(trigExpr).Copy().ReplaceAll(
"HLT_2",
"").Data();
579 if (isdimuon) { newtrigExpr +=
"_"+newtrigExpr; }
580 boost::replace_all(newtrigExpr,
"HLT_",
"");
581 boost::char_separator<char>
sep(
"_");
583 for (
const auto& mutrig : boost::tokenizer<boost::char_separator<char>>(newtrigExpr,
sep)) {
584 double dataFactor = 1.;
585 double mcFactor = 1.;
592 if( (1-mcFactor) > 0. )
593 trig_sf *= (1-dataFactor)/(1-mcFactor);
606 if( !acc_passOR(*
muon) )
continue;
607 if (acc_signal(*
muon)) {
625 if (
ret != StatusCode::SUCCESS) {
626 ATH_MSG_ERROR(
"Cannot configure MuonEfficiencyScaleFactors for systematic var. " << systConfig.
name() );
630 if (
ret != StatusCode::SUCCESS) {
631 ATH_MSG_ERROR(
"Cannot configure MuonBadMuonHighPtScaleFactors for systematic var. " << systConfig.
name() );
635 if (
ret != StatusCode::SUCCESS) {
636 ATH_MSG_ERROR(
"Cannot configure MuonTTVAEfficiencyScaleFactors for systematic var. " << systConfig.
name() );
640 if (
ret != StatusCode::SUCCESS) {
641 ATH_MSG_ERROR(
"Cannot configure MuonIsolationScaleFactors for systematic var. " << systConfig.
name() );
645 if (
ret != StatusCode::SUCCESS) {
646 ATH_MSG_ERROR(
"Cannot configure MuonHighPtIsolationScaleFactors for systematic var. " << systConfig.
name() );
650 if (
ret != StatusCode::SUCCESS) {
651 ATH_MSG_ERROR(
"Cannot configure MuonTriggerScaleFactors for systematic var. " << systConfig.
name() );
655 if (
ret != StatusCode::SUCCESS) {
656 ATH_MSG_ERROR(
"Cannot configure TrigGlobalEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.
name() );
660 if (
ret != StatusCode::SUCCESS) {
661 ATH_MSG_ERROR(
"Cannot configure TrigGlobalEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.
name() );
668 if (
ret != StatusCode::SUCCESS) {
669 ATH_MSG_ERROR(
"Cannot configure MuonEfficiencyScaleFactors back to default.");
673 if (
ret != StatusCode::SUCCESS) {
674 ATH_MSG_ERROR(
"Cannot configure MuonBadMuonHighPtScaleFactors back to default.");
678 if (
ret != StatusCode::SUCCESS) {
679 ATH_MSG_ERROR(
"Cannot configure MuonTTVAEfficiencyScaleFactors back to default.");
683 if (
ret != StatusCode::SUCCESS) {
684 ATH_MSG_ERROR(
"Cannot configure MuonIsolationScaleFactors back to default.");
688 if (
ret != StatusCode::SUCCESS) {
689 ATH_MSG_ERROR(
"Cannot configure MuonIsolationScaleFactors back to default.");
693 if (
ret != StatusCode::SUCCESS) {
694 ATH_MSG_ERROR(
"Cannot configure MuonTriggerScaleFactors back to default.");
698 if (
ret != StatusCode::SUCCESS) {
699 ATH_MSG_ERROR(
"Cannot configure TrigGlobalEfficiencyCorrectionTool (trigger) back to default.");
703 if (
ret != StatusCode::SUCCESS) {
704 ATH_MSG_ERROR(
"Cannot configure TrigGlobalEfficiencyCorrectionTool (trigger) back to default.");
def retrieve(aClass, aKey=None)
asg::AnaToolHandle< CP::IMuonEfficiencyScaleFactors > m_muonEfficiencySFTool
asg::AnaToolHandle< CP::IIsolationSelectionTool > m_isoHighPtTool
virtual double pt() const override final
The transverse momentum ( ) of the particle.
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
bool IsHighPtMuon(const xAOD::Muon &input) const override final
asg::AnaToolHandle< ITrigGlobalEfficiencyCorrectionTool > m_trigGlobalEffCorrTool_multiLep
StatusCode prepareLRTMuons(const xAOD::MuonContainer *inMuons, xAOD::MuonContainer *copy) const override final
double GetTotalMuonTriggerSF(const xAOD::MuonContainer &sfmuons, const std::string &trigExpr) override final
virtual CorrectionCode getTriggerEfficiency(const xAOD::Muon &mu, Double_t &efficiency, const std::string &trigger, Bool_t dataType) const =0
asg::AnaToolHandle< CP::IMuonEfficiencyScaleFactors > m_muonEfficiencyBMHighPtSFTool
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
StatusCode FillMuon(xAOD::Muon &input, const float ptcut, const float etacut) override final
DataVector adapter that acts like it holds const pointers.
double GetTotalMuonSF(const xAOD::MuonContainer &muons, const bool recoSF=true, const bool isoSF=true, const std::string &trigExpr="HLT_mu20_iloose_L1MU15_OR_HLT_mu50", const bool bmhptSF=true) override final
bool IsBadMuon(const xAOD::Muon &input, const float qopcut) const override final
const xAOD::MuonContainer * lrt_muons
asg::AnaToolHandle< CP::IIsolationSelectionTool > m_isoBaselineTool
bool IsCosmicMuon(const xAOD::Muon &input, const float z0cut, const float d0cut) const override final
double d0significance(const xAOD::TrackParticle *tp, double d0_uncert_beam_spot_2)
Class creating a shallow copy of an existing auxiliary container.
Class to wrap a set of SystematicVariations.
const T * get(size_type n) const
Access an element, as an rvalue.
std::string name() const
returns: the systematics joined into a single string.
float beamPosSigmaX() const
The width of the beam spot in the X direction.
asg::AnaToolHandle< CP::IMuonEfficiencyScaleFactors > m_muonTTVAEfficiencySFTool
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
@ numberOfTRTHits
number of TRT hits [unit8_t].
std::string m_muBaselineIso_WP
Helper class to provide constant type-safe access to aux data.
const xAOD::Vertex * GetPrimVtx() const override final
#define ATH_MSG_VERBOSE(x)
bool IsSignalMuon(const xAOD::Muon &input, const float ptcut, const float d0sigcut, const float z0cut, const float etacut=DUMMYDEF) const override final
@ numberOfBLayerHits
these are the hits in the first pixel layer, i.e.
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
asg::AnaToolHandle< CP::IMuonLRTOverlapRemovalTool > m_muonLRTORTool
virtual CorrectionCode getTriggerScaleFactor(const xAOD::MuonContainer &mucont, Double_t &triggersf, const std::string &trigger) const =0
asg::AnaToolHandle< ITrigGlobalEfficiencyCorrectionTool > m_trigGlobalEffCorrTool_diLep
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
@ OutOfValidityRange
Input object is out of validity range.
Helper class to provide type-safe access to aux data.
double GetMuonTriggerEfficiency(const xAOD::Muon &mu, const std::string &trigExpr, const bool isdata=false) override final
asg::AnaToolHandle< CP::IMuonEfficiencyScaleFactors > m_muonIsolationSFTool
::StatusCode StatusCode
StatusCode definition for legacy code.
asg::AnaToolHandle< CP::IMuonCalibrationAndSmearingTool > m_muonCalibTool
const xAOD::MuonContainer * prompt_muons
double m_muIsoHighPtThresh
@ numberOfSCTHoles
number of SCT holes [unit8_t].
float beamPosSigmaY() const
The width of the beam spot in the Y direction.
Muon_v1 Muon
Reference the current persistent version:
asg::AnaToolHandle< CP::IMuonSelectionTool > m_muonSelectionToolBaseline
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
bool nSCTHits(const xAOD::TauJet &, const xAOD::TauTrack &track, double &out)
value_type push_back(value_type pElem)
Add an element to the end of the collection.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
asg::AnaToolHandle< CP::IMuonSelectionTool > m_muonSelectionHighPtTool
std::pair< std::unique_ptr< T >, std::unique_ptr< ShallowAuxContainer > > shallowCopyContainer(const T &cont, [[maybe_unused]] const EventContext &ctx)
Function making a shallow copy of a constant container.
bool isAvailable(const std::string &name, const std::string &clsname="") const
Check if a user property is available for reading or not.
SG::WriteHandleKey< xAOD::MuonContainer > m_outMuonLocation
Class describing the basic event information.
@ numberOfTRTOutliers
number of TRT outliers [unit8_t].
asg::AnaToolHandle< CP::IMuonTriggerScaleFactors > m_muonTriggerSFTool
@ Ok
The correction was done successfully.
float beamPosSigmaXY() const
The beam spot shape's X-Y correlation.
Class describing a Vertex.
StatusCode GetMuons(xAOD::MuonContainer *©, xAOD::ShallowAuxContainer *©aux, const bool recordSG=true, const std::string &muonkey="Muons", const std::string &lrtmuonkey="MuonsLRT", const xAOD::MuonContainer *containerToBeCopied=nullptr) override final
#define ATH_MSG_WARNING(x)
@ numberOfSCTDeadSensors
number of dead SCT sensors crossed [unit8_t].
float GetSignalMuonSF(const xAOD::Muon &mu, const bool recoSF=true, const bool isoSF=true, const bool doBadMuonHP=true, const bool warnOVR=true) override final
DataVector adapter that acts like it holds const pointers.
bool setOriginalObjectLink(const IParticle &original, IParticle ©)
This function should be used by CP tools when they make a deep copy of an object in their correctedCo...
CP::SystematicSet m_currentSyst
virtual CorrectionCode getEfficiencyScaleFactor(const xAOD::Muon &mu, float &sf, const xAOD::EventInfo *info=0) const =0
Retrieve the Scale factor.
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].
Class describing a TrackParticle.
const IParticle * getOriginalObject(const IParticle ©)
This function can be used to conveniently get a pointer back to the original object from which a copy...
StatusCode MergeMuons(const xAOD::MuonContainer &muons, const std::vector< bool > &writeMuon, xAOD::MuonContainer *outputCol) const override final
std::string m_muIsoHighPt_WP
asg::AnaToolHandle< CP::IMuonEfficiencyScaleFactors > m_muonHighPtIsolationSFTool
setBGCode setTAP setLVL2ErrorBits bool
double GetTotalMuonSFsys(const xAOD::MuonContainer &muons, const CP::SystematicSet &systConfig, const bool recoSF=true, const bool isoSF=true, const std::string &trigExpr="HLT_mu20_iloose_L1MU15_OR_HLT_mu50", const bool bmhptSF=true) override final
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
asg::AnaToolHandle< CP::IMuonSelectionTool > m_muonSelectionTool
asg::AnaToolHandle< CP::IIsolationSelectionTool > m_isoTool