|
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
56 if (muons.
empty())
return StatusCode::SUCCESS;
59 if (writeMuon.at(
muon->index())){
70 return StatusCode::SUCCESS;
78 if ( acc_lrtFilter.isAvailable(*idtrack) )
80 if (
static_cast<int>(acc_lrtFilter(*idtrack) ) ){
81 std::unique_ptr<xAOD::Muon> copyMuon = std::make_unique<xAOD::Muon>(*
muon);
85 copy->push_back( std::move(copyMuon) );
90 std::unique_ptr<xAOD::Muon> copyMuon = std::make_unique<xAOD::Muon>(*
muon);
93 copy->push_back( std::move(copyMuon) );
97 return StatusCode::SUCCESS;
104 return StatusCode::FAILURE;
108 auto outputCol = std::make_unique<xAOD::MuonContainer>();
109 std::unique_ptr<xAOD::MuonAuxContainer> outputAuxCol;
110 outputAuxCol = std::make_unique<xAOD::MuonAuxContainer>();
111 outputCol->setStore(outputAuxCol.get());
114 if (
bool(
m_muLRT) && !lrtmuonkey.empty() &&
evtStore()->contains<xAOD::MuonContainer>(lrtmuonkey)){
118 if (
evtStore()->contains<xAOD::MuonContainer>(
"StdWithLRTMuons")) {
119 ATH_MSG_DEBUG(
"Merged prompt/LRT container already created in TStore");
121 ATH_MSG_DEBUG(
"Creating merged prompt/LRT container in TStore");
128 auto filtered_muons = std::make_unique<xAOD::MuonContainer>();
129 std::unique_ptr<xAOD::MuonAuxContainer> filtered_muons_aux = std::make_unique<xAOD::MuonAuxContainer>();
130 filtered_muons->setStore(filtered_muons_aux.get());
134 std::vector<bool> writePromptMuon;
135 std::vector<bool> writeLRTMuon;
152 }
else if (!lrtmuonkey.empty()) {
153 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!");
157 if (
m_isPHYSLITE && muonkey.find(
"AnalysisMuons")==std::string::npos){
158 ATH_MSG_ERROR(
"You are running on PHYSLITE derivation. Please change the Muons container to 'AnalysisMuons'");
159 return StatusCode::FAILURE;
163 if (
bool(
m_muLRT) &&
evtStore()->contains<xAOD::MuonContainer>(lrtmuonkey)){
170 if (containerToBeCopied !=
nullptr) {
172 muons = containerToBeCopied;
182 copy = shallowcopy.first;
183 copyaux = shallowcopy.second;
188 ATH_MSG_DEBUG(
"Not retrieving muon collection, using existing one provided by user");
202 return StatusCode::SUCCESS;
209 dec_baseline(
input) =
false;
210 dec_selected(
input) = 0;
211 dec_signal(
input) =
false;
212 dec_isol(
input) =
false;
213 dec_isolHighPt(
input) =
false;
214 dec_passedHighPtCuts(
input) =
false;
215 dec_passSignalID(
input) =
false;
218 dec_DFCommonJetDr(
input) = -2.0;
220 dec_dRJet(
input) = -2.0;
224 if (
input.pt() < 3
e3 )
return StatusCode::SUCCESS;
241 double primvertex_z =
pv ?
pv->z() : 0;
244 if (
input.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
245 track =
input.trackParticle(xAOD::Muon::CombinedTrackParticle);
246 if (!
track)
return StatusCode::SUCCESS;
254 dec_z0sinTheta(
input) = (
track->z0() +
track->vz() - primvertex_z) * TMath::Sin(
input.p4().Theta());
263 dec_d0sig(
input) = -99.;
266 float d0sigError = -99.;
267 ATH_MSG_WARNING(
"FillMuon : Exception caught from d0significance() calculation. Setting dummy decoration d0sig=" << d0sigError );
268 dec_d0sig(
input) = d0sigError;
275 unsigned char nBLHits(0), nPixHits(0), nPixelDeadSensors(0), nPixHoles(0),
298 ATH_MSG_INFO(
"MUON bHit: " <<
static_cast<int>( nBLHits ));
299 ATH_MSG_INFO(
"MUON pHit: " <<
static_cast<int>( nPixHits ));
300 ATH_MSG_INFO(
"MUON pDead:" <<
static_cast<int>( nPixelDeadSensors ));
301 ATH_MSG_INFO(
"MUON pHole:" <<
static_cast<int>( nPixHoles ));
303 ATH_MSG_INFO(
"MUON sDead:" <<
static_cast<int>( nSCTDeadSensors ));
306 ATH_MSG_INFO(
"MUON tOut: " <<
static_cast<int>( nTRTOutliers ));
309 input.trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
320 if (
input.pt() <=
ptcut || std::abs(
input.eta()) >= etacut)
return StatusCode::SUCCESS;
328 dec_baseline(
input) =
true;
329 dec_selected(
input) = 2;
337 return StatusCode::SUCCESS;
343 if (!acc_baseline(
input))
return false;
344 if (!acc_passSignalID(
input))
return false;
347 if ( etacut==DUMMYDEF ){
350 else if ( std::abs(
input.eta()) > etacut )
return false;
352 if (z0cut > 0.0 && std::abs(acc_z0sinTheta(
input)) > z0cut)
return false;
353 if (acc_d0sig(
input) != 0) {
354 if (d0sigcut > 0.0 && std::abs(acc_d0sig(
input)) > d0sigcut)
return false;
365 dec_signal(
input) =
true;
369 <<
" signal? " <<
static_cast<int>(acc_signal(
input))
370 <<
" isolation? " <<
static_cast<int>(acc_isol(
input))
371 <<
" passedHighPtCuts? " <<
static_cast<int>(acc_passedHighPtCuts(
input)));
374 <<
" signal? " <<
static_cast<int>( acc_signal(
input))
375 <<
" isolation? " <<
static_cast<int>( acc_isol(
input)));
379 return acc_signal(
input);
389 ATH_MSG_DEBUG(
"No HighPt check supported for muons below 3GeV! False.");
390 dec_passedHighPtCuts(
input) =
false;
395 isHighPt =
bool(m_muonSelectionHighPtTool->accept(
input));
396 dec_passedHighPtCuts(
input) = isHighPt;
405 dec_bad(
input) =
false;
408 dec_bad_highPt(
input) =
false;
411 if (
input.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
412 track =
input.trackParticle(xAOD::Muon::CombinedTrackParticle);
413 if (!
track)
return false;
418 ATH_MSG_WARNING(
"Non-SAF muon without a track; cannot test IsBadMuon criteria");
425 bool isbad = Rerr > qopcut;
426 bool isbadHighPt = Rerr > qopcut;
434 dec_bad(
input) = isbad;
435 dec_bad_highPt(
input) = isbadHighPt;
443 dec_cosmic(
input) =
false;
446 if (
input.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
447 track =
input.trackParticle(xAOD::Muon::CombinedTrackParticle);
449 ATH_MSG_VERBOSE(
"WARNING: SAF muon without CB track found. Not possible to check cosmic muon criteria");
456 ATH_MSG_WARNING(
"Non-SAF muon without primary track particle found. Not possible to check cosmic muon criteria");
461 double mu_d0 =
track->d0();
463 double primvertex_z =
pv ?
pv->z() : 0;
464 double mu_z0_exPV =
track->z0() +
track->vz() - primvertex_z;
466 bool isCosmicMuon = (std::abs(mu_z0_exPV) >= z0cut || std::abs(mu_d0) >= d0cut);
469 ATH_MSG_VERBOSE(
"COSMIC PV Z = " << primvertex_z <<
", track z0 = " << mu_z0_exPV <<
", track d0 = " << mu_d0);
472 dec_cosmic(
input) = isCosmicMuon;
484 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: Reco getEfficiencyScaleFactor out of validity range");
492 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: TTVA getEfficiencyScaleFactor out of validity range");
498 float sf_badHighPt(1.);
499 if(
m_muId == 4 && doBadMuonHP){
501 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: BadMuonHighPt getEfficiencyScaleFactor out of validity range");
513 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: high-pt Iso getEfficiencyScaleFactor out of validity range");
517 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: Iso getEfficiencyScaleFactor out of validity range");
525 dec_effscalefact(
mu) =
sf;
535 ATH_MSG_WARNING(
"Problem retrieving signal muon trigger efficiency for " << trigExpr );
546 if (trigExpr.empty() || sfmuons.
empty())
return 1.;
552 const char *
tmp = trigExpr.c_str();
553 while( (
tmp = strstr(
tmp,
"mu")) ){
558 bool isdimuon = (trigExpr.find(
"2mu") != std::string::npos);
559 bool isOR = (trigExpr.find(
"OR") != std::string::npos);
561 if((!isdimuon && mulegs<2) || (isdimuon && sfmuons.
size()==2) || (mulegs>=2 && isOR)){
569 else if(mulegs!=2 && isOR){
570 ATH_MSG_WARNING(
"SF for " << trigExpr <<
" are only supported for two muon events!");
574 std::string newtrigExpr = TString(trigExpr).Copy().ReplaceAll(
"HLT_2",
"").Data();
577 if (isdimuon) { newtrigExpr +=
"_"+newtrigExpr; }
578 boost::replace_all(newtrigExpr,
"HLT_",
"");
579 boost::char_separator<char>
sep(
"_");
581 for (
const auto& mutrig : boost::tokenizer<boost::char_separator<char>>(newtrigExpr,
sep)) {
582 double dataFactor = 1.;
583 double mcFactor = 1.;
590 if( (1-mcFactor) > 0. )
591 trig_sf *= (1-dataFactor)/(1-mcFactor);
604 if( !acc_passOR(*
muon) )
continue;
605 if (acc_signal(*
muon)) {
623 if ( ret != StatusCode::SUCCESS) {
624 ATH_MSG_ERROR(
"Cannot configure MuonEfficiencyScaleFactors for systematic var. " << systConfig.
name() );
628 if ( ret != StatusCode::SUCCESS) {
629 ATH_MSG_ERROR(
"Cannot configure MuonBadMuonHighPtScaleFactors for systematic var. " << systConfig.
name() );
633 if ( ret != StatusCode::SUCCESS) {
634 ATH_MSG_ERROR(
"Cannot configure MuonTTVAEfficiencyScaleFactors for systematic var. " << systConfig.
name() );
638 if ( ret != StatusCode::SUCCESS) {
639 ATH_MSG_ERROR(
"Cannot configure MuonIsolationScaleFactors for systematic var. " << systConfig.
name() );
643 if ( ret != StatusCode::SUCCESS) {
644 ATH_MSG_ERROR(
"Cannot configure MuonHighPtIsolationScaleFactors for systematic var. " << systConfig.
name() );
648 if ( ret != StatusCode::SUCCESS) {
649 ATH_MSG_ERROR(
"Cannot configure MuonTriggerScaleFactors for systematic var. " << systConfig.
name() );
653 if (ret != StatusCode::SUCCESS) {
654 ATH_MSG_ERROR(
"Cannot configure TrigGlobalEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.
name() );
658 if (ret != StatusCode::SUCCESS) {
659 ATH_MSG_ERROR(
"Cannot configure TrigGlobalEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.
name() );
666 if ( ret != StatusCode::SUCCESS) {
667 ATH_MSG_ERROR(
"Cannot configure MuonEfficiencyScaleFactors back to default.");
671 if ( ret != StatusCode::SUCCESS) {
672 ATH_MSG_ERROR(
"Cannot configure MuonBadMuonHighPtScaleFactors back to default.");
676 if ( ret != StatusCode::SUCCESS) {
677 ATH_MSG_ERROR(
"Cannot configure MuonTTVAEfficiencyScaleFactors back to default.");
681 if ( ret != StatusCode::SUCCESS) {
682 ATH_MSG_ERROR(
"Cannot configure MuonIsolationScaleFactors back to default.");
686 if ( ret != StatusCode::SUCCESS) {
687 ATH_MSG_ERROR(
"Cannot configure MuonIsolationScaleFactors back to default.");
691 if ( ret != StatusCode::SUCCESS) {
692 ATH_MSG_ERROR(
"Cannot configure MuonTriggerScaleFactors back to default.");
696 if (ret != StatusCode::SUCCESS) {
697 ATH_MSG_ERROR(
"Cannot configure TrigGlobalEfficiencyCorrectionTool (trigger) back to default.");
701 if (ret != StatusCode::SUCCESS) {
702 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
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.
double GetMuonTriggerEfficiency(const xAOD::Muon &mu, const std::string &trigExpr, const bool isdata=false) override final
float nSCTHits(const U &p)
float nTRTHits(const U &p)
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 nSCTHoles(const U &p)
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 ...
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.
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].
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
@ 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