 |
ATLAS Offline Software
|
Go to the documentation of this file.
33 #include <string_view>
36 #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;
79 if ( acc_lrtFilter.isAvailable(*idtrack) )
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;
184 copy = shallowcopy.first;
185 copyaux = shallowcopy.second;
191 ATH_MSG_DEBUG(
"Not retrieving muon collection, using existing one provided by user");
205 return StatusCode::SUCCESS;
212 dec_baseline(input) =
false;
213 dec_selected(input) = 0;
214 dec_signal(input) =
false;
215 dec_isol(input) =
false;
216 dec_isolHighPt(input) =
false;
217 dec_passedHighPtCuts(input) =
false;
218 dec_passSignalID(input) =
false;
221 dec_DFCommonJetDr(input) = -2.0;
222 }
else if (!acc_DFCommonJetDr.
isAvailable(input)) {
223 dec_dRJet(input) = -2.0;
227 if ( input.pt() < 3
e3 )
return StatusCode::SUCCESS;
244 double primvertex_z =
pv ?
pv->z() : 0;
247 if (input.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
248 track = input.trackParticle(xAOD::Muon::CombinedTrackParticle);
249 if (!
track)
return StatusCode::SUCCESS;
252 track = input.primaryTrackParticle();
257 dec_z0sinTheta(input) = (
track->z0() +
track->vz() - primvertex_z) * TMath::Sin(input.p4().Theta());
259 ATH_MSG_WARNING(
"FillMuon: Muon of pT and eta " << input.pt() <<
" MeV " << input.eta() <<
" has no associated track");
266 dec_d0sig(input) = -99.;
269 float d0sigError = -99.;
270 ATH_MSG_WARNING(
"FillMuon : Exception caught from d0significance() calculation. Setting dummy decoration d0sig=" << d0sigError );
271 dec_d0sig(input) = d0sigError;
299 ATH_MSG_INFO(
"MUON sTag: " << (input.muonType() == xAOD::Muon::SegmentTagged));
301 ATH_MSG_INFO(
"MUON bHit: " <<
static_cast<int>( nBLHits ));
302 ATH_MSG_INFO(
"MUON pHit: " <<
static_cast<int>( nPixHits ));
304 ATH_MSG_INFO(
"MUON pHole:" <<
static_cast<int>( nPixHoles ));
309 ATH_MSG_INFO(
"MUON tOut: " <<
static_cast<int>( nTRTOutliers ));
312 input.trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
323 if (input.pt() <=
ptcut || std::abs(input.eta()) >= etacut)
return StatusCode::SUCCESS;
331 dec_baseline(input) =
true;
332 dec_selected(input) = 2;
340 return StatusCode::SUCCESS;
346 if (!acc_baseline(input))
return false;
347 if (!acc_passSignalID(input))
return false;
349 if (input.pt() <=
ptcut || input.pt() == 0)
return false;
350 if ( etacut==DUMMYDEF ){
351 if(std::abs(input.eta()) >
m_muEta )
return false;
353 else if ( std::abs(input.eta()) > etacut )
return false;
355 if (z0cut > 0.0 && std::abs(acc_z0sinTheta(input)) > z0cut)
return false;
356 if (acc_d0sig(input) != 0) {
357 if (d0sigcut > 0.0 && std::abs(acc_d0sig(input)) > d0sigcut)
return false;
368 dec_signal(input) =
true;
372 <<
" signal? " <<
static_cast<int>(acc_signal(input))
373 <<
" isolation? " <<
static_cast<int>(acc_isol(input))
374 <<
" passedHighPtCuts? " <<
static_cast<int>(acc_passedHighPtCuts(input)));
377 <<
" signal? " <<
static_cast<int>( acc_signal(input))
378 <<
" isolation? " <<
static_cast<int>( acc_isol(input)));
382 return acc_signal(input);
391 if (input.pt() < 3
e3){
392 ATH_MSG_DEBUG(
"No HighPt check supported for muons below 3GeV! False.");
393 dec_passedHighPtCuts(input) =
false;
398 isHighPt =
bool(m_muonSelectionHighPtTool->accept(input));
399 dec_passedHighPtCuts(input) = isHighPt;
408 dec_bad(input) =
false;
411 dec_bad_highPt(input) =
false;
414 if (input.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
415 track = input.trackParticle(xAOD::Muon::CombinedTrackParticle);
416 if (!
track)
return false;
419 track = input.primaryTrackParticle();
421 ATH_MSG_WARNING(
"Non-SAF muon without a track; cannot test IsBadMuon criteria");
428 bool isbad = Rerr > qopcut;
429 bool isbadHighPt = Rerr > qopcut;
437 dec_bad(input) = isbad;
438 dec_bad_highPt(input) = isbadHighPt;
446 dec_cosmic(input) =
false;
449 if (input.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
450 track = input.trackParticle(xAOD::Muon::CombinedTrackParticle);
452 ATH_MSG_VERBOSE(
"WARNING: SAF muon without CB track found. Not possible to check cosmic muon criteria");
457 track = input.primaryTrackParticle();
459 ATH_MSG_WARNING(
"Non-SAF muon without primary track particle found. Not possible to check cosmic muon criteria");
464 double mu_d0 =
track->d0();
466 double primvertex_z =
pv ?
pv->z() : 0;
467 double mu_z0_exPV =
track->z0() +
track->vz() - primvertex_z;
469 bool isCosmicMuon = (std::abs(mu_z0_exPV) >= z0cut || std::abs(mu_d0) >= d0cut);
472 ATH_MSG_VERBOSE(
"COSMIC PV Z = " << primvertex_z <<
", track z0 = " << mu_z0_exPV <<
", track d0 = " << mu_d0);
475 dec_cosmic(input) = isCosmicMuon;
487 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: Reco getEfficiencyScaleFactor out of validity range");
495 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: TTVA getEfficiencyScaleFactor out of validity range");
501 float sf_badHighPt(1.);
502 if(
m_muId == 4 && doBadMuonHP){
504 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: BadMuonHighPt getEfficiencyScaleFactor out of validity range");
516 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: high-pt Iso getEfficiencyScaleFactor out of validity range");
520 if(warnOVR)
ATH_MSG_WARNING(
" GetSignalMuonSF: Iso getEfficiencyScaleFactor out of validity range");
528 dec_effscalefact(
mu) =
sf;
538 ATH_MSG_WARNING(
"Problem retrieving signal muon trigger efficiency for " << trigExpr );
549 if (trigExpr.empty() || sfmuons.
empty())
return 1.;
555 const char *
tmp = trigExpr.c_str();
556 while( (
tmp = strstr(
tmp,
"mu")) ){
561 bool isdimuon = (trigExpr.find(
"2mu") != std::string::npos);
562 bool isOR = (trigExpr.find(
"OR") != std::string::npos);
564 if((!isdimuon && mulegs<2) || (isdimuon && sfmuons.
size()==2) || (mulegs>=2 && isOR)){
572 else if(mulegs!=2 && isOR){
573 ATH_MSG_WARNING(
"SF for " << trigExpr <<
" are only supported for two muon events!");
577 std::string newtrigExpr = TString(trigExpr).Copy().ReplaceAll(
"HLT_2",
"").Data();
580 if (isdimuon) { newtrigExpr +=
"_"+newtrigExpr; }
581 newtrigExpr = std::regex_replace(newtrigExpr,
std::regex(
"HLT_"),
"");
585 double dataFactor = 1.;
586 double mcFactor = 1.;
593 if( (1-mcFactor) > 0. )
594 trig_sf *= (1-dataFactor)/(1-mcFactor);
607 if( !acc_passOR(*
muon) )
continue;
608 if (acc_signal(*
muon)) {
626 if ( ret != StatusCode::SUCCESS) {
627 ATH_MSG_ERROR(
"Cannot configure MuonEfficiencyScaleFactors for systematic var. " << systConfig.
name() );
631 if ( ret != StatusCode::SUCCESS) {
632 ATH_MSG_ERROR(
"Cannot configure MuonBadMuonHighPtScaleFactors for systematic var. " << systConfig.
name() );
636 if ( ret != StatusCode::SUCCESS) {
637 ATH_MSG_ERROR(
"Cannot configure MuonTTVAEfficiencyScaleFactors for systematic var. " << systConfig.
name() );
641 if ( ret != StatusCode::SUCCESS) {
642 ATH_MSG_ERROR(
"Cannot configure MuonIsolationScaleFactors for systematic var. " << systConfig.
name() );
646 if ( ret != StatusCode::SUCCESS) {
647 ATH_MSG_ERROR(
"Cannot configure MuonHighPtIsolationScaleFactors for systematic var. " << systConfig.
name() );
651 if ( ret != StatusCode::SUCCESS) {
652 ATH_MSG_ERROR(
"Cannot configure MuonTriggerScaleFactors for systematic var. " << systConfig.
name() );
656 if (ret != StatusCode::SUCCESS) {
657 ATH_MSG_ERROR(
"Cannot configure TrigGlobalEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.
name() );
661 if (ret != StatusCode::SUCCESS) {
662 ATH_MSG_ERROR(
"Cannot configure TrigGlobalEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.
name() );
669 if ( ret != StatusCode::SUCCESS) {
670 ATH_MSG_ERROR(
"Cannot configure MuonEfficiencyScaleFactors back to default.");
674 if ( ret != StatusCode::SUCCESS) {
675 ATH_MSG_ERROR(
"Cannot configure MuonBadMuonHighPtScaleFactors back to default.");
679 if ( ret != StatusCode::SUCCESS) {
680 ATH_MSG_ERROR(
"Cannot configure MuonTTVAEfficiencyScaleFactors back to default.");
684 if ( ret != StatusCode::SUCCESS) {
685 ATH_MSG_ERROR(
"Cannot configure MuonIsolationScaleFactors back to default.");
689 if ( ret != StatusCode::SUCCESS) {
690 ATH_MSG_ERROR(
"Cannot configure MuonIsolationScaleFactors back to default.");
694 if ( ret != StatusCode::SUCCESS) {
695 ATH_MSG_ERROR(
"Cannot configure MuonTriggerScaleFactors back to default.");
699 if (ret != StatusCode::SUCCESS) {
700 ATH_MSG_ERROR(
"Cannot configure TrigGlobalEfficiencyCorrectionTool (trigger) back to default.");
704 if (ret != StatusCode::SUCCESS) {
705 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
float nPixelDeadSensors(const U &p)
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.
float nSCTDeadSensors(const U &p)
@ 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
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
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