16 #include "HepPDT/ParticleDataTable.hh"
35 if(m_num>0 && m_vector.size()>=m_num) {
36 if(m_orderByPt && etac.
pt<=m_vector.back().pt)
return;
37 else if(!m_orderByPt && etac.
chi2NDF>=m_vector.back().chi2NDF)
return;
39 auto pos = m_vector.cend();
40 for(
auto iter=m_vector.cbegin(); iter!=m_vector.cend(); iter++) {
42 if(etac.
pt>iter->pt) {
pos = iter;
break; }
45 if(etac.
chi2NDF<iter->chi2NDF) {
pos = iter;
break; }
48 m_vector.insert(
pos, etac);
49 if(m_num>0 && m_vector.size()>m_num) m_vector.pop_back();
59 m_cascadeOutputKeys({
"JpsiXPlusDisplacedVtx1_sub",
"JpsiXPlusDisplacedVtx1",
"JpsiXPlusDisplacedVtx2",
"JpsiXPlusDisplacedVtx3"}),
61 m_TrkParticleCollection(
"InDetTrackParticles"),
62 m_VxPrimaryCandidateName(
"PrimaryVertices"),
63 m_refPVContainerName(
"RefittedPrimaryVertices"),
64 m_eventInfo_key(
"EventInfo"),
65 m_RelinkContainers({
"InDetTrackParticles",
"InDetLargeD0TrackParticles"}),
67 m_jxMassUpper(30000.0),
69 m_jpsiMassUpper(20000.0),
70 m_diTrackMassLower(-1.0),
71 m_diTrackMassUpper(-1.0),
72 m_V0Hypothesis(
"Lambda"),
74 m_V0MassUpper(20000.0),
76 m_minMass_gamma(-1.0),
77 m_chi2cut_gamma(-1.0),
78 m_DisplacedMassLower(0.0),
79 m_DisplacedMassUpper(30000.0),
80 m_lxyDisV_cut(-999.0),
86 m_jxDaug1MassHypo(-1),
87 m_jxDaug2MassHypo(-1),
88 m_jxDaug3MassHypo(-1),
89 m_jxDaug4MassHypo(-1),
90 m_jxPtOrdering(
false),
92 m_disVDaug3MassHypo(-1),
93 m_disVDaug3MinPt(480),
94 m_extraTrk1MassHypo(-1),
95 m_extraTrk1MinPt(480),
96 m_extraTrk2MassHypo(-1),
97 m_extraTrk2MinPt(480),
98 m_extraTrk3MassHypo(-1),
99 m_extraTrk3MinPt(480),
100 m_V0ExtraMassLower(0.0),
101 m_V0ExtraMassUpper(30000.0),
103 m_DpmMassUpper(30000.0),
105 m_D0MassUpper(30000.0),
106 m_DstpmMassLower(0.0),
107 m_DstpmMassUpper(30000.0),
108 m_maxMesonCandidates(400),
109 m_MesonPtOrdering(
true),
125 m_constrV0Extra(
false),
128 m_constrDstpm(
false),
129 m_constrMainV(
false),
133 m_chi2cut_DisV(-1.0),
134 m_chi2cut_V0Extra(-1.0),
135 m_chi2cut_JXDpm(-1.0),
136 m_chi2cut_JXDstpm(-1.0),
141 m_maxJXCandidates(0),
142 m_maxV0Candidates(0),
143 m_maxDisVCandidates(0),
144 m_maxMainVCandidates(0),
145 m_iVertexFitter(
"Trk::TrkVKalVrtFitter"),
146 m_iV0Fitter(
"Trk::V0VertexFitter"),
147 m_iGammaFitter(
"Trk::TrkVKalVrtFitter"),
148 m_pvRefitter(
"Analysis::PrimaryVertexRefitter",
this),
149 m_V0Tools(
"Trk::V0Tools"),
150 m_trackToVertexTool(
"Reco::TrackToVertex"),
151 m_trkSelector(
"InDet::TrackSelectorTool"),
152 m_v0TrkSelector(
"InDet::TrackSelectorTool"),
153 m_CascadeTools(
"DerivationFramework::CascadeTools"),
154 m_vertexEstimator(
"InDet::VertexPointEstimator"),
155 m_extrapolator(
"Trk::Extrapolator/AtlasExtrapolator")
157 declareProperty(
"JXVertices", m_vertexJXContainerKey);
158 declareProperty(
"V0Vertices", m_vertexV0ContainerKey);
159 declareProperty(
"JXVtxHypoNames", m_vertexJXHypoNames);
160 declareProperty(
"CascadeVertexCollections", m_cascadeOutputKeys);
161 declareProperty(
"OutoutV0VtxCollection", m_v0VtxOutputKey);
162 declareProperty(
"TrackParticleCollection", m_TrkParticleCollection);
163 declareProperty(
"VxPrimaryCandidateName", m_VxPrimaryCandidateName);
164 declareProperty(
"RefPVContainerName", m_refPVContainerName);
165 declareProperty(
"EventInfoKey", m_eventInfo_key);
166 declareProperty(
"RelinkTracks", m_RelinkContainers);
167 declareProperty(
"JXMassLowerCut", m_jxMassLower);
168 declareProperty(
"JXMassUpperCut", m_jxMassUpper);
169 declareProperty(
"JpsiMassLowerCut", m_jpsiMassLower);
170 declareProperty(
"JpsiMassUpperCut", m_jpsiMassUpper);
171 declareProperty(
"DiTrackMassLower", m_diTrackMassLower);
172 declareProperty(
"DiTrackMassUpper", m_diTrackMassUpper);
173 declareProperty(
"V0Hypothesis", m_V0Hypothesis);
174 declareProperty(
"V0MassLowerCut", m_V0MassLower);
175 declareProperty(
"V0MassUpperCut", m_V0MassUpper);
176 declareProperty(
"LxyV0Cut", m_lxyV0_cut);
177 declareProperty(
"MassCutGamma", m_minMass_gamma);
178 declareProperty(
"Chi2CutGamma", m_chi2cut_gamma);
179 declareProperty(
"DisplacedMassLowerCut", m_DisplacedMassLower);
180 declareProperty(
"DisplacedMassUpperCut", m_DisplacedMassUpper);
181 declareProperty(
"LxyDisVtxCut", m_lxyDisV_cut);
182 declareProperty(
"LxyDpmCut", m_lxyDpm_cut);
183 declareProperty(
"LxyD0Cut", m_lxyD0_cut);
184 declareProperty(
"MassLowerCut", m_MassLower);
185 declareProperty(
"MassUpperCut", m_MassUpper);
186 declareProperty(
"HypothesisName", m_hypoName =
"TQ");
187 declareProperty(
"NumberOfJXDaughters", m_jxDaug_num);
188 declareProperty(
"JXDaug1MassHypo", m_jxDaug1MassHypo);
189 declareProperty(
"JXDaug2MassHypo", m_jxDaug2MassHypo);
190 declareProperty(
"JXDaug3MassHypo", m_jxDaug3MassHypo);
191 declareProperty(
"JXDaug4MassHypo", m_jxDaug4MassHypo);
192 declareProperty(
"JXPtOrdering", m_jxPtOrdering);
193 declareProperty(
"NumberOfDisVDaughters", m_disVDaug_num);
194 declareProperty(
"DisVDaug3MassHypo", m_disVDaug3MassHypo);
195 declareProperty(
"DisVDaug3MinPt", m_disVDaug3MinPt);
196 declareProperty(
"ExtraTrack1MassHypo", m_extraTrk1MassHypo);
197 declareProperty(
"ExtraTrack1MinPt", m_extraTrk1MinPt);
198 declareProperty(
"ExtraTrack2MassHypo", m_extraTrk2MassHypo);
199 declareProperty(
"ExtraTrack2MinPt", m_extraTrk2MinPt);
200 declareProperty(
"ExtraTrack3MassHypo", m_extraTrk3MassHypo);
201 declareProperty(
"ExtraTrack3MinPt", m_extraTrk3MinPt);
202 declareProperty(
"V0ExtraMassLowerCut", m_V0ExtraMassLower);
203 declareProperty(
"V0ExtraMassUpperCut", m_V0ExtraMassUpper);
204 declareProperty(
"DpmMassLowerCut", m_DpmMassLower);
205 declareProperty(
"DpmMassUpperCut", m_DpmMassUpper);
206 declareProperty(
"D0MassLowerCut", m_D0MassLower);
207 declareProperty(
"D0MassUpperCut", m_D0MassUpper);
208 declareProperty(
"DstarpmMassLowerCut", m_DstpmMassLower);
209 declareProperty(
"DstarpmMassUpperCut", m_DstpmMassUpper);
210 declareProperty(
"MaxMesonCandidates", m_maxMesonCandidates);
211 declareProperty(
"MesonPtOrdering", m_MesonPtOrdering);
212 declareProperty(
"JXMass", m_massJX);
213 declareProperty(
"JpsiMass", m_massJpsi);
214 declareProperty(
"XMass", m_massX);
215 declareProperty(
"DisVtxMass", m_massDisV);
216 declareProperty(
"V0Mass", m_massV0);
217 declareProperty(
"V0ExtraMass", m_massV0Extra);
218 declareProperty(
"DpmMass", m_mass_Dpm);
219 declareProperty(
"D0Mass", m_mass_D0);
220 declareProperty(
"DstarpmMass", m_mass_Dstpm);
221 declareProperty(
"MainVtxMass", m_massMainV);
222 declareProperty(
"ApplyJXMassConstraint", m_constrJX);
223 declareProperty(
"ApplyJpsiMassConstraint", m_constrJpsi);
224 declareProperty(
"ApplyXMassConstraint", m_constrX);
225 declareProperty(
"ApplyDisVMassConstraint", m_constrDisV);
226 declareProperty(
"ApplyV0MassConstraint", m_constrV0);
227 declareProperty(
"ApplyV0ExtraMassConstraint", m_constrV0Extra);
228 declareProperty(
"ApplyDpmMassConstraint", m_constrDpm);
229 declareProperty(
"ApplyD0MassConstraint", m_constrD0);
230 declareProperty(
"ApplyDstarpmMassConstraint", m_constrDstpm);
231 declareProperty(
"ApplyMainVMassConstraint", m_constrMainV);
232 declareProperty(
"HasJXSubVertex", m_JXSubVtx);
233 declareProperty(
"Chi2CutJX", m_chi2cut_JX);
234 declareProperty(
"Chi2CutV0", m_chi2cut_V0);
235 declareProperty(
"Chi2CutDisV", m_chi2cut_DisV);
236 declareProperty(
"Chi2CutV0Extra", m_chi2cut_V0Extra);
237 declareProperty(
"Chi2CutJXDpm", m_chi2cut_JXDpm);
238 declareProperty(
"Chi2CutJXDstarpm", m_chi2cut_JXDstpm);
239 declareProperty(
"Chi2Cut", m_chi2cut);
240 declareProperty(
"UseTRT", m_useTRT);
241 declareProperty(
"PtTRT", m_ptTRT);
242 declareProperty(
"Trackd0Cut", m_d0_cut);
243 declareProperty(
"MaxJXCandidates", m_maxJXCandidates);
244 declareProperty(
"MaxV0Candidates", m_maxV0Candidates);
245 declareProperty(
"MaxDisVCandidates", m_maxDisVCandidates);
246 declareProperty(
"MaxMainVCandidates", m_maxMainVCandidates);
247 declareProperty(
"RefitPV", m_refitPV =
true);
248 declareProperty(
"MaxnPV", m_PV_max = 1000);
249 declareProperty(
"MinNTracksInPV", m_PV_minNTracks = 0);
250 declareProperty(
"DoVertexType", m_DoVertexType = 7);
251 declareProperty(
"TrkVertexFitterTool", m_iVertexFitter);
252 declareProperty(
"V0VertexFitterTool", m_iV0Fitter);
253 declareProperty(
"GammaFitterTool", m_iGammaFitter);
254 declareProperty(
"PVRefitter", m_pvRefitter);
255 declareProperty(
"V0Tools", m_V0Tools);
256 declareProperty(
"TrackToVertexTool", m_trackToVertexTool);
257 declareProperty(
"TrackSelectorTool", m_trkSelector);
258 declareProperty(
"V0TrackSelectorTool", m_v0TrkSelector);
259 declareProperty(
"CascadeTools", m_CascadeTools);
260 declareProperty(
"VertexPointEstimator", m_vertexEstimator);
261 declareProperty(
"Extrapolator", m_extrapolator);
266 ATH_MSG_FATAL(
"Incorrect V0 container hypothesis - not recognized");
267 return StatusCode::FAILURE;
270 if(m_jxDaug_num<2 || m_jxDaug_num>4 || m_disVDaug_num<2 || m_disVDaug_num>3) {
272 return StatusCode::FAILURE;
276 ATH_MSG_FATAL(
"Input and output V0 container names can not be both empty");
277 return StatusCode::FAILURE;
356 return StatusCode::SUCCESS;
359 StatusCode JpsiXPlusDisplaced::performSearch(std::vector<Trk::VxCascadeInfo*>& cascadeinfoContainer,
const std::vector<std::pair<const xAOD::Vertex*,V0Enum> >& selectedV0Candidates,
const std::vector<const xAOD::TrackParticle*>& tracksDisplaced)
const {
361 if(selectedV0Candidates.size()==0)
return StatusCode::SUCCESS;
368 std::vector<const xAOD::TrackParticleContainer*> trackCols;
372 trackCols.push_back(handle.
cptr());
384 std::vector<XiCandidate> disVtxContainer;
386 for(
size_t it=0;
it<selectedV0Candidates.size(); ++
it) {
387 std::pair<const xAOD::Vertex*,V0Enum> elem = selectedV0Candidates[
it];
391 if(disVtx.V0vtx && disVtx.track) disVtxContainer.push_back(disVtx);
395 std::sort( disVtxContainer.begin(), disVtxContainer.end(), [](
const XiCandidate&
a,
const XiCandidate&
b) { return a.chi2NDF < b.chi2NDF; } );
399 if(disVtxContainer.size()==0)
return StatusCode::SUCCESS;
403 std::vector<const xAOD::Vertex*> selectedJXCandidates;
416 TLorentzVector p4_mu1, p4_mu2;
417 p4_mu1.SetPtEtaPhiM(vtx->trackParticle(0)->pt(),vtx->trackParticle(0)->eta(),vtx->trackParticle(0)->phi(),
m_jxDaug1MassHypo);
418 p4_mu2.SetPtEtaPhiM(vtx->trackParticle(1)->pt(),vtx->trackParticle(1)->eta(),vtx->trackParticle(1)->phi(),
m_jxDaug2MassHypo);
419 double mass_jpsi = (p4_mu1 + p4_mu2).M();
420 if (mass_jpsi < m_jpsiMassLower || mass_jpsi >
m_jpsiMassUpper)
continue;
422 TLorentzVector p4_trk1, p4_trk2;
423 if(
m_jxDaug_num>=3) p4_trk1.SetPtEtaPhiM(vtx->trackParticle(2)->pt(),vtx->trackParticle(2)->eta(),vtx->trackParticle(2)->phi(),
m_jxDaug3MassHypo);
424 if(
m_jxDaug_num==4) p4_trk2.SetPtEtaPhiM(vtx->trackParticle(3)->pt(),vtx->trackParticle(3)->eta(),vtx->trackParticle(3)->phi(),
m_jxDaug4MassHypo);
427 double mass_jx = (p4_mu1 + p4_mu2 + p4_trk1).M();
428 if(mass_jx < m_jxMassLower || mass_jx >
m_jxMassUpper)
continue;
431 double mass_jx = (p4_mu1 + p4_mu2 + p4_trk1 + p4_trk2).M();
432 if(mass_jx < m_jxMassLower || mass_jx >
m_jxMassUpper)
continue;
435 double mass_diTrk = (p4_trk1 + p4_trk2).M();
440 double chi2DOF = vtx->chiSquared()/vtx->numberDoF();
443 selectedJXCandidates.push_back(vtx);
445 if(selectedJXCandidates.size()==0)
return StatusCode::SUCCESS;
448 std::sort( selectedJXCandidates.begin(), selectedJXCandidates.end(), [massesJX](
const xAOD::Vertex*
a,
const xAOD::Vertex*
b) {
449 TLorentzVector p4_a, p4_b, tmp;
450 for(size_t it=0; it<a->nTrackParticles(); it++) {
451 tmp.SetPtEtaPhiM(a->trackParticle(it)->pt(), a->trackParticle(it)->eta(), a->trackParticle(it)->phi(), massesJX[it]);
454 for(
size_t it=0; it<b->nTrackParticles();
it++) {
455 tmp.SetPtEtaPhiM(
b->trackParticle(
it)->pt(),
b->trackParticle(
it)->eta(),
b->trackParticle(
it)->phi(), massesJX[
it]);
458 return p4_a.Pt() > p4_b.Pt();
462 std::sort( selectedJXCandidates.begin(), selectedJXCandidates.end(), [](
const xAOD::Vertex*
a,
const xAOD::Vertex*
b) { return a->chiSquared()/a->numberDoF() < b->chiSquared()/b->numberDoF(); } );
464 if(m_maxJXCandidates>0 && selectedJXCandidates.size()>m_maxJXCandidates) {
465 selectedJXCandidates.erase(selectedJXCandidates.begin()+m_maxJXCandidates, selectedJXCandidates.end());
472 if(m_disVDaug_num==2) {
473 for(
auto&& V0Candidate : selectedV0Candidates) {
474 std::vector<Trk::VxCascadeInfo*>
result = fitMainVtx(jxVtx, massesJX, V0Candidate.first, V0Candidate.second, trackContainer.cptr(), trackCols);
475 for(
auto cascade_info :
result) {
476 if(cascade_info) cascadeinfoContainer.push_back(cascade_info);
480 else if(m_disVDaug_num==3) {
481 for(
auto&& disVtx : disVtxContainer) {
482 std::vector<Trk::VxCascadeInfo*>
result = fitMainVtx(jxVtx, massesJX, disVtx, trackContainer.cptr(), trackCols);
483 for(
auto cascade_info :
result) {
484 if(cascade_info) cascadeinfoContainer.push_back(cascade_info);
490 return StatusCode::SUCCESS;
494 size_t topoN = (m_disVDaug_num==2 ? 3 : 4);
495 if(!m_JXSubVtx) topoN--;
496 if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo>0) topoN = 3;
498 if(m_cascadeOutputKeys.size() != topoN) {
499 ATH_MSG_FATAL(
"Incorrect number of output cascade vertices");
500 return StatusCode::FAILURE;
503 std::array<SG::WriteHandle<xAOD::VertexContainer>, 4> VtxWriteHandles;
int ikey(0);
506 ATH_CHECK( VtxWriteHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
516 if (pvContainer.
cptr()->
size()==0) {
518 return StatusCode::RECOVERABLE;
520 else primaryVertex = (*pvContainer.
cptr())[0];
528 ATH_CHECK( refPvContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
536 std::vector<const xAOD::TrackParticleContainer*> trackCols;
540 trackCols.push_back(handle.
cptr());
545 if(m_vertexV0ContainerKey.key()==
"" && m_v0VtxOutputKey.key()!=
"") {
547 ATH_CHECK( V0OutputContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
551 std::vector<const xAOD::TrackParticle*> tracksDisplaced;
554 if(m_v0TrkSelector->decision(*TP, primaryVertex)) {
559 if(!m_useTRT && nclus == 0)
continue;
561 bool trk_cut =
false;
562 if(nclus != 0) trk_cut =
true;
563 if(nclus == 0 && TP->pt()>=m_ptTRT) trk_cut =
true;
564 if(!trk_cut)
continue;
567 if(!d0Pass(TP,primaryVertex))
continue;
569 tracksDisplaced.push_back(TP);
579 std::vector<std::pair<const xAOD::Vertex*,V0Enum> > selectedV0Candidates;
582 if(m_vertexV0ContainerKey.key() !=
"") {
587 std::string type_V0Vtx;
588 if(mAcc_type.
isAvailable(*vtx)) type_V0Vtx = mAcc_type(*vtx);
591 if(type_V0Vtx ==
"Lambda") {
593 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_ppi);
595 else if(type_V0Vtx ==
"Lambdabar") {
597 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pip);
599 else if(type_V0Vtx ==
"Ks") {
601 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pipi);
603 if(massV0<m_V0MassLower || massV0>m_V0MassUpper)
continue;
606 if((
opt==LAMBDA ||
opt==LAMBDABAR) && m_V0Hypothesis !=
"Lambda")
continue;
607 if(
opt==KS && m_V0Hypothesis !=
"Ks")
continue;
609 int gamma_fit = mAcc_gfit.
isAvailable(*vtx) ? mAcc_gfit(*vtx) : 0;
610 double gamma_mass = mAcc_gmass.
isAvailable(*vtx) ? mAcc_gmass(*vtx) : -1;
611 double gamma_chisq = mAcc_gchisq.
isAvailable(*vtx) ? mAcc_gchisq(*vtx) : 999999;
612 double gamma_ndof = mAcc_gndof.
isAvailable(*vtx) ? mAcc_gndof(*vtx) : 0;
613 if(gamma_fit==1 && gamma_mass<m_minMass_gamma && gamma_chisq/gamma_ndof<m_chi2cut_gamma)
continue;
615 selectedV0Candidates.push_back(std::pair<const xAOD::Vertex*,V0Enum>{vtx,
opt});
620 fitV0Container(V0OutputContainer.
ptr(), tracksDisplaced, trackCols);
623 std::string type_V0Vtx;
624 if(mAcc_type.
isAvailable(*vtx)) type_V0Vtx = mAcc_type(*vtx);
627 if(type_V0Vtx ==
"Lambda") {
629 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_ppi);
631 else if(type_V0Vtx ==
"Lambdabar") {
633 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pip);
635 else if(type_V0Vtx ==
"Ks") {
637 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pipi);
639 if(massV0<m_V0MassLower || massV0>m_V0MassUpper)
continue;
642 if((
opt==LAMBDA ||
opt==LAMBDABAR) && m_V0Hypothesis !=
"Lambda")
continue;
643 if(
opt==KS && m_V0Hypothesis !=
"Ks")
continue;
645 int gamma_fit = mAcc_gfit.
isAvailable(*vtx) ? mAcc_gfit(*vtx) : 0;
646 double gamma_mass = mAcc_gmass.
isAvailable(*vtx) ? mAcc_gmass(*vtx) : -1;
647 double gamma_chisq = mAcc_gchisq.
isAvailable(*vtx) ? mAcc_gchisq(*vtx) : 999999;
648 double gamma_ndof = mAcc_gndof.
isAvailable(*vtx) ? mAcc_gndof(*vtx) : 0;
649 if(gamma_fit==1 && gamma_mass<m_minMass_gamma && gamma_chisq/gamma_ndof<m_chi2cut_gamma)
continue;
651 selectedV0Candidates.push_back(std::pair<const xAOD::Vertex*,V0Enum>{vtx,
opt});
656 std::sort( selectedV0Candidates.begin(), selectedV0Candidates.end(), [](std::pair<const xAOD::Vertex*,V0Enum>&
a, std::pair<const xAOD::Vertex*,V0Enum>&
b) { return a.first->chiSquared()/a.first->numberDoF() < b.first->chiSquared()/b.first->numberDoF(); } );
657 if(m_maxV0Candidates>0 && selectedV0Candidates.size()>m_maxV0Candidates) {
658 selectedV0Candidates.erase(selectedV0Candidates.begin()+m_maxV0Candidates, selectedV0Candidates.end());
661 std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer;
662 ATH_CHECK( performSearch(cascadeinfoContainer, selectedV0Candidates, tracksDisplaced) );
666 if(m_maxMainVCandidates>0 && cascadeinfoContainer.size()>m_maxMainVCandidates) {
667 for(
auto it=cascadeinfoContainer.begin()+m_maxMainVCandidates;
it!=cascadeinfoContainer.end();
it++)
delete *
it;
668 cascadeinfoContainer.erase(cascadeinfoContainer.begin()+m_maxMainVCandidates, cascadeinfoContainer.end());
674 helper.SetMinNTracksInPV(m_PV_minNTracks);
711 for(
auto cascade_info : cascadeinfoContainer) {
712 if(cascade_info==
nullptr) {
717 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->vertices();
718 if(cascadeVertices.size() != topoN)
ATH_MSG_ERROR(
"Incorrect number of vertices");
719 for(
size_t i=0;
i<topoN;
i++) {
720 if(cascadeVertices[
i]==
nullptr)
ATH_MSG_ERROR(
"Error null vertex");
723 cascade_info->setSVOwnership(
false);
724 const auto mainVertex = cascadeVertices[topoN-1];
725 const std::vector< std::vector<TLorentzVector> > &moms = cascade_info->getParticleMoms();
728 int ijx = m_JXSubVtx ? topoN-2 : topoN-1;
729 if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo>0) ijx = topoN-1;
731 if(m_jxDaug_num==4) jxVtx = FindVertex<4>(jxContainer.
ptr(), cascadeVertices[ijx]);
732 else if(m_jxDaug_num==3) jxVtx = FindVertex<3>(jxContainer.
ptr(), cascadeVertices[ijx]);
733 else jxVtx = FindVertex<2>(jxContainer.
ptr(), cascadeVertices[ijx]);
738 BPhysPVCascadeTools::SetVectorInfo(vtx, cascade_info);
747 BPHYS_CHECK( vtx.
setMassErr(m_CascadeTools->invariantMassError(moms[topoN-1],cascade_info->getCovariance()[topoN-1])) );
749 Pt_decor(*mainVertex) = m_CascadeTools->pT(moms[topoN-1]);
750 PtErr_decor(*mainVertex) = m_CascadeTools->pTError(moms[topoN-1],cascade_info->getCovariance()[topoN-1]);
752 chi2_decor(*mainVertex) = cascade_info->fitChi2();
753 ndof_decor(*mainVertex) = cascade_info->nDoF();
755 if(m_disVDaug_num==2) {
757 lxy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
758 lxyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
759 a0z_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
760 a0zErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
761 a0xy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
762 a0xyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
766 lxy_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
767 lxyErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
768 a0z_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],cascadeVertices[1]);
769 a0zErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
770 a0xy_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],cascadeVertices[1]);
771 a0xyErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
774 lxy_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
775 lxyErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
776 a0xy_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
777 a0xyErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
778 a0z_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
779 a0zErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
782 if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo>0) {
783 lxy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
784 lxyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
785 a0z_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
786 a0zErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
787 a0xy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
788 a0xyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
791 else if(m_JXSubVtx) {
792 lxy_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->lxy(moms[ijx],cascadeVertices[ijx],mainVertex);
793 lxyErr_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->lxyError(moms[ijx],cascade_info->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
794 a0z_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0z(moms[ijx],cascadeVertices[ijx],mainVertex);
795 a0zErr_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0zError(moms[ijx],cascade_info->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
796 a0xy_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0xy(moms[ijx],cascadeVertices[ijx],mainVertex);
797 a0xyErr_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0xyError(moms[ijx],cascade_info->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
800 chi2_V2_decor(*cascadeVertices[ijx]) = m_V0Tools->chisq(jxVtx);
801 ndof_V2_decor(*cascadeVertices[ijx]) = m_V0Tools->ndof(jxVtx);
803 double Mass_Moth = m_CascadeTools->invariantMass(moms[topoN-1]);
804 ATH_CHECK(
helper.FillCandwithRefittedVertices(m_refitPV, pvContainer.
cptr(), m_refitPV ? refPvContainer.
ptr() : 0, &(*m_pvRefitter), m_PV_max, m_DoVertexType, cascade_info, topoN-1, Mass_Moth, vtx));
806 for(
size_t i=0;
i<topoN;
i++) {
807 VtxWriteHandles[
i].ptr()->push_back(cascadeVertices[
i]);
815 if( vertexLink1.
isValid() ) precedingVertexLinks.push_back( vertexLink1 );
820 if( vertexLink2.
isValid() ) precedingVertexLinks.push_back( vertexLink2 );
826 if( vertexLink3.
isValid() ) precedingVertexLinks.push_back( vertexLink3 );
828 CascadeLinksDecor(*mainVertex) = precedingVertexLinks;
832 for (
auto cascade_info : cascadeinfoContainer)
delete cascade_info;
834 return StatusCode::SUCCESS;
839 const EventContext& ctx = Gaudi::Hive::currentContext();
840 std::unique_ptr<Trk::Perigee> per = m_trackToVertexTool->perigeeAtVertex(ctx, *
track, PV->
position());
841 if(!per)
return pass;
843 double sig_d0 = sqrt((*per->covariance())(0,0));
844 if(std::abs(
d0/sig_d0) > m_d0_cut) pass =
true;
851 std::vector<const xAOD::TrackParticle*> tracksV0;
854 if(
std::find(tracksV0.cbegin(), tracksV0.cend(), track3) != tracksV0.cend())
return disVtx;
856 std::vector<double> massesV0;
858 massesV0 = m_massesV0_ppi;
860 else if(V0==LAMBDABAR) {
861 massesV0 = m_massesV0_pip;
864 massesV0 = m_massesV0_pipi;
867 TLorentzVector p4_v0,
tmp;
869 tmp.SetPtEtaPhiM(track3->
pt(),track3->
eta(),track3->
phi(),m_disVDaug3MassHypo);
871 if((p4_v0+
tmp).M() < m_DisplacedMassLower-120. || (p4_v0+
tmp).M() > m_DisplacedMassUpper+120.)
return disVtx;
873 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
875 m_iVertexFitter->setRobustness(robustness, *state);
876 std::vector<Trk::VertexID> vrtList;
878 Trk::VertexID vID = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
879 vrtList.push_back(vID);
881 std::vector<const xAOD::TrackParticle*> tracksDis3{track3};
882 std::vector<double> massesDis3{m_disVDaug3MassHypo};
883 m_iVertexFitter->nextVertex(tracksDis3,massesDis3,vrtList,*state);
885 std::unique_ptr<Trk::VxCascadeInfo> cascade_info = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
888 double chi2NDF = cascade_info->
fitChi2()/cascade_info->
nDoF();
889 if(m_chi2cut_DisV<=0 || chi2NDF < m_chi2cut_DisV) {
890 const std::vector<std::vector<TLorentzVector> > &moms = cascade_info->
getParticleMoms();
891 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->
vertices();
892 double lxy_SV1_sub = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
893 if(lxy_SV1_sub > m_lxyV0_cut) {
894 TLorentzVector totalMom;
895 for(
size_t it=0;
it<moms[1].size();
it++) totalMom += moms[1][
it];
896 if(totalMom.M()>m_DisplacedMassLower && totalMom.M()<m_DisplacedMassUpper) {
910 std::vector<const xAOD::TrackParticle*> tracksV0;
913 if(
std::find(tracksV0.cbegin(), tracksV0.cend(), extraTrk1) != tracksV0.cend())
return etac;
914 if(
std::find(tracksV0.cbegin(), tracksV0.cend(), extraTrk2) != tracksV0.cend())
return etac;
916 std::vector<double> massesV0;
918 massesV0 = m_massesV0_ppi;
920 else if(V0==LAMBDABAR) {
921 massesV0 = m_massesV0_pip;
924 massesV0 = m_massesV0_pipi;
927 TLorentzVector p4_v0, tmp1,
tmp2;
929 tmp1.SetPtEtaPhiM(extraTrk1->
pt(),extraTrk1->
eta(),extraTrk1->
phi(),m_extraTrk1MassHypo);
930 tmp2.SetPtEtaPhiM(extraTrk2->
pt(),extraTrk2->
eta(),extraTrk2->
phi(),m_extraTrk2MassHypo);
931 if((p4_v0+tmp1+
tmp2).M() < m_V0ExtraMassLower || (p4_v0+tmp1+
tmp2).M() > m_V0ExtraMassUpper)
return etac;
933 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
935 m_iVertexFitter->setRobustness(robustness, *state);
936 std::vector<Trk::VertexID> vrtList;
938 Trk::VertexID vID = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
939 vrtList.push_back(vID);
941 std::vector<const xAOD::TrackParticle*> extraTracks{extraTrk1, extraTrk2};
942 std::vector<double> extraMasses{m_extraTrk1MassHypo, m_extraTrk2MassHypo};
943 m_iVertexFitter->nextVertex(extraTracks,extraMasses,vrtList,*state);
945 std::unique_ptr<Trk::VxCascadeInfo> cascade_info = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
948 double chi2NDF = cascade_info->
fitChi2()/cascade_info->
nDoF();
949 if(m_chi2cut_V0Extra<=0 || chi2NDF < m_chi2cut_V0Extra) {
950 const std::vector<std::vector<TLorentzVector> > &moms = cascade_info->
getParticleMoms();
951 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->
vertices();
952 double lxy = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
953 if(lxy > m_lxyV0_cut) {
954 TLorentzVector totalMom;
955 for(
size_t it=0;
it<moms[1].size();
it++) totalMom += moms[1][
it];
958 etac.
chi2NDF = chi2NDF; etac.
pt = totalMom.Pt();
968 std::vector<const xAOD::TrackParticle*> tracksJX;
971 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk1) != tracksJX.cend())
return Dpm;
972 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk2) != tracksJX.cend())
return Dpm;
973 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk3) != tracksJX.cend())
return Dpm;
975 TLorentzVector tmp1,
tmp2, tmp3;
976 tmp1.SetPtEtaPhiM(extraTrk1->
pt(),extraTrk1->
eta(),extraTrk1->
phi(),m_extraTrk1MassHypo);
977 tmp2.SetPtEtaPhiM(extraTrk2->
pt(),extraTrk2->
eta(),extraTrk2->
phi(),m_extraTrk2MassHypo);
978 tmp3.SetPtEtaPhiM(extraTrk3->
pt(),extraTrk3->
eta(),extraTrk3->
phi(),m_extraTrk3MassHypo);
979 if((tmp1+
tmp2+tmp3).M() < m_DpmMassLower || (tmp1+
tmp2+tmp3).M() > m_DpmMassUpper)
return Dpm;
981 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
983 m_iVertexFitter->setRobustness(robustness, *state);
984 std::vector<Trk::VertexID> vrtList;
986 std::vector<const xAOD::TrackParticle*> extraTracks{extraTrk1, extraTrk2, extraTrk3};
987 std::vector<double> extraMasses{m_extraTrk1MassHypo, m_extraTrk2MassHypo, m_extraTrk3MassHypo};
988 Trk::VertexID vID = m_iVertexFitter->startVertex(extraTracks,extraMasses,*state);
989 vrtList.push_back(vID);
991 m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
993 std::unique_ptr<Trk::VxCascadeInfo> cascade_info = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
996 double chi2NDF = cascade_info->
fitChi2()/cascade_info->
nDoF();
997 if(m_chi2cut_JXDpm<=0 || chi2NDF < m_chi2cut_JXDpm) {
998 const std::vector<std::vector<TLorentzVector> > &moms = cascade_info->
getParticleMoms();
999 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->
vertices();
1000 double lxy = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
1001 if(lxy > m_lxyDpm_cut) {
1003 Dpm.
chi2NDF = chi2NDF; Dpm.
pt = moms[1][tracksJX.size()].Pt();
1013 std::vector<const xAOD::TrackParticle*> tracksJX;
1016 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk1) != tracksJX.cend())
return Dstpm;
1017 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk2) != tracksJX.cend())
return Dstpm;
1018 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk3) != tracksJX.cend())
return Dstpm;
1020 TLorentzVector tmp1,
tmp2, tmp3;
1021 tmp1.SetPtEtaPhiM(extraTrk1->
pt(),extraTrk1->
eta(),extraTrk1->
phi(),m_extraTrk1MassHypo);
1022 tmp2.SetPtEtaPhiM(extraTrk2->
pt(),extraTrk2->
eta(),extraTrk2->
phi(),m_extraTrk2MassHypo);
1023 tmp3.SetPtEtaPhiM(extraTrk3->
pt(),extraTrk3->
eta(),extraTrk3->
phi(),m_extraTrk3MassHypo);
1024 if((tmp1+
tmp2).M() < m_D0MassLower || (tmp1+
tmp2).M() > m_D0MassUpper)
return Dstpm;
1025 if((tmp1+
tmp2+tmp3).M()-(tmp1+
tmp2).M()+m_mass_D0 < m_DstpmMassLower || (tmp1+
tmp2+tmp3).M()-(tmp1+
tmp2).M()+m_mass_D0 > m_DstpmMassUpper)
return Dstpm;
1027 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1029 m_iVertexFitter->setRobustness(robustness, *state);
1030 std::vector<Trk::VertexID> vrtList;
1032 std::vector<const xAOD::TrackParticle*> extraTracks{extraTrk1, extraTrk2};
1033 std::vector<double> extraMasses{m_extraTrk1MassHypo, m_extraTrk2MassHypo};
1034 Trk::VertexID vID = m_iVertexFitter->startVertex(extraTracks,extraMasses,*state);
1035 vrtList.push_back(vID);
1037 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX;
1038 tracksJXExtra.push_back(extraTrk3);
1039 std::vector<double> massesJXExtra = massesJX;
1040 massesJXExtra.push_back(m_extraTrk3MassHypo);
1041 m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state);
1043 std::unique_ptr<Trk::VxCascadeInfo> cascade_info = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1046 double chi2NDF = cascade_info->
fitChi2()/cascade_info->
nDoF();
1047 if(m_chi2cut_JXDstpm<=0 || chi2NDF < m_chi2cut_JXDstpm) {
1048 const std::vector<std::vector<TLorentzVector> > &moms = cascade_info->
getParticleMoms();
1049 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->
vertices();
1050 double lxy = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
1051 if(lxy > m_lxyD0_cut) {
1052 TLorentzVector totalMom;
1053 for(
size_t it=tracksJX.size();
it<moms[1].size();
it++) totalMom += moms[1][
it];
1055 Dstpm.
chi2NDF = chi2NDF; Dstpm.
pt = totalMom.Pt();
1063 std::vector<Trk::VxCascadeInfo*>
result;
1065 std::vector<const xAOD::TrackParticle*> tracksJX;
1068 if (tracksJX.size() != massesJX.size()) {
1069 ATH_MSG_ERROR(
"Problems with JX input: number of tracks or track mass inputs is not correct!");
1075 std::vector<const xAOD::TrackParticle*> tracksV0;
1079 std::vector<const xAOD::TrackParticle*> tracksJpsi{tracksJX[0], tracksJX[1]};
1080 std::vector<const xAOD::TrackParticle*> tracksX;
1081 if(m_jxDaug_num>=3) tracksX.push_back(tracksJX[2]);
1082 if(m_jxDaug_num==4) tracksX.push_back(tracksJX[3]);
1084 std::vector<double> massesV0;
1086 massesV0 = m_massesV0_ppi;
1088 else if(V0==LAMBDABAR) {
1089 massesV0 = m_massesV0_pip;
1092 massesV0 = m_massesV0_pipi;
1095 TLorentzVector p4_moth, p4_v0,
tmp;
1102 p4_moth += V0_helper.
refTrk(
it,massesV0[
it]);
1127 std::vector<float> trk_px;
1128 std::vector<float> trk_py;
1129 std::vector<float> trk_pz;
1131 if(m_extraTrk1MassHypo<=0) {
1132 if (p4_moth.M() < m_MassLower || p4_moth.M() > m_MassUpper)
return result;
1135 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1138 m_iVertexFitter->setRobustness(robustness, *state);
1141 std::vector<Trk::VertexID> vrtList;
1146 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1148 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1150 vrtList.push_back(vID1);
1154 if (m_constrJX && m_jxDaug_num>2) {
1155 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state,m_massJX);
1157 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state);
1159 vrtList.push_back(vID2);
1161 std::vector<const xAOD::TrackParticle*>
tp;
1162 std::vector<double> tp_masses;
1164 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state,m_massMainV);
1166 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state);
1172 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massMainV);
1174 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
1176 if (m_constrJX && m_jxDaug_num>2) {
1177 std::vector<Trk::VertexID> cnstV;
1178 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1184 std::vector<Trk::VertexID> cnstV;
1185 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1189 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1190 std::vector<Trk::VertexID> cnstV;
1191 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1196 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1200 if(
v->nTrackParticles()==0) {
1201 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1202 v->setTrackParticleLinks(nullLinkVector);
1206 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1212 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1213 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1215 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1216 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1217 size_t iMoth = cascadeVertices.size()-1;
1218 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1219 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut) {
1220 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1221 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1223 type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1225 else if(V0==LAMBDABAR) {
1226 type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1229 type_V1_decor(*cascadeVertices[0]) =
"Ks";
1231 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1232 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1233 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1234 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1235 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1236 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1237 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1238 trk_px.reserve(V0_helper.
nRefTrks());
1239 trk_py.reserve(V0_helper.
nRefTrks());
1240 trk_pz.reserve(V0_helper.
nRefTrks());
1241 for(
auto&& vec3 : V0_helper.
refTrks()) {
1242 trk_px.push_back( vec3.Px() );
1243 trk_py.push_back( vec3.Py() );
1244 trk_pz.push_back( vec3.Pz() );
1246 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1247 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1248 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1250 result.push_back( fit_result.release() );
1254 else if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo<=0) {
1255 std::vector<double> massesJXExtra = massesJX;
1256 massesJXExtra.push_back(m_extraTrk1MassHypo);
1259 if( tpExtra->pt()<m_extraTrk1MinPt )
continue;
1260 if( !m_trkSelector->decision(*tpExtra,
nullptr) )
continue;
1262 if(
std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend())
continue;
1263 if(
std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend())
continue;
1266 tmp.SetPtEtaPhiM(tpExtra->pt(),tpExtra->eta(),tpExtra->phi(),m_extraTrk1MassHypo);
1267 if((p4_moth+
tmp).M() < m_MassLower || (p4_moth+
tmp).M() > m_MassUpper)
continue;
1269 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX;
1270 tracksJXExtra.push_back(tpExtra);
1273 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1276 m_iVertexFitter->setRobustness(robustness, *state);
1279 std::vector<Trk::VertexID> vrtList;
1284 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1286 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1288 vrtList.push_back(vID1);
1292 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,*state);
1293 vrtList.push_back(vID2);
1295 std::vector<const xAOD::TrackParticle*>
tp;
1296 std::vector<double> tp_masses;
1298 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state,m_massMainV);
1300 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state);
1306 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state,m_massMainV);
1308 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state);
1311 if (m_constrJX && m_jxDaug_num>2) {
1312 std::vector<Trk::VertexID> cnstV;
1313 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1318 std::vector<Trk::VertexID> cnstV;
1319 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1323 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1324 std::vector<Trk::VertexID> cnstV;
1325 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1330 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1334 if(
v->nTrackParticles()==0) {
1335 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1336 v->setTrackParticleLinks(nullLinkVector);
1340 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1346 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1347 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1348 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1349 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1350 size_t iMoth = cascadeVertices.size()-1;
1351 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1352 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut) {
1353 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1354 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1356 type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1358 else if(V0==LAMBDABAR) {
1359 type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1362 type_V1_decor(*cascadeVertices[0]) =
"Ks";
1364 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1365 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1366 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1367 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1368 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1369 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1370 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1371 trk_px.reserve(V0_helper.
nRefTrks());
1372 trk_py.reserve(V0_helper.
nRefTrks());
1373 trk_pz.reserve(V0_helper.
nRefTrks());
1374 for(
auto&& vec3 : V0_helper.
refTrks()) {
1375 trk_px.push_back( vec3.Px() );
1376 trk_py.push_back( vec3.Py() );
1377 trk_pz.push_back( vec3.Pz() );
1379 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1380 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1381 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1383 result.push_back( fit_result.release() );
1388 else if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo<=0) {
1389 std::vector<const xAOD::TrackParticle*> tracksPlus;
1390 std::vector<const xAOD::TrackParticle*> tracksMinus;
1392 if( tpExtra->pt() < std::fmin(m_extraTrk1MinPt,m_extraTrk2MinPt) )
continue;
1393 if( !m_trkSelector->decision(*tpExtra,
nullptr) )
continue;
1395 if(
std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend())
continue;
1396 if(
std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend())
continue;
1397 if(tpExtra->charge()>0) {
1398 tracksPlus.push_back(tpExtra);
1401 tracksMinus.push_back(tpExtra);
1406 TLorentzVector p4_ExtraTrk1, p4_ExtraTrk2;
1409 if((tp1->pt()>m_extraTrk1MinPt && tp2->pt()>m_extraTrk2MinPt) ||
1410 (tp1->pt()>m_extraTrk2MinPt && tp2->pt()>m_extraTrk1MinPt)) {
1411 p4_ExtraTrk1.SetPtEtaPhiM(tp1->pt(), tp1->eta(), tp1->phi(), m_extraTrk1MassHypo);
1412 p4_ExtraTrk2.SetPtEtaPhiM(tp2->pt(), tp2->eta(), tp2->phi(), m_extraTrk2MassHypo);
1413 if((p4_moth+p4_ExtraTrk1+p4_ExtraTrk2).M() < m_MassLower || (p4_moth+p4_ExtraTrk1+p4_ExtraTrk2).M() > m_MassUpper)
continue;
1414 auto etac = getEtacCandidate(V0vtx,V0,tp1,tp2);
1415 if(etac.V0vtx) etacCandidates.
push_back(etac);
1420 std::vector<double> massesJXExtra = massesJX;
1421 massesJXExtra.push_back(m_extraTrk1MassHypo);
1422 massesJXExtra.push_back(m_extraTrk2MassHypo);
1424 for(
auto&& etac : etacCandidates.
vector()) {
1425 std::vector<const xAOD::TrackParticle*> tracksExtra{etac.extraTrack1, etac.extraTrack2};
1426 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX;
1427 tracksJXExtra.push_back(etac.extraTrack1);
1428 tracksJXExtra.push_back(etac.extraTrack2);
1431 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1434 m_iVertexFitter->setRobustness(robustness, *state);
1437 std::vector<Trk::VertexID> vrtList;
1442 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1444 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1446 vrtList.push_back(vID1);
1450 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,*state);
1451 vrtList.push_back(vID2);
1453 std::vector<const xAOD::TrackParticle*>
tp;
1454 std::vector<double> tp_masses;
1456 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state,m_massMainV);
1458 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state);
1464 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state,m_massMainV);
1466 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state);
1469 if (m_constrJX && m_jxDaug_num>2) {
1470 std::vector<Trk::VertexID> cnstV;
1471 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1476 std::vector<Trk::VertexID> cnstV;
1477 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1481 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1482 std::vector<Trk::VertexID> cnstV;
1483 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1487 if (m_constrV0Extra && m_massV0Extra>0) {
1488 std::vector<Trk::VertexID> cnstV{vID1};
1489 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksExtra,cnstV,*state,m_massV0Extra).isSuccess() ) {
1494 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1498 if(
v->nTrackParticles()==0) {
1499 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1500 v->setTrackParticleLinks(nullLinkVector);
1504 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1510 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1511 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1512 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1513 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1514 size_t iMoth = cascadeVertices.size()-1;
1515 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1516 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut) {
1517 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1518 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1520 type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1522 else if(V0==LAMBDABAR) {
1523 type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1526 type_V1_decor(*cascadeVertices[0]) =
"Ks";
1528 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1529 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1530 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1531 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1532 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1533 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1534 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1535 trk_px.reserve(V0_helper.
nRefTrks());
1536 trk_py.reserve(V0_helper.
nRefTrks());
1537 trk_pz.reserve(V0_helper.
nRefTrks());
1538 for(
auto&& vec3 : V0_helper.
refTrks()) {
1539 trk_px.push_back( vec3.Px() );
1540 trk_py.push_back( vec3.Py() );
1541 trk_pz.push_back( vec3.Pz() );
1543 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1544 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1545 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1547 result.push_back( fit_result.release() );
1552 else if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo>0) {
1553 std::vector<const xAOD::TrackParticle*> tracksPlus;
1554 std::vector<const xAOD::TrackParticle*> tracksMinus;
1555 double minTrkPt = std::fmin(std::fmin(m_extraTrk1MinPt,m_extraTrk2MinPt),m_extraTrk3MinPt);
1557 if( tpExtra->pt() < minTrkPt )
continue;
1558 if( !m_trkSelector->decision(*tpExtra,
nullptr) )
continue;
1560 if(
std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend())
continue;
1561 if(
std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend())
continue;
1562 if(tpExtra->charge()>0) {
1563 tracksPlus.push_back(tpExtra);
1566 tracksMinus.push_back(tpExtra);
1572 TLorentzVector p4_ExtraTrk1, p4_ExtraTrk2, p4_ExtraTrk3;
1575 if( tp1->pt() < m_extraTrk1MinPt )
continue;
1576 for(
auto tp2Itr=tracksMinus.cbegin(); tp2Itr!=tracksMinus.cend(); ++tp2Itr) {
1578 for(
auto tp3Itr=tp2Itr+1; tp3Itr!=tracksMinus.cend(); ++tp3Itr) {
1580 if((tp2->
pt()>m_extraTrk2MinPt && tp3->
pt()>m_extraTrk3MinPt) ||
1581 (tp2->
pt()>m_extraTrk3MinPt && tp3->
pt()>m_extraTrk2MinPt)) {
1582 p4_ExtraTrk1.SetPtEtaPhiM(tp1->pt(), tp1->eta(), tp1->phi(), m_extraTrk1MassHypo);
1583 p4_ExtraTrk2.SetPtEtaPhiM(tp2->
pt(), tp2->
eta(), tp2->
phi(), m_extraTrk2MassHypo);
1584 p4_ExtraTrk3.SetPtEtaPhiM(tp3->
pt(), tp3->
eta(), tp3->
phi(), m_extraTrk3MassHypo);
1585 if((p4_moth+p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M() < m_MassLower || (p4_moth+p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M() > m_MassUpper)
continue;
1586 auto Dpm = getDpmCandidate(JXvtx,massesJX,tp1,tp2,tp3);
1587 if(Dpm.extraTrack1) DpmCandidates.
push_back(Dpm);
1588 auto Dstpm = getDstpmCandidate(JXvtx,massesJX,tp1,tp2,tp3);
1589 if(Dstpm.extraTrack1) DstpmCandidates.
push_back(Dstpm);
1596 if( tp1->pt() < m_extraTrk1MinPt )
continue;
1597 for(
auto tp2Itr=tracksPlus.cbegin(); tp2Itr!=tracksPlus.cend(); ++tp2Itr) {
1599 for(
auto tp3Itr=tp2Itr+1; tp3Itr!=tracksPlus.cend(); ++tp3Itr) {
1601 if((tp2->
pt()>m_extraTrk2MinPt && tp3->
pt()>m_extraTrk3MinPt) ||
1602 (tp2->
pt()>m_extraTrk3MinPt && tp3->
pt()>m_extraTrk2MinPt)) {
1603 p4_ExtraTrk1.SetPtEtaPhiM(tp1->pt(), tp1->eta(), tp1->phi(), m_extraTrk1MassHypo);
1604 p4_ExtraTrk2.SetPtEtaPhiM(tp2->
pt(), tp2->
eta(), tp2->
phi(), m_extraTrk2MassHypo);
1605 p4_ExtraTrk3.SetPtEtaPhiM(tp3->
pt(), tp3->
eta(), tp3->
phi(), m_extraTrk3MassHypo);
1606 if((p4_moth+p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M() < m_MassLower || (p4_moth+p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M() > m_MassUpper)
continue;
1607 auto Dpm = getDpmCandidate(JXvtx,massesJX,tp1,tp2,tp3);
1608 if(Dpm.extraTrack1) DpmCandidates.
push_back(Dpm);
1609 auto Dstpm = getDstpmCandidate(JXvtx,massesJX,tp1,tp2,tp3);
1610 if(Dstpm.extraTrack1) DstpmCandidates.
push_back(Dstpm);
1616 std::vector<double> massesExtra{m_extraTrk1MassHypo,m_extraTrk2MassHypo,m_extraTrk3MassHypo};
1618 for(
auto&& Dpm : DpmCandidates.
vector()) {
1619 std::vector<const xAOD::TrackParticle*> tracksExtra{Dpm.extraTrack1,Dpm.extraTrack2,Dpm.extraTrack3};
1622 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1625 m_iVertexFitter->setRobustness(robustness, *state);
1628 std::vector<Trk::VertexID> vrtList;
1633 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1635 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1637 vrtList.push_back(vID1);
1640 if (m_constrDpm && m_mass_Dpm>0) {
1641 vID2 = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state,m_mass_Dpm);
1643 vID2 = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state);
1645 vrtList.push_back(vID2);
1649 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massMainV);
1651 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
1653 if (m_constrJX && m_jxDaug_num>2) {
1654 std::vector<Trk::VertexID> cnstV;
1655 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1660 std::vector<Trk::VertexID> cnstV;
1661 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1665 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1666 std::vector<Trk::VertexID> cnstV;
1667 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1672 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1676 if(
v->nTrackParticles()==0) {
1677 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1678 v->setTrackParticleLinks(nullLinkVector);
1682 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1688 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1689 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1690 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1691 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1692 size_t iMoth = cascadeVertices.size()-1;
1693 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1694 double lxy_SV2 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
1695 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut && lxy_SV2>m_lxyDpm_cut) {
1696 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1697 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1699 type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1701 else if(V0==LAMBDABAR) {
1702 type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1705 type_V1_decor(*cascadeVertices[0]) =
"Ks";
1707 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1708 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1709 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1710 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1711 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1712 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1713 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1714 trk_px.reserve(V0_helper.
nRefTrks());
1715 trk_py.reserve(V0_helper.
nRefTrks());
1716 trk_pz.reserve(V0_helper.
nRefTrks());
1717 for(
auto&& vec3 : V0_helper.
refTrks()) {
1718 trk_px.push_back( vec3.Px() );
1719 trk_py.push_back( vec3.Py() );
1720 trk_pz.push_back( vec3.Pz() );
1722 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1723 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1724 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1726 result.push_back( fit_result.release() );
1731 std::vector<double> massesJXExtra = massesJX;
1732 massesJXExtra.push_back(m_extraTrk3MassHypo);
1733 std::vector<double> massesExtra12{m_extraTrk1MassHypo,m_extraTrk2MassHypo};
1735 for(
auto&& Dstpm : DstpmCandidates.
vector()) {
1736 std::vector<const xAOD::TrackParticle*> tracksExtra12{Dstpm.extraTrack1,Dstpm.extraTrack2};
1737 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX;
1738 tracksJXExtra.push_back(Dstpm.extraTrack3);
1741 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1744 m_iVertexFitter->setRobustness(robustness, *state);
1747 std::vector<Trk::VertexID> vrtList;
1752 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1754 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1756 vrtList.push_back(vID1);
1759 if (m_constrD0 && m_mass_D0>0) {
1760 vID2 = m_iVertexFitter->nextVertex(tracksExtra12,massesExtra12,*state,m_mass_D0);
1762 vID2 = m_iVertexFitter->nextVertex(tracksExtra12,massesExtra12,*state);
1764 vrtList.push_back(vID2);
1768 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state,m_massMainV);
1770 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state);
1772 if (m_constrJX && m_jxDaug_num>2) {
1773 std::vector<Trk::VertexID> cnstV;
1774 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1779 std::vector<Trk::VertexID> cnstV;
1780 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1784 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1785 std::vector<Trk::VertexID> cnstV;
1786 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1790 if (m_constrDstpm && m_mass_Dstpm>0) {
1791 std::vector<Trk::VertexID> cnstV{vID2};
1792 std::vector<const xAOD::TrackParticle*> tracksExtra3{Dstpm.extraTrack3};
1793 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksExtra3,cnstV,*state,m_mass_Dstpm).isSuccess() ) {
1798 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1802 if(
v->nTrackParticles()==0) {
1803 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1804 v->setTrackParticleLinks(nullLinkVector);
1808 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1814 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1815 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1816 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1817 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1818 size_t iMoth = cascadeVertices.size()-1;
1819 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1820 double lxy_SV2 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
1821 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut && lxy_SV2>m_lxyD0_cut) {
1822 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1823 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1825 type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1827 else if(V0==LAMBDABAR) {
1828 type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1831 type_V1_decor(*cascadeVertices[0]) =
"Ks";
1833 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1834 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1835 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1836 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1837 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1838 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1839 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1840 trk_px.reserve(V0_helper.
nRefTrks());
1841 trk_py.reserve(V0_helper.
nRefTrks());
1842 trk_pz.reserve(V0_helper.
nRefTrks());
1843 for(
auto&& vec3 : V0_helper.
refTrks()) {
1844 trk_px.push_back( vec3.Px() );
1845 trk_py.push_back( vec3.Py() );
1846 trk_pz.push_back( vec3.Pz() );
1848 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1849 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1850 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1852 result.push_back( fit_result.release() );
1861 std::vector<Trk::VxCascadeInfo*> JpsiXPlusDisplaced::fitMainVtx(
const xAOD::Vertex* JXvtx,
const std::vector<double>& massesJX,
const XiCandidate& disVtx,
const xAOD::TrackParticleContainer* trackContainer,
const std::vector<const xAOD::TrackParticleContainer*>& trackCols)
const {
1862 std::vector<Trk::VxCascadeInfo*>
result;
1864 std::vector<const xAOD::TrackParticle*> tracksJX;
1867 if (tracksJX.size() != massesJX.size()) {
1868 ATH_MSG_ERROR(
"Problems with JX input: number of tracks or track mass inputs is not correct!");
1874 std::vector<const xAOD::TrackParticle*> tracksV0;
1878 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), disVtx.
track) != tracksJX.cend())
return result;
1879 std::vector<const xAOD::TrackParticle*> tracks3{disVtx.
track};
1880 std::vector<double> massesDis3{m_disVDaug3MassHypo};
1882 std::vector<const xAOD::TrackParticle*> tracksJpsi{tracksJX[0], tracksJX[1]};
1883 std::vector<const xAOD::TrackParticle*> tracksX;
1884 if(m_jxDaug_num>=3) tracksX.push_back(tracksJX[2]);
1885 if(m_jxDaug_num==4) tracksX.push_back(tracksJX[3]);
1887 std::vector<double> massesV0;
1888 if(disVtx.
V0type==LAMBDA) {
1889 massesV0 = m_massesV0_ppi;
1891 else if(disVtx.
V0type==LAMBDABAR) {
1892 massesV0 = m_massesV0_pip;
1894 else if(disVtx.
V0type==KS) {
1895 massesV0 = m_massesV0_pipi;
1898 std::vector<double> massesDisV = massesV0;
1899 massesDisV.push_back(m_disVDaug3MassHypo);
1901 TLorentzVector p4_moth,
tmp;
1932 std::vector<float> trk_px;
1933 std::vector<float> trk_py;
1934 std::vector<float> trk_pz;
1936 if(m_extraTrk1MassHypo<=0) {
1937 if (p4_moth.M() < m_MassLower || p4_moth.M() > m_MassUpper)
return result;
1940 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1943 m_iVertexFitter->setRobustness(robustness, *state);
1946 std::vector<Trk::VertexID> vrtList;
1947 std::vector<Trk::VertexID> vrtList2;
1952 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1954 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1956 vrtList.push_back(vID1);
1960 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state,m_massDisV);
1962 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state);
1964 vrtList2.push_back(vID2);
1968 if (m_constrJX && m_jxDaug_num>2) {
1969 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state,m_massJX);
1971 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state);
1973 vrtList2.push_back(vID3);
1975 std::vector<const xAOD::TrackParticle*>
tp;
1976 std::vector<double> tp_masses;
1978 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList2,*state,m_massMainV);
1980 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList2,*state);
1986 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state,m_massMainV);
1988 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state);
1990 if (m_constrJX && m_jxDaug_num>2) {
1991 std::vector<Trk::VertexID> cnstV;
1992 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1998 std::vector<Trk::VertexID> cnstV;
1999 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
2003 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
2004 std::vector<Trk::VertexID> cnstV;
2005 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
2010 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
2014 if(
v->nTrackParticles()==0) {
2015 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
2016 v->setTrackParticleLinks(nullLinkVector);
2020 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
2026 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
2027 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
2029 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
2030 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
2031 size_t iMoth = cascadeVertices.size()-1;
2032 double lxy_SV1_sub = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
2033 double lxy_SV1 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
2035 if(chi2CutPassed && lxy_SV1>m_lxyDisV_cut && lxy_SV1_sub>m_lxyV0_cut) {
2038 if(disVtx.
V0type==LAMBDA) {
2039 type_V0_decor(*cascadeVertices[0]) =
"Lambda";
2041 else if(disVtx.
V0type==LAMBDABAR) {
2042 type_V0_decor(*cascadeVertices[0]) =
"Lambdabar";
2044 else if(disVtx.
V0type==KS) {
2045 type_V0_decor(*cascadeVertices[0]) =
"Ks";
2047 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*disVtx.
V0vtx) ? mAcc_gfit(*disVtx.
V0vtx) : 0;
2048 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*disVtx.
V0vtx) ? mAcc_gmass(*disVtx.
V0vtx) : -1;
2049 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*disVtx.
V0vtx) ? mAcc_gmasserr(*disVtx.
V0vtx) : -1;
2050 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*disVtx.
V0vtx) ? mAcc_gchisq(*disVtx.
V0vtx) : 999999;
2051 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*disVtx.
V0vtx) ? mAcc_gndof(*disVtx.
V0vtx) : 0;
2052 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*disVtx.
V0vtx) ? mAcc_gprob(*disVtx.
V0vtx) : -1;
2053 trk_px.clear(); trk_py.clear(); trk_pz.clear();
2057 trk_pxDeco(*cascadeVertices[0]) = trk_px;
2058 trk_pyDeco(*cascadeVertices[0]) = trk_py;
2059 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
2060 trk_px_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Px();
2061 trk_py_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Py();
2062 trk_pz_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Pz();
2064 result.push_back( fit_result.release() );
2069 std::vector<double> massesJXExtra = massesJX;
2070 massesJXExtra.push_back(m_extraTrk1MassHypo);
2073 if ( tpExtra->pt()<m_extraTrk1MinPt )
continue;
2074 if ( !m_trkSelector->decision(*tpExtra,
nullptr) )
continue;
2076 if(
std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend())
continue;
2077 if(
std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend())
continue;
2078 if(tpExtra == disVtx.
track)
continue;
2081 tmp.SetPtEtaPhiM(tpExtra->pt(),tpExtra->eta(),tpExtra->phi(),m_extraTrk1MassHypo);
2082 if ((p4_moth+
tmp).M() < m_MassLower || (p4_moth+
tmp).M() > m_MassUpper)
continue;
2084 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX;
2085 tracksJXExtra.push_back(tpExtra);
2088 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
2091 m_iVertexFitter->setRobustness(robustness, *state);
2094 std::vector<Trk::VertexID> vrtList;
2095 std::vector<Trk::VertexID> vrtList2;
2100 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
2102 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
2104 vrtList.push_back(vID1);
2108 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state,m_massDisV);
2110 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state);
2112 vrtList2.push_back(vID2);
2116 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,*state);
2117 vrtList2.push_back(vID3);
2119 std::vector<const xAOD::TrackParticle*>
tp;
2120 std::vector<double> tp_masses;
2122 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList2,*state,m_massMainV);
2124 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList2,*state);
2130 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList2,*state,m_massMainV);
2132 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList2,*state);
2135 if (m_constrJX && m_jxDaug_num>2) {
2136 std::vector<Trk::VertexID> cnstV;
2137 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
2142 std::vector<Trk::VertexID> cnstV;
2143 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
2147 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
2148 std::vector<Trk::VertexID> cnstV;
2149 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
2154 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
2158 if(
v->nTrackParticles()==0) {
2159 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
2160 v->setTrackParticleLinks(nullLinkVector);
2164 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
2170 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
2171 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
2173 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
2174 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
2175 size_t iMoth = cascadeVertices.size()-1;
2176 double lxy_SV1_sub = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
2177 double lxy_SV1 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
2179 if(chi2CutPassed && lxy_SV1>m_lxyDisV_cut && lxy_SV1_sub>m_lxyV0_cut) {
2182 if(disVtx.
V0type==LAMBDA) {
2183 type_V0_decor(*cascadeVertices[0]) =
"Lambda";
2185 else if(disVtx.
V0type==LAMBDABAR) {
2186 type_V0_decor(*cascadeVertices[0]) =
"Lambdabar";
2188 else if(disVtx.
V0type==KS) {
2189 type_V0_decor(*cascadeVertices[0]) =
"Ks";
2191 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*disVtx.
V0vtx) ? mAcc_gfit(*disVtx.
V0vtx) : 0;
2192 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*disVtx.
V0vtx) ? mAcc_gmass(*disVtx.
V0vtx) : -1;
2193 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*disVtx.
V0vtx) ? mAcc_gmasserr(*disVtx.
V0vtx) : -1;
2194 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*disVtx.
V0vtx) ? mAcc_gchisq(*disVtx.
V0vtx) : 999999;
2195 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*disVtx.
V0vtx) ? mAcc_gndof(*disVtx.
V0vtx) : 0;
2196 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*disVtx.
V0vtx) ? mAcc_gprob(*disVtx.
V0vtx) : -1;
2197 trk_px.clear(); trk_py.clear(); trk_pz.clear();
2201 trk_pxDeco(*cascadeVertices[0]) = trk_px;
2202 trk_pyDeco(*cascadeVertices[0]) = trk_py;
2203 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
2204 trk_px_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Px();
2205 trk_py_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Py();
2206 trk_pz_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Pz();
2208 result.push_back( fit_result.release() );
2217 void JpsiXPlusDisplaced::fitV0Container(
xAOD::VertexContainer* V0ContainerNew,
const std::vector<const xAOD::TrackParticle*>& selectedTracks,
const std::vector<const xAOD::TrackParticleContainer*>& trackCols)
const {
2218 const EventContext& ctx = Gaudi::Hive::currentContext();
2228 std::vector<const xAOD::TrackParticle*> posTracks;
2229 std::vector<const xAOD::TrackParticle*> negTracks;
2231 if(TP->charge()>0) posTracks.push_back(TP);
2232 else negTracks.push_back(TP);
2236 const Trk::Perigee& aPerigee1 = TP1->perigeeParameters();
2238 const Trk::Perigee& aPerigee2 = TP2->perigeeParameters();
2239 int sflag(0), errorcode(0);
2240 Amg::Vector3D startingPoint = m_vertexEstimator->getCirclesIntersectionPoint(&aPerigee1,&aPerigee2,sflag,errorcode);
2241 if (errorcode != 0) {startingPoint(0) = 0.0; startingPoint(1) = 0.0; startingPoint(2) = 0.0;}
2243 if (errorcode == 0 || errorcode == 5 || errorcode == 6 || errorcode == 8) {
2245 const Trk::TrackParameters* extrapolatedPerigee1 = m_extrapolator->extrapolate(ctx,TP1->perigeeParameters(), perigeeSurface).release();
2246 const Trk::TrackParameters* extrapolatedPerigee2 = m_extrapolator->extrapolate(ctx,TP2->perigeeParameters(), perigeeSurface).release();
2247 std::vector<std::unique_ptr<const Trk::TrackParameters> > cleanup;
2248 if(!extrapolatedPerigee1) extrapolatedPerigee1 = &TP1->perigeeParameters();
2249 else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee1));
2250 if(!extrapolatedPerigee2) extrapolatedPerigee2 = &TP2->perigeeParameters();
2251 else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee2));
2252 if(extrapolatedPerigee1 && extrapolatedPerigee2) {
2254 TLorentzVector v1; TLorentzVector
v2;
2256 v1.SetXYZM(extrapolatedPerigee1->
momentum().x(),extrapolatedPerigee1->
momentum().y(),extrapolatedPerigee1->
momentum().z(),m_mass_proton);
2257 v2.SetXYZM(extrapolatedPerigee2->
momentum().x(),extrapolatedPerigee2->
momentum().y(),extrapolatedPerigee2->
momentum().z(),m_mass_pion);
2258 if((v1+
v2).M()>900.0 && (v1+
v2).M()<1350.0) pass =
true;
2261 v1.SetXYZM(extrapolatedPerigee1->
momentum().x(),extrapolatedPerigee1->
momentum().y(),extrapolatedPerigee1->
momentum().z(),m_mass_pion);
2262 v2.SetXYZM(extrapolatedPerigee2->
momentum().x(),extrapolatedPerigee2->
momentum().y(),extrapolatedPerigee2->
momentum().z(),m_mass_proton);
2263 if((v1+
v2).M()>900.0 && (v1+
v2).M()<1350.0) pass =
true;
2266 v1.SetXYZM(extrapolatedPerigee1->
momentum().x(),extrapolatedPerigee1->
momentum().y(),extrapolatedPerigee1->
momentum().z(),m_mass_pion);
2267 v2.SetXYZM(extrapolatedPerigee2->
momentum().x(),extrapolatedPerigee2->
momentum().y(),extrapolatedPerigee2->
momentum().z(),m_mass_pion);
2268 if((v1+
v2).M()>300.0 && (v1+
v2).M()<700.0) pass =
true;
2271 std::vector<const xAOD::TrackParticle*> tracksV0;
2272 tracksV0.push_back(TP1); tracksV0.push_back(TP2);
2273 std::unique_ptr<xAOD::Vertex> V0vtx = std::unique_ptr<xAOD::Vertex>( m_iV0Fitter->fit(tracksV0, startingPoint) );
2276 if(chi2DOF>m_chi2cut_V0)
continue;
2278 double massSig_V0_Lambda1 = std::abs(m_V0Tools->invariantMass(V0vtx.get(), m_massesV0_ppi)-m_mass_Lambda)/m_V0Tools->invariantMassError(V0vtx.get(), m_massesV0_ppi);
2279 double massSig_V0_Lambda2 = std::abs(m_V0Tools->invariantMass(V0vtx.get(), m_massesV0_pip)-m_mass_Lambda)/m_V0Tools->invariantMassError(V0vtx.get(), m_massesV0_pip);
2280 double massSig_V0_Ks = std::abs(m_V0Tools->invariantMass(V0vtx.get(), m_massesV0_pipi)-m_mass_Ks)/m_V0Tools->invariantMassError(V0vtx.get(), m_massesV0_pipi);
2281 if(massSig_V0_Lambda1<=massSig_V0_Lambda2 && massSig_V0_Lambda1<=massSig_V0_Ks) {
2282 mDec_type(*V0vtx.get()) =
"Lambda";
2284 else if(massSig_V0_Lambda2<=massSig_V0_Lambda1 && massSig_V0_Lambda2<=massSig_V0_Ks) {
2285 mDec_type(*V0vtx.get()) =
"Lambdabar";
2287 else if(massSig_V0_Ks<=massSig_V0_Lambda1 && massSig_V0_Ks<=massSig_V0_Lambda2) {
2288 mDec_type(*V0vtx.get()) =
"Ks";
2291 int gamma_fit = 0;
int gamma_ndof = 0;
double gamma_chisq = 999999.;
2292 double gamma_prob = -1., gamma_mass = -1., gamma_massErr = -1.;
2293 std::unique_ptr<xAOD::Vertex> gammaVtx = std::unique_ptr<xAOD::Vertex>( m_iGammaFitter->fit(tracksV0, m_V0Tools->vtx(V0vtx.get())) );
2296 gamma_mass = m_V0Tools->invariantMass(gammaVtx.get(),m_mass_e,m_mass_e);
2297 gamma_massErr = m_V0Tools->invariantMassError(gammaVtx.get(),m_mass_e,m_mass_e);
2298 gamma_chisq = m_V0Tools->chisq(gammaVtx.get());
2299 gamma_ndof = m_V0Tools->ndof(gammaVtx.get());
2300 gamma_prob = m_V0Tools->vertexProbability(gammaVtx.get());
2302 mDec_gfit(*V0vtx.get()) = gamma_fit;
2303 mDec_gmass(*V0vtx.get()) = gamma_mass;
2304 mDec_gmasserr(*V0vtx.get()) = gamma_massErr;
2305 mDec_gchisq(*V0vtx.get()) = gamma_chisq;
2306 mDec_gndof(*V0vtx.get()) = gamma_ndof;
2307 mDec_gprob(*V0vtx.get()) = gamma_prob;
2312 if(not trackCols.empty()){
2314 JpsiUpsilonCommon::RelinkVertexTracks(trackCols, V0vtx.get());
2315 }
catch (std::runtime_error
const&
e) {
2321 V0ContainerNew->
push_back(std::move(V0vtx));
2330 template<
size_t NTracks>
2333 assert(v1->nTrackParticles() == NTracks);
2334 std::array<const xAOD::TrackParticle*, NTracks> a1;
2335 std::array<const xAOD::TrackParticle*, NTracks> a2;
2336 for(
size_t i=0;
i<NTracks;
i++){
2337 a1[
i] = v1->trackParticle(
i);
2338 a2[
i] =
v->trackParticle(
i);
2340 std::sort(a1.begin(), a1.end());
2341 std::sort(a2.begin(), a2.end());
2342 if(a1 == a2)
return v1;