7#include "GaudiKernel/SystemOfUnits.h"
14using namespace Gaudi::Units;
33 return StatusCode::SUCCESS;
49 std::vector<std::unique_ptr<xAOD::Vertex>> offlineDimuons;
51 ATH_MSG_ERROR(
"Problems building offline dimuons, won't fill corresponding histograms");
57 return StatusCode::SUCCESS;
63 ATH_MSG_DEBUG(
"Process container " << monitoredContainerKey.key().c_str());
65 ATH_MSG_ERROR(Form(
"Problems filling %s container histograms", monitoredContainerKey.key().c_str()));
69 return StatusCode::SUCCESS;
74 if( !trigBphysContainer.
isValid() ) {
75 ATH_MSG_WARNING(
"No valid TrigBphysContainer with tag: " << trigBphysContainerKey);
79 std::string monGroupName = std::string(
"Container_")+trigBphysContainerKey.
key();
80 auto monGroup =
getGroup(monGroupName);
83 ncandidates = trigBphysContainer->size();
87 fill(monGroup, ncandidates, bphys_mass);
90 return StatusCode::SUCCESS;
99 ATH_MSG_DEBUG(
"Chain " << monitoredChain <<
" is not passed");
103 ATH_MSG_ERROR(Form(
"Problems filling %s chain histograms", monitoredChain.c_str()));
110 ATH_MSG_DEBUG(
"Chain " << monitoredChain <<
" is not passed");
114 ATH_MSG_ERROR(Form(
"Problems filling %s chain histograms", monitoredChain.c_str()));
121 ATH_MSG_DEBUG(
"Chain " << monitoredChain <<
" is not passed");
125 ATH_MSG_ERROR(Form(
"Problems filling %s chain histograms", monitoredChain.c_str()));
129 return StatusCode::SUCCESS;
133 ATH_MSG_DEBUG(
"Filling " << chainName <<
" chain histograms");
135 std::string monGroupName = std::string(
"Chain_")+chainName;
136 auto monGroup =
getGroup(monGroupName);
139 ATH_MSG_ERROR(Form(
"Problems filling generic histograms for %s chain",chainName.c_str()));
143 for (
const auto& featLinkInfo: chainFeatureContainer){
145 const auto featLink = featLinkInfo.link;
147 ATH_MSG_ERROR(Form(
"Problems filling bphys object histograms for %s chain",chainName.c_str()));
150 ATH_MSG_ERROR(Form(
"Problems filling muon histograms for %s chain",chainName.c_str()));
153 return StatusCode::SUCCESS;
158 ATH_MSG_DEBUG(
"Filling " << chainName <<
" chain histograms");
160 std::string monGroupName = std::string(
"Chain_")+chainName;
161 auto monGroup =
getGroup(monGroupName);
164 ATH_MSG_ERROR(Form(
"Problems filling generic histograms for %s chain",chainName.c_str()));
168 for (
const auto& featLinkInfo: chainFeatureContainer){
170 const auto featLink = featLinkInfo.link;
172 ATH_MSG_ERROR(Form(
"Problems filling bphys object histograms for %s chain",chainName.c_str()));
175 ATH_MSG_ERROR(Form(
"Problems filling muon histograms for %s chain",chainName.c_str()));
178 auto dimuonLink = (*featLink)->lowerChainLink();
181 ATH_MSG_ERROR(Form(
"Problems filling dimuon object histograms for %s chain",chainName.c_str()));
184 ATH_MSG_ERROR(Form(
"Problems filling muon histograms for %s chain",chainName.c_str()));
188 return StatusCode::SUCCESS;
192 ATH_MSG_DEBUG(
"Filling " << chainName <<
" chain histograms");
194 std::string monGroupName = std::string(
"Chain_")+chainName;
195 auto monGroup =
getGroup(monGroupName);
198 ATH_MSG_ERROR(Form(
"Problems filling generic histograms for %s chain",chainName.c_str()));
202 for (
const auto& featLinkInfo: chainFeatureContainer){
204 const auto featLink = featLinkInfo.link;
206 ATH_MSG_ERROR(Form(
"Problems filling bphys object histograms for %s chain",chainName.c_str()));
209 ATH_MSG_ERROR(Form(
"Problems filling muon histograms for %s chain",chainName.c_str()));
212 return StatusCode::SUCCESS;
221 ncandidates = chainFeatureContainer.size();
223 fill(currentMonGroup, ncandidates);
225 return StatusCode::SUCCESS;
238 dimu_mass = (*bphysLink)->mass() /
GeV;
239 dimu_fitmass = (*bphysLink)->fitmass() /
GeV;
240 dimu_pt = (*bphysLink)->pt() /
GeV;
241 dimu_chi2 = (*bphysLink)->fitchi2();
242 dimu_y = (*bphysLink)->eta();
244 fill(currentMonGroup, dimu_mass, dimu_fitmass, dimu_pt, dimu_y, dimu_chi2);
246 return StatusCode::SUCCESS;
253 const std::vector<ElementLink<xAOD::TrackParticleContainer> > trackVector = (*bphysLink)->trackParticleLinks();
254 ATH_MSG_DEBUG(
"fillTrigLeptonHists: number of lepton tracks: " << trackVector.size());
255 if(
fillTracksHists(currentMonGroup, trackVector, name_prefix,
true).isFailure() ) {
256 ATH_MSG_ERROR(Form(
"Problems filling muon histograms for a chain"));
257 return StatusCode::FAILURE;
259 if(
fillDiTracksHists(currentMonGroup, trackVector, std::string(
"di")+name_prefix).isFailure() ) {
260 ATH_MSG_ERROR(Form(
"Problems filling two-muon histograms for a chain"));
261 return StatusCode::FAILURE;
264 return StatusCode::SUCCESS;
270 const std::vector<ElementLink<xAOD::TrackParticleContainer> > trackVector = (*bphysLink)->trackParticleLinks();
271 if (trackVector.size() < tracksStartFrom) {
272 ATH_MSG_WARNING(
"Unexpected number of tracks: "<< trackVector.size() <<
" found, while expected at least " << tracksStartFrom);
273 return StatusCode::SUCCESS;
276 if (
fillTracksHists(currentMonGroup, trackVector,
"trk",
false, tracksStartFrom).isFailure()) {
277 ATH_MSG_ERROR(Form(
"Problems filling track histograms for a BMuMuX chain"));
278 return StatusCode::FAILURE;
281 return StatusCode::SUCCESS;
286 const std::string& prefix,
288 UInt_t offsetIndex)
const {
289 for(UInt_t i = offsetIndex; i < tpLinkVector.size(); ++i) {
291 std::string curPrefix = prefix;
293 curPrefix += std::to_string(i+1);
294 if (
fillTrkHists(currentMonGroup, *tpLinkVector.at(i), curPrefix).isFailure()) {
296 return StatusCode::FAILURE;
299 return StatusCode::SUCCESS;
304 const std::string& name_prefix)
const {
306 if (tpLinkVector.size() <2) {
307 ATH_MSG_ERROR(
"Unexpected number of tracks in a dimuon: " << tpLinkVector.size());
308 return StatusCode::FAILURE;
320 ditrk_deta = std::abs(trk1->
eta()-trk2->
eta());
323 fill(currentMonGroup, ditrk_dR, ditrk_deta, ditrk_dphi);
325 return StatusCode::SUCCESS;
332 return StatusCode::FAILURE;
338 trk_pt = trk->
pt() /
GeV;
339 trk_eta = trk->
eta();
342 fill(currentMonGroup, trk_pt, trk_eta, trk_d0);
344 return StatusCode::SUCCESS;
349 std::vector<std::string> dimuonMonGroupNames = {
"Any"};
353 for(
const auto& dimuonMonGroupName : dimuonMonGroupNames) {
355 if(dimuonMonGroupName !=
"Any") {
356 auto& monitoredChain = dimuonMonGroupName;
357 if( !(dimuonMonGroupName ==
"Any") && !
isChainPassed(monitoredChain) ) {
358 ATH_MSG_DEBUG(
"Chain " << monitoredChain <<
" is not passed");
363 ATH_MSG_ERROR(Form(
"Problems filling offline dimuon histograms for %s", dimuonMonGroupName.c_str()));
367 return StatusCode::SUCCESS;
371 ATH_MSG_DEBUG(
"Filling " << dimuonMonGroupName <<
" offline dimuons histograms");
374 std::vector<const xAOD::Vertex*> matchedDimuons;
375 for(
auto& offlineDimuon : dimuonContainer) {
376 if( dimuonMonGroupName ==
"Any" ||
matchDimuon(offlineDimuon.get(), dimuonMonGroupName) )
377 matchedDimuons.push_back(offlineDimuon.get());
380 std::string monGroupName = std::string(
"OfflineDimu_")+dimuonMonGroupName;
381 auto monGroup =
getGroup(monGroupName);
384 ncandidates = matchedDimuons.size();
386 fill(monGroup, ncandidates);
388 for(
auto matchedDimuon : matchedDimuons) {
390 ATH_MSG_ERROR(Form(
"Problems filling histogram for an offline dimuon vertex in %s", dimuonMonGroupName.c_str()));
392 if (
fillTracksHists(monGroup, matchedDimuon->trackParticleLinks(),
"mu",
true).isFailure()) {
393 ATH_MSG_ERROR(Form(
"Problems filling histogram for offline dimuon muons in %s", dimuonMonGroupName.c_str()));
395 if (
fillDiTracksHists(monGroup, matchedDimuon->trackParticleLinks(),
"dimu").isFailure()) {
396 ATH_MSG_ERROR(Form(
"Problems filling histogram for offline dimuon muon pairs in %s", dimuonMonGroupName.c_str()));
400 return StatusCode::SUCCESS;
407 if(dimuonVertexHelper.
nRefTrks() != 2) {
409 return StatusCode::SUCCESS;
422 dimu_mass = dimuonMom.M() /
GeV;
423 dimu_pt = dimuonMom.Pt() /
GeV;
424 dimu_chi2 = vertex->chiSquared();
425 dimu_y = dimuonMom.Rapidity();
429 fill(currentMonGroup, dimu_mass, dimu_pt, dimu_y, dimu_chi2, dimu_Lxy, dimu_LxySig);
431 return StatusCode::SUCCESS;
455 std::vector<const xAOD::Muon*> selectedMuons;
457 if ( mu ==
nullptr )
continue;
458 if ( mu->muonType() != xAOD::Muon::Combined )
continue;
459 if (!mu->inDetTrackParticleLink())
continue;
460 if (!mu->inDetTrackParticleLink().isValid())
continue;
461 selectedMuons.push_back(mu);
463 if(selectedMuons.size() < 2) {
464 ATH_MSG_DEBUG(
"Only " << selectedMuons.size() <<
"muons pass preselection");
465 return StatusCode::SUCCESS;
467 std::sort(selectedMuons.begin(), selectedMuons.end(), [](
const auto mu1,
const auto mu2){ return mu1->pt() > mu2->pt(); });
470 for(
auto outerItr=selectedMuons.begin(); outerItr<selectedMuons.end(); ++outerItr){
471 for(
auto innerItr=(outerItr+1); innerItr!=selectedMuons.end(); ++innerItr){
472 const auto muon1 = *outerItr;
473 const auto muon2 = *innerItr;
474 const auto trackParticle1 = muon1->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
475 const auto trackParticle2 = muon2->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
477 if(trackParticle1->qOverP() * trackParticle2->qOverP() > 0.)
480 double dimu_momentum_prefit =
dimuonMass(trackParticle1, trackParticle2);
484 std::unique_ptr<xAOD::Vertex> dimuon =
dimuonFit(trackParticle1, trackParticle2);
485 if(!dimuon)
continue;
487 vxContainer.push_back(std::move(dimuon));
490 ATH_MSG_DEBUG(
"Found " << vxContainer.size() <<
" good dimuons");
493 if( !vxContainer.empty() ) {
497 std::vector<const xAOD::Vertex*> goodPVs =
GetGoodPVs(pvContainer);
499 for(
auto& dimuon : vxContainer) {
512 return StatusCode::SUCCESS;
519 int sflag = 0;
int errorcode = 0;
521 if (errorcode != 0) {startingPoint(0) = 0.0; startingPoint(1) = 0.0; startingPoint(2) = 0.0;}
522 const std::vector<const xAOD::TrackParticle*> trackPair = {mu1, mu2};
523 std::unique_ptr<xAOD::Vertex> myVxCandidate(
m_vertexFitter->fit(trackPair, startingPoint));
525 return myVxCandidate;
530 for (
const auto& featLinkInfo: chainFeatureContainer){
531 if(!featLinkInfo.isValid())
533 const auto featLink = featLinkInfo.link;
543 if(!offlineTrk1 || !offlineTrk2) {
544 ATH_MSG_DEBUG(
"TrackParticle from dimuon is null, won't match");
548 const std::vector<ElementLink<xAOD::TrackParticleContainer> > trackVector = (*bphysLink)->trackParticleLinks();
549 if (trackVector.size() < 2) {
550 ATH_MSG_ERROR(
"Unexpected number of tracks in a dimuon: " << trackVector.size() <<
", won't match");
556 if( !trackVector.at(0).isValid() || !trackVector.at(1).isValid() )
558 hltTrk1 = *trackVector.at(0);
559 hltTrk2 = *trackVector.at(1);
560 if (!hltTrk1 || !hltTrk2) {
590 std::vector<const xAOD::Vertex*> goodPrimaryVertices;
591 goodPrimaryVertices.reserve(pvContainer->
size());
592 for (
auto pv : *pvContainer) {
595 goodPrimaryVertices.push_back(pv);
598 return goodPrimaryVertices;
602 std::vector<const xAOD::Vertex*>::const_iterator pv = std::min_element(PVs.begin(), PVs.end(),
604 { return (std::abs(m_v0Tools->a0(vtx, pv1)) < std::abs(m_v0Tools->a0(vtx, pv2)));}
606 if(pv == PVs.end()) {
Scalar deltaR(const MatrixBase< Derived > &vec) const
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
: B-physics xAOD helpers.
xAOD::MuonContainer * muonContainer
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
virtual StatusCode initialize() override
initialize
const ToolHandle< Trig::TrigDecisionTool > & getTrigDecisionTool() const
Get the trigger decision tool member.
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
size_type size() const noexcept
Returns the number of elements in the collection.
ElementLink implementation for ROOT usage.
Declare a monitored scalar variable.
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const std::string & key() const
Return the StoreGate ID for the referenced object.
StatusCode fillChains(const EventContext &ctx) const
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
Gaudi::Property< double > m_deltaRMatchingThreshold
bool matchTrackParticles(const xAOD::TrackParticle *trk1, const xAOD::TrackParticle *trk2) const
SG::ReadHandleKey< xAOD::MuonContainer > m_offlineMuonCollectionKey
Gaudi::Property< double > m_dimuMassLower_prefit
bool matchDimuon(const xAOD::Vertex *dimuonVertex, const std::string &chainName) const
Gaudi::Property< std::vector< std::string > > m_ChainNames_MuMu
ToolHandle< Trk::V0Tools > m_v0Tools
StatusCode fillVertexHists(const ToolHandle< GenericMonitoringTool > ¤tMonGroup, const xAOD::Vertex *vertex, const std::string &objStr) const
Gaudi::Property< double > m_dimuMassUpper_prefit
virtual ~TrigBphysMonitorAlgorithm()
StatusCode fillChainGenericHists(const EventContext &, const ToolHandle< GenericMonitoringTool > ¤tMonGroup, const std::string &chainName) const
StatusCode fillDiTracksHists(const ToolHandle< GenericMonitoringTool > ¤tMonGroup, const std::vector< ElementLink< xAOD::TrackParticleContainer > > &tpLinkVector, const std::string &name_prefix) const
StatusCode fillDimuonChainHists(const EventContext &ctx, const std::string &chainName) const
StatusCode fillBphysObjectHists(const ToolHandle< GenericMonitoringTool > ¤tMonGroup, const ElementLink< xAOD::TrigBphysContainer > &bphysLink, const std::string &objStr) const
virtual StatusCode initialize() override
initialize
StatusCode fillTrigBmumuxTrkHists(const ToolHandle< GenericMonitoringTool > ¤tMonGroup, const ElementLink< xAOD::TrigBphysContainer > &bphysLink, UInt_t tracksStartFrom=2) const
Gaudi::Property< double > m_dimuChi2Cut
StatusCode fillBmumuxChainHists(const EventContext &ctx, const std::string &chainName) const
SG::ReadHandleKey< xAOD::VertexContainer > m_offlinePvCollectionKey
bool isChainPassed(const std::string &chain) const
StatusCode fillContainerHists(const EventContext &ctx, const SG::ReadHandleKey< xAOD::TrigBphysContainer > &trigBphysContainerKey) const
Gaudi::Property< std::vector< std::string > > m_ChainNames_MuMuX
ToolHandle< InDet::VertexPointEstimator > m_vertexPointEstimator
std::vector< const xAOD::Vertex * > GetGoodPVs(const xAOD::VertexContainer *pvContainer) const
StatusCode fillOfflineDimuonHists(const EventContext &, const std::string &dimuonMonGroupName, const std::vector< std::unique_ptr< xAOD::Vertex > > &dimuonContainer) const
StatusCode fillContainers(const EventContext &ctx) const
For lxy etc.
StatusCode fillOfflineDimuons(const EventContext &ctx, const std::vector< std::unique_ptr< xAOD::Vertex > > &dimuonContainer) const
StatusCode fillTrigLeptonHists(const ToolHandle< GenericMonitoringTool > ¤tMonGroup, const ElementLink< xAOD::TrigBphysContainer > &bphysLink, const std::string &name_prefix) const
StatusCode fillTracksHists(const ToolHandle< GenericMonitoringTool > ¤tMonGroup, const std::vector< ElementLink< xAOD::TrackParticleContainer > > &tpLinkVector, const std::string &prefix, bool separateHists=false, UInt_t offsetIndex=0) const
const xAOD::Vertex * getPvForDimuon_lowestA0(const xAOD::Vertex *vtx, const std::vector< const xAOD::Vertex * > &PVs) const
StatusCode fillTrkHists(const ToolHandle< GenericMonitoringTool > ¤tMonGroup, const xAOD::TrackParticle *trk, const std::string &name_prefix) const
std::unique_ptr< xAOD::Vertex > dimuonFit(const xAOD::TrackParticle *mu1, const xAOD::TrackParticle *mu2) const
Gaudi::Property< bool > m_requireExplicitESDecision
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_offlineIDTrackCollectionKey
SG::ReadHandleKeyArray< xAOD::TrigBphysContainer > m_TrigBphysContainerKeys
StatusCode fillDielectronChainHists(const EventContext &ctx, const std::string &chainName) const
TrigBphysMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
StatusCode buildDimuons(const EventContext &ctx, std::vector< std::unique_ptr< xAOD::Vertex > > &vxContainer) const
Gaudi::Property< std::vector< std::string > > m_ChainNames_ElEl
double dimuonMass(const xAOD::TrackParticle *mu1, const xAOD::TrackParticle *mu2) const
ToolHandle< Trk::TrkVKalVrtFitter > m_vertexFitter
bool setLxyErr(const float val, const pv_type vertexType=BPhysHelper::PV_MIN_A0)
its error
bool setLxy(const float val, const pv_type vertexType=BPhysHelper::PV_MIN_A0)
Set the transverse decay distance and its error measured between the refitted primary vertex of type ...
float lxy(const pv_type vertexType=BPhysHelper::PV_MIN_A0)
Get the transverse decay distance and its error measured between the refitted primary vertex of type ...
bool setRefTrks(std::vector< float > px, std::vector< float > py, std::vector< float > pz)
Sets refitted track momenta.
int nRefTrks()
Returns number of stored refitted track momenta.
TVector3 totalP()
: Returns total 3-momentum calculated from the refitted tracks
float lxyErr(const pv_type vertexType=BPhysHelper::PV_MIN_A0)
its error
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzM4D< double > > GenVecFourMom_t
Base 4 Momentum type for TrackParticle.
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
float d0() const
Returns the parameter.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
GenVecFourMom_t genvecP4() const
The full 4-momentum of the particle : GenVector form.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
float fitmass() const
accessor method: mass from vertex fit
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
Eigen::Matrix< double, 3, 1 > Vector3D
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
static const unsigned int Express_passed
static const unsigned int Physics
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
TrackParticle_v1 TrackParticle
Reference the current persistent version:
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
TrigBphysContainer_v1 TrigBphysContainer
std::array< double, 6 > mass
void fill(H5::Group &out_file, size_t iterations)