14 constexpr double MeVtoGeV = 1. / Gaudi::Units::GeV;
20 sstr <<
" Muon pT: " << mu->pt() * MeVtoGeV <<
" [GeV], eta: " << mu->eta() <<
", phi: " << mu->phi() <<
", q: " << mu->charge()
21 <<
", priamry Author: " << mu->author();
24 sstr <<
" Electron pT: " << elec->
pt() * MeVtoGeV <<
" [GeV], eta: " << elec->
eta() <<
", phi: " << elec->
phi()
25 <<
", q: " << elec->
charge();
28 sstr <<
" Track pT: " << trk->
pt() * MeVtoGeV <<
" [GeV], eta: " << trk->
eta() <<
", phi: " << trk->
phi()
29 <<
", q: " << trk->
charge() <<
", d0: " << trk->
d0() <<
", z0: " << trk->
z0();
31 sstr <<
" index: " << part->index();
35std::ostream&
operator<<(std::ostream& sstr,
const LeptonQuadruplet& quad) {
37 for (
const xAOD::IParticle* lep : quad) { sstr <<
" **** " << lep << std::endl; }
57 return StatusCode::FAILURE;
60 return StatusCode::SUCCESS;
63 unsigned int n_processed = std::accumulate(m_num_lep.begin(), m_num_lep.end(), 0, [](
const std::atomic<unsigned int>& l,
unsigned int n){
66 ATH_MSG_INFO(
"Proccessed in total "<<n_processed<<
" events. Lepton multiplicities observed:");
67 for (
unsigned int l = 0 ; l < m_num_lep.size(); ++l) {
68 ATH_MSG_INFO(
" ---- Events with "<<l<<
" leptons: "<<m_num_lep[l]<<
" (elec/muon) "<<m_num_ele[l]<<
"/"<<m_num_muo[l]<<
" ("<<(100.*m_num_lep[l] / std::max(1u,n_processed))<<
"%)" );
72 return StatusCode::SUCCESS;
77 ATH_CHECK(vtxContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()));
82 std::unique_ptr<xAOD::Vertex> candidate =
fitQuadruplet(ctx, quad);
83 if (candidate) out_container->
push_back(std::move(candidate));
85 return StatusCode::SUCCESS;
96 std::vector<LeptonQuadruplet> to_ret{};
102 throw std::runtime_error(
"Invalid key access");
105 if (!elecContainer.
isValid()) {
107 throw std::runtime_error(
"Invalid key access");
110 using PartVec = std::vector<const xAOD::IParticle*>;
111 PartVec selected_lep{};
112 const size_t num_lep = elecContainer->size() +
muonContainer->size();
115 ++m_num_lep[num_lep];
116 ++m_num_ele[elecContainer->size()];
120 selected_lep.reserve(num_lep);
121 size_t n_ele{0},n_muo{0};
125 selected_lep.push_back(muon);
132 selected_lep.push_back(elec);
137 ++m_num_lep[std::min(m_num_lep.size() -1 , n_ele + n_muo)];
138 ++m_num_ele[std::min(m_num_ele.size() -1 , n_ele)];
139 ++m_num_muo[std::min(m_num_muo.size() -1 , n_muo)];
141 if (selected_lep.size() < 4) {
145 std::sort(selected_lep.begin(),selected_lep.end(),
147 return a->pt() > b->pt();});
151 to_ret.reserve(std::pow(selected_lep.size(), 4));
152 for (PartVec::const_iterator itr1 = selected_lep.begin() + 3; itr1 != selected_lep.end(); ++itr1) {
153 for (PartVec::const_iterator itr2 = selected_lep.begin() + 2; itr2 != itr1; ++itr2) {
154 for (PartVec::const_iterator itr3 = selected_lep.begin() + 1; itr3 != itr2; ++itr3) {
156 for (PartVec::const_iterator itr4 = selected_lep.begin(); itr4 != itr3; ++itr4) {
162 to_ret.push_back(std::move(quad));
178 if (acc_charge.
isAvailable(*part))
return acc_charge(*part);
184 std::vector<const xAOD::TrackParticle*> trks{};
191 throw std::runtime_error(
"Invalid key access");
194 const Amg::Vector3D beam_spot{evtInfo->beamPosX(), evtInfo->beamPosY(), evtInfo->beamPosZ()};
195 std::unique_ptr<xAOD::Vertex> common_vtx =
m_fitter->fit(ctx, trks, beam_spot);
200 const float redChi2 = (common_vtx->chiSquared() / common_vtx->numberDoF());
201 ATH_MSG_DEBUG(
"Fit from " << quad <<
" gave a vertex with position at " << common_vtx->position() <<
" with chi2 "
202 << redChi2 <<
" nDoF: " << common_vtx->numberDoF());
207 static const std::vector<float> empty_vec{};
209 if (
m_pruneCov) common_vtx->setCovariance(empty_vec);
210 std::vector<TrkLink> track_links{};
213 TrkLink link{*cont, trk->index(), ctx};
215 track_links.push_back(std::move(link));
217 common_vtx->setTrackParticleLinks(track_links);
223 for (
unsigned int i = 1; i < quad.size(); ++i) {
224 for (
unsigned int j = 0; j < i; ++j) {
228 if (std::abs(trk_b->
z0() - trk_a->
z0()) >
m_z0Cut)
return false;
231 const float di_m1 = (quad[i]->p4() + quad[j]->p4()).M();
232 const bool isSFOS1 =
charge(quad[i])*
charge(quad[j]) < 0 && quad[i]->type() == quad[j]->type();
235 max_m = std::max(di_m1, max_m);
236 for (
unsigned int k = 1 ; k < quad.size(); ++k) {
237 if (k == i || k == j)
continue;
238 for (
unsigned int l = 0; l < k ; ++l) {
239 if (l == i || l == j)
continue;
240 const float di_m2 = (quad[k]->p4() + quad[l]->p4()).M();
241 const bool isSFOS2 =
charge(quad[k])*
charge(quad[l]) < 0 && quad[k]->type() == quad[l]->type();
243 max_m = std::max(max_m, di_m2);
#define ATH_CHECK
Evaluate an expression and check for errors.
std::ostream & operator<<(std::ostream &sstr, const xAOD::IParticle *part)
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
xAOD::MuonContainer * muonContainer
An algorithm that can be simultaneously executed in multiple threads.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const xAOD::TrackParticle * trackParticle(const xAOD::IParticle *part) const
Gaudi::Property< bool > m_pruneCov
SG::WriteHandleKey< xAOD::VertexContainer > m_vtxKey
xAOD::Muon::TrackParticleType MuonTrk
StatusCode initialize() override
ToolHandle< IAsgElectronLikelihoodTool > m_elecSelTool
Gaudi::Property< bool > m_elecUseGSF
SG::ReadHandleKey< xAOD::ElectronContainer > m_elecKey
bool passSelection(const xAOD::Electron *elec) const
std::atomic< unsigned int > m_good_fits
How many vertex fits were actually successful.
std::array< const xAOD::IParticle *, 4 > LeptonQuadruplet
ToolHandle< Trk::IVertexFitter > m_fitter
Gaudi::Property< float > m_minMuonPt
FourLeptonVertexingAlgorithm(const std::string &n, ISvcLocator *p)
SG::ReadHandleKey< xAOD::MuonContainer > m_muonKey
Input containers.
Gaudi::Property< int > m_muonTrkProp
std::vector< LeptonQuadruplet > buildAllQuadruplets(const EventContext &ctx) const
Gaudi::Property< bool > m_pruneWeight
std::atomic< unsigned int > m_tried_fits
How many vertex fits were attempted.
SG::ReadHandleKey< xAOD::EventInfo > m_evtKey
Gaudi::Property< float > m_LeadPtCut
Gaudi::Property< float > m_highPair_Cut
Gaudi::Property< float > m_minElecPt
int charge(const xAOD::IParticle *part) const
std::unique_ptr< xAOD::Vertex > fitQuadruplet(const EventContext &ctx, const LeptonQuadruplet &quad) const
StatusCode finalize() override
Gaudi::Property< float > m_lowSFOS_Cut
StatusCode execute(const EventContext &ctx) const override
Gaudi::Property< float > m_z0Cut
Gaudi::Property< float > m_VtxChi2Cut
ToolHandle< CP::IMuonSelectionTool > m_muonSelTool
Gaudi::Property< float > m_SubLeadPtCut
ElementLink implementation for ROOT usage.
SG::ConstAccessor< T, ALLOC > ConstAccessor
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
virtual double phi() const override final
The azimuthal angle ( ) of the particle.
float charge() const
Obtain the charge of the object.
Class providing the definition of the 4-vector interface.
float z0() const
Returns the parameter.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
float d0() const
Returns the parameter.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
float charge() const
Returns the charge.
Eigen::Matrix< double, 3, 1 > Vector3D
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ TrackParticle
The object is a charged track particle.
@ Muon
The object is a muon.
@ Electron
The object is an electron.
std::vector< const xAOD::TrackParticle * > getTrackParticlesVec(const xAOD::Egamma *eg, bool useBremAssoc=true, bool allParticles=true)
Return a list of all or only the best TrackParticle associated to the object.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
Muon_v1 Muon
Reference the current persistent version:
Electron_v1 Electron
Definition of the current "egamma version".