24#include "HepPDT/ParticleDataTable.hh"
38 declareInterface<InDetV0FinderTool>(
this);
122 std::string BDTPathName =
"InDetV0FinderTool/BDT/v1/" +
m_BDTFile;
125 std::unique_ptr<TFile> rootFile(TFile::Open(fullPathToFile.c_str(),
"READ"));
126 std::string strBDTName =
"xgboost";
127 std::unique_ptr<TTree> training( (TTree*)rootFile->Get(strBDTName.c_str()) );
128 m_BDT = std::make_unique<MVAUtils::BDT>(training.get());
168 ATH_MSG_FATAL(
"The vertex fitter passed is not a V0 Vertex Fitter");
169 return StatusCode::FAILURE;
177 return StatusCode::SUCCESS;
186 const EventContext& ctx
191 std::vector<const xAOD::TrackParticleContainer*> trackCols;
194 trackCols.push_back(handle.
cptr());
204 return StatusCode::SUCCESS;
212 return StatusCode::SUCCESS;
214 ATH_MSG_DEBUG(
"Track particle container size " << TPC->size());
222 beamspot = beamSpotHandle->beamPos();
227 beamspot =
Amg::Vector3D(beamPosX(0), beamPosY(0), beamPosZ(0));
230 std::vector<const xAOD::TrackParticle*> posTracks; posTracks.clear();
231 std::vector<const xAOD::TrackParticle*> negTracks; negTracks.clear();
233 if (
m_pv && primaryVertex) vx = primaryVertex;
235 if (TPC->size() > 1) {
237 for ( tpIt=TPC->begin(); tpIt!=TPC->end(); ++tpIt )
248 for (
const auto *
const vx : *vertices)
258 if (foundVertex)
break;
261 bool useTrack =
false;
263 if (
m_useorigin && foundVertex ==
nullptr) useTrack =
true;
264 if (!useTrack)
continue;
268 bool d0wrtVertex =
true;
270 if ( !
d0Pass(TP,vertColl, ctx) ) d0wrtVertex =
false;
274 if ( !
d0Pass(TP,primaryVertex, ctx) ) d0wrtVertex =
false;
276 if ( !
d0Pass(TP,beamspot, ctx) ) d0wrtVertex =
false;
279 if (!d0wrtVertex)
continue;
282 posTracks.push_back(TP);
283 negTracks.push_back(TP);
286 posTracks.push_back(*tpIt);
288 negTracks.push_back(*tpIt);
294 ATH_MSG_DEBUG(
"number of tracks passing preselection, positive " << posTracks.size() <<
" negative " << negTracks.size());
296 if (!posTracks.empty() && !negTracks.empty())
313 std::vector<const xAOD::TrackParticle*>::const_iterator tpIt1;
314 std::vector<const xAOD::TrackParticle*>::const_iterator tpIt2;
316 for (tpIt1 = posTracks.begin(); tpIt1 != posTracks.end(); ++tpIt1)
323 double pt1 = TP1->
pt();
326 for (tpIt2 = negTracks.begin(); tpIt2 != negTracks.end(); ++tpIt2)
328 if (*tpIt1 == *tpIt2)
continue;
336 ATH_MSG_DEBUG(
"nclus1 " << (
int)nclus1 <<
" nclus2 " << (
int)nclus2);
341 double pt2 = TP2->
pt();
343 bool trk_cut1 =
false;
344 bool trk_cut2 =
false;
345 if (nclus1 != 0) trk_cut1 =
true;
346 if (nclus1 == 0 && pt1 >=
m_ptTRT) trk_cut1 =
true;
347 if (!trk_cut1)
continue;
348 if (nclus2 != 0) trk_cut2 =
true;
349 if (nclus2 == 0 && pt2 >=
m_ptTRT) trk_cut2 =
true;
350 if (!trk_cut2)
continue;
358 if (errorcode != 0) {startingPoint(0) = 0.0; startingPoint(1) = 0.0; startingPoint(2) = 0.0;}
359 bool errorCode =
false;
360 if (errorcode == 0 || errorcode == 5 || errorcode == 6 || errorcode == 8) errorCode =
true;
361 if (!errorCode)
continue;
364 bool d0wrtVertex =
true;
366 if ( !
d0Pass(TP1,TP2,vertColl, ctx) ) d0wrtVertex =
false;
368 if (!d0wrtVertex)
continue;
372 if (
doFit(TP1,TP2,startingPoint, ctx) )
374 std::vector<const xAOD::TrackParticle*> pairV0;
376 pairV0.push_back(TP1);
377 pairV0.push_back(TP2);
382 std::unique_ptr<xAOD::Vertex> myVxCandidate;
386 myVxCandidate = std::unique_ptr<xAOD::Vertex>(
m_iVKVertexFitter->fit(pairV0, startingPoint) );
394 bool doKshortFit =
false;
395 doKshortFit =
doMassFit(myVxCandidate.get(),310);
396 bool doLambdaFit =
false;
397 doLambdaFit =
doMassFit(myVxCandidate.get(),3122);
398 bool doLambdabarFit =
false;
399 doLambdabarFit =
doMassFit(myVxCandidate.get(),-3122);
401 if (doKshortFit || doLambdaFit || doLambdabarFit)
403 bool pointAtVert =
true;
405 if ( !
pointAtVertexColl(myVxCandidate.get(),vertColl,score) ) pointAtVert =
false;
408 if ( !
pointAtVertex(myVxCandidate.get(),primaryVertex,score) ) pointAtVert =
false;
415 std::unique_ptr<xAOD::Vertex> myKshort;
416 std::unique_ptr<xAOD::Vertex> myLambda;
417 std::unique_ptr<xAOD::Vertex> myLambdabar;
418 std::unique_ptr<xAOD::Vertex> myGamma;
419 bool foundKshort =
false;
420 bool foundLambda =
false;
421 bool foundLambdabar =
false;
424 myKshort = std::unique_ptr<xAOD::Vertex>(
massFit(310, pairV0, vertex) );
434 myLambda = std::unique_ptr<xAOD::Vertex>(
massFit(3122, pairV0, vertex) );
444 myLambdabar = std::unique_ptr<xAOD::Vertex>(
massFit(-3122, pairV0, vertex));
448 foundLambdabar =
true;
453 bool doGamma =
false;
455 double gamma_prob = -1., gamma_mass = -1., gamma_massErr = -1.;
456 if (foundKshort || foundLambda || foundLambdabar) doGamma =
true;
465 myVxCandidate->clearTracks();
468 myVxCandidate->addTrackAtVertex(newLink1);
469 myVxCandidate->addTrackAtVertex(newLink2);
470 v0Container->
push_back(myVxCandidate.release());
472 v0_BDTScore( *(v0Container->
back()) ) = score;
476 myKshort->clearTracks();
479 myKshort->addTrackAtVertex(ksLink1);
480 myKshort->addTrackAtVertex(ksLink2);
481 ksContainer->
push_back(myKshort.release());
485 v0LinksDecorks(*(ksContainer->
back())) = v0Link;
489 v0_ksLinksDecor(*(v0Container->
back())) = ksLink;
491 v0_ksLinksDecor(*(v0Container->
back())) = ksLink;
495 myLambda->clearTracks();
498 myLambda->addTrackAtVertex(laLink1);
499 myLambda->addTrackAtVertex(laLink2);
500 laContainer->
push_back(myLambda.release());
504 v0LinksDecorlb(*(laContainer->
back())) = v0Link;
508 v0_laLinksDecor(*(v0Container->
back())) = laLink;
510 v0_laLinksDecor(*(v0Container->
back())) = laLink;
514 myLambdabar->clearTracks();
517 myLambdabar->addTrackAtVertex(lbLink1);
518 myLambdabar->addTrackAtVertex(lbLink2);
519 lbContainer->
push_back(myLambdabar.release());
523 v0LinksDecorlbb(*(lbContainer->
back())) = v0Link;
527 v0_lbLinksDecor(*(v0Container->
back())) = lbLink;
529 v0_lbLinksDecor(*(v0Container->
back())) = lbLink;
532 myGamma = std::unique_ptr<xAOD::Vertex>(
massFit(22, pairV0, vertex) );
535 gamma_prob =
m_V0Tools->vertexProbability(myGamma.get());
540 mDecor_gfit( *(v0Container->
back()) ) = gamma_fit;
541 mDecor_gmass( *(v0Container->
back()) ) = gamma_mass;
542 mDecor_gmasserr( *(v0Container->
back()) ) = gamma_massErr;
543 mDecor_gprob( *(v0Container->
back()) ) = gamma_prob;
565 if (v0Container->
empty())
ATH_MSG_DEBUG(
"No Candidates found. Empty container returned");
566 if (ksContainer->
empty())
ATH_MSG_DEBUG(
"No Kshort Candidates found. Empty container returned");
567 if (laContainer->
empty())
ATH_MSG_DEBUG(
"No Lambda Candidates found. Empty container returned");
568 if (lbContainer->
empty())
ATH_MSG_DEBUG(
"No Lambdabar Candidates found. Empty container returned");
570 return StatusCode::SUCCESS;
576 <<
"----------------------------------------------------------------------------------------------------------------------------------------------" <<
endmsg
583 msg(MSG::DEBUG) <<
"----------------------------------------------------------------------------------------------------------------------------------------------" <<
endmsg;
585 return StatusCode::SUCCESS;
598 double srxy = startingPoint.perp();
601 double massKshort_i=2000001., massLambda_i=2000001., massLambdabar_i=2000001.;
604 std::vector<std::unique_ptr<const Trk::TrackParameters> > cleanup;
608 if (extrapolatedPerigee1 ==
nullptr) extrapolatedPerigee1 = &track1->
perigeeParameters();
609 else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee1));
612 if (extrapolatedPerigee2 ==
nullptr) extrapolatedPerigee2 = &track2->
perigeeParameters();
613 else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee2));
615 if (extrapolatedPerigee1 !=
nullptr && extrapolatedPerigee2 !=
nullptr) {
621 (massLambdabar_i >=
m_ulamin && massLambdabar_i <=
m_ulamax)) ) pass =
true;
632 bool hasInnerPixHit1 =
true;
633 bool hasInnerPixHit2 =
true;
636 uint8_t nInnerHits1 = numberOfInnermostPixelLayerHits(*track1);
637 if (nInnerHits1 == 0) hasInnerPixHit1 =
false;
638 uint8_t nInnerHits2 = numberOfInnermostPixelLayerHits(*track2);
639 if (nInnerHits2 == 0) hasInnerPixHit2 =
false;
641 for (
auto vItr=vertColl->
begin(); vItr!=vertColl->
end(); ++vItr )
645 if (per1 ==
nullptr)
continue;
647 if (per2 ==
nullptr)
continue;
648 double d0_1 = per1->parameters()[
Trk::d0];
649 double sig_d0_1 = sqrt((*per1->covariance())(0,0));
650 double delta_z0_1 = track1->
z0() + track1->
vz() - PV->
z();
651 double d0_2 = per2->parameters()[
Trk::d0];
652 double sig_d0_2 = sqrt((*per2->covariance())(0,0));
653 double delta_z0_2 = track2->
z0() + track2->
vz() - PV->
z();
654 bool IP_check1 = (std::abs(d0_1/sig_d0_1) >
m_d0_cut) || !hasInnerPixHit1;
657 bool IP_check2 = (std::abs(d0_2/sig_d0_2) >
m_d0_cut) || !hasInnerPixHit2;
660 if (IP_check1 && IP_check2)
return true;
670 bool hasInnerPixHit1 =
true;
673 uint8_t nInnerHits1 = numberOfInnermostPixelLayerHits(*track1);
674 if (nInnerHits1 == 0) hasInnerPixHit1 =
false;
676 for (
auto vItr=vertColl->
begin(); vItr!=vertColl->
end(); ++vItr )
680 if (per1 ==
nullptr)
continue;
681 double d0_1 = per1->parameters()[
Trk::d0];
682 double sig_d0_1 = sqrt((*per1->covariance())(0,0));
683 double delta_z0_1 = track1->
z0() + track1->
vz() - PV->
z();
684 if (((std::abs(d0_1/sig_d0_1) >
m_d0_cut) ||
685 (!hasInnerPixHit1)) &&
696 bool hasInnerPixHit1 =
true;
699 uint8_t nInnerHits1 = numberOfInnermostPixelLayerHits(*track1);
700 if (nInnerHits1 == 0) hasInnerPixHit1 =
false;
703 if (per1 ==
nullptr)
return pass;
704 double d0_1 = per1->parameters()[
Trk::d0];
705 double sig_d0_1 = sqrt((*per1->covariance())(0,0));
706 double delta_z0_1 = track1->
z0() + track1->
vz() - PV->
z();
707 if (((std::abs(d0_1/sig_d0_1) >
m_d0_cut) ||
708 (!hasInnerPixHit1)) &&
717 bool hasInnerPixHit1 =
true;
720 uint8_t nInnerHits1 = numberOfInnermostPixelLayerHits(*track1);
721 if (nInnerHits1 == 0) hasInnerPixHit1 =
false;
724 if (per1 ==
nullptr)
return pass;
725 double d0_1 = per1->parameters()[
Trk::d0];
726 double sig_d0_1 = sqrt((*per1->covariance())(0,0));
727 double delta_z0_1 = track1->
z0() + track1->
vz() - PV.z();
728 if (((std::abs(d0_1/sig_d0_1) >
m_d0_cut) ||
729 (!hasInnerPixHit1)) &&
739 float v0lxyError =
m_V0Tools->lxyError(v0,PV);
744 float prob =
m_V0Tools->vertexProbability(v0);
745 float nLogProb = 999999;
746 if (prob>0) nLogProb = -1*log10f(prob);
747 std::vector<float> bdt_vars = {
754 float this_Score=
m_BDT->GetClassification(bdt_vars);
755 if (this_Score > score) {
772 for ( vItr=vertColl->
begin(); vItr!=vertColl->
end(); ++vItr ) {
if (
pointAtVertex(v0,(*vItr),score)) pass =
true; }
778 double e1sq = per1->
momentum().mag2() + m1*m1;
779 double e1 = (e1sq>0.) ? sqrt(e1sq) : 0.;
780 double e2sq = per2->
momentum().mag2() + m2*m2;
781 double e2 = (e2sq>0.) ? sqrt(e2sq) : 0.;
783 double msq = (e1+e2+p)*(e1+e2-p);
784 double mass = (msq>0.) ? sqrt(msq) : 0.;
791 double mass = 1000000000.;
792 double error = 1000000001.;
793 bool in_mass_window =
false;
794 double winmass_min = 0., winmass_max = 0.;
801 if (mass >= winmass_min && mass <= winmass_max &&
error <=
m_errmass) in_mass_window =
true;
802 }
else if (pdgID == 3122 || pdgID == -3122) {
808 }
else if (pdgID == -3122) {
812 if (mass >= winmass_min && mass <= winmass_max &&
error <=
m_errmass) in_mass_window =
true;
814 if (in_mass_window) pass =
true;
822 std::vector<double> masses;
826 }
else if (pdgID == 3122) {
829 }
else if (pdgID == -3122) {
832 }
else if (pdgID == 22) {
854 if (pdgID == -3122) {
866 const std::vector<const xAOD::TrackParticleContainer*>& trackcols)
const
870 bool elementSet =
false;
871 if(trackcols.empty()){
876 auto itr = std::find(trkcol->begin(), trkcol->end(), tp);
877 if(itr != trkcol->end()){
884 if(!elementSet)
ATH_MSG_ERROR(
"Track was not found when linking");
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
double charge(const T &p)
ATLAS-specific HepMC functions.
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
DataModel_detail::const_iterator< DataVector > const_iterator
const T * back() const
Access the last element in the collection as an rvalue.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
ElementLink implementation for ROOT usage.
bool setElement(ElementType element)
Set to point to an element.
bool setStorableObject(BaseConstReference data, bool replace=false, IProxyDict *sg=0)
Set link to point to a new container (storable).
SG::ConstAccessor< T, ALLOC > ConstAccessor
Handle class for reading a decoration on an object.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
Handle class for adding a decoration to an object.
const Amg::Vector3D & momentum() const
Access method for the momentum.
Class describing the Line to which the Perigee refers to.
This class implements a vertex fitting algorithm optimised for V0 finding.
float z0() const
Returns the parameter.
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
float vz() const
The z origin for the parameters.
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
float charge() const
Returns the charge.
float z() const
Returns the z position.
const TrackParticleLinks_t & trackParticleLinks() const
Get all the particles associated with the vertex.
const Amg::Vector3D & position() const
Returns the 3-pos.
int count(std::string s, const std::string ®x)
count how many occurances of a regx are in a string
Eigen::Matrix< double, 3, 1 > Vector3D
static const int ELECTRON
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
ParametersBase< TrackParametersDim, Charged > TrackParameters
@ V0Vtx
Vertex from V0 decay.
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.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].