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)
ATH_MSG_ERROR(
"CascadeInfo is null");
714 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->vertices();
715 if(cascadeVertices.size() != topoN)
ATH_MSG_ERROR(
"Incorrect number of vertices");
716 for(
size_t i=0;
i<topoN;
i++) {
717 if(cascadeVertices[
i]==
nullptr)
ATH_MSG_ERROR(
"Error null vertex");
720 cascade_info->setSVOwnership(
false);
721 const auto mainVertex = cascadeVertices[topoN-1];
722 const std::vector< std::vector<TLorentzVector> > &moms = cascade_info->getParticleMoms();
725 int ijx = m_JXSubVtx ? topoN-2 : topoN-1;
726 if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo>0) ijx = topoN-1;
728 if(m_jxDaug_num==4) jxVtx = FindVertex<4>(jxContainer.
ptr(), cascadeVertices[ijx]);
729 else if(m_jxDaug_num==3) jxVtx = FindVertex<3>(jxContainer.
ptr(), cascadeVertices[ijx]);
730 else jxVtx = FindVertex<2>(jxContainer.
ptr(), cascadeVertices[ijx]);
735 BPhysPVCascadeTools::SetVectorInfo(vtx, cascade_info);
744 BPHYS_CHECK( vtx.
setMassErr(m_CascadeTools->invariantMassError(moms[topoN-1],cascade_info->getCovariance()[topoN-1])) );
746 Pt_decor(*mainVertex) = m_CascadeTools->pT(moms[topoN-1]);
747 PtErr_decor(*mainVertex) = m_CascadeTools->pTError(moms[topoN-1],cascade_info->getCovariance()[topoN-1]);
749 chi2_decor(*mainVertex) = cascade_info->fitChi2();
750 ndof_decor(*mainVertex) = cascade_info->nDoF();
752 if(m_disVDaug_num==2) {
754 lxy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
755 lxyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
756 a0z_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
757 a0zErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
758 a0xy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
759 a0xyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
763 lxy_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
764 lxyErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
765 a0z_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],cascadeVertices[1]);
766 a0zErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
767 a0xy_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],cascadeVertices[1]);
768 a0xyErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
771 lxy_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
772 lxyErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
773 a0xy_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
774 a0xyErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
775 a0z_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
776 a0zErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
779 if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo>0) {
780 lxy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
781 lxyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
782 a0z_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
783 a0zErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
784 a0xy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
785 a0xyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
788 else if(m_JXSubVtx) {
789 lxy_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->lxy(moms[ijx],cascadeVertices[ijx],mainVertex);
790 lxyErr_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->lxyError(moms[ijx],cascade_info->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
791 a0z_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0z(moms[ijx],cascadeVertices[ijx],mainVertex);
792 a0zErr_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0zError(moms[ijx],cascade_info->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
793 a0xy_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0xy(moms[ijx],cascadeVertices[ijx],mainVertex);
794 a0xyErr_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0xyError(moms[ijx],cascade_info->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
797 chi2_V2_decor(*cascadeVertices[ijx]) = m_V0Tools->chisq(jxVtx);
798 ndof_V2_decor(*cascadeVertices[ijx]) = m_V0Tools->ndof(jxVtx);
800 double Mass_Moth = m_CascadeTools->invariantMass(moms[topoN-1]);
801 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));
803 for(
size_t i=0;
i<topoN;
i++) {
804 VtxWriteHandles[
i].ptr()->push_back(cascadeVertices[
i]);
812 if( vertexLink1.
isValid() ) precedingVertexLinks.push_back( vertexLink1 );
817 if( vertexLink2.
isValid() ) precedingVertexLinks.push_back( vertexLink2 );
823 if( vertexLink3.
isValid() ) precedingVertexLinks.push_back( vertexLink3 );
825 CascadeLinksDecor(*mainVertex) = precedingVertexLinks;
829 for (
auto cascade_info : cascadeinfoContainer)
delete cascade_info;
831 return StatusCode::SUCCESS;
836 const EventContext& ctx = Gaudi::Hive::currentContext();
837 std::unique_ptr<Trk::Perigee> per = m_trackToVertexTool->perigeeAtVertex(ctx, *
track, PV->
position());
838 if(!per)
return pass;
840 double sig_d0 = sqrt((*per->covariance())(0,0));
841 if(std::abs(
d0/sig_d0) > m_d0_cut) pass =
true;
848 std::vector<const xAOD::TrackParticle*> tracksV0;
851 if(
std::find(tracksV0.cbegin(), tracksV0.cend(), track3) != tracksV0.cend())
return disVtx;
853 std::vector<double> massesV0;
855 massesV0 = m_massesV0_ppi;
857 else if(V0==LAMBDABAR) {
858 massesV0 = m_massesV0_pip;
861 massesV0 = m_massesV0_pipi;
864 TLorentzVector p4_v0,
tmp;
866 tmp.SetPtEtaPhiM(track3->
pt(),track3->
eta(),track3->
phi(),m_disVDaug3MassHypo);
868 if((p4_v0+
tmp).M() < m_DisplacedMassLower-120. || (p4_v0+
tmp).M() > m_DisplacedMassUpper+120.)
return disVtx;
870 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
872 m_iVertexFitter->setRobustness(robustness, *state);
873 std::vector<Trk::VertexID> vrtList;
875 Trk::VertexID vID = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
876 vrtList.push_back(vID);
878 std::vector<const xAOD::TrackParticle*> tracksDis3{track3};
879 std::vector<double> massesDis3{m_disVDaug3MassHypo};
880 m_iVertexFitter->nextVertex(tracksDis3,massesDis3,vrtList,*state);
882 std::unique_ptr<Trk::VxCascadeInfo> cascade_info = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
885 double chi2NDF = cascade_info->
fitChi2()/cascade_info->
nDoF();
886 if(m_chi2cut_DisV<=0 || chi2NDF < m_chi2cut_DisV) {
887 const std::vector<std::vector<TLorentzVector> > &moms = cascade_info->
getParticleMoms();
888 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->
vertices();
889 double lxy_SV1_sub = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
890 if(lxy_SV1_sub > m_lxyV0_cut) {
891 TLorentzVector totalMom;
892 for(
size_t it=0;
it<moms[1].size();
it++) totalMom += moms[1][
it];
893 if(totalMom.M()>m_DisplacedMassLower && totalMom.M()<m_DisplacedMassUpper) {
907 std::vector<const xAOD::TrackParticle*> tracksV0;
910 if(
std::find(tracksV0.cbegin(), tracksV0.cend(), extraTrk1) != tracksV0.cend())
return etac;
911 if(
std::find(tracksV0.cbegin(), tracksV0.cend(), extraTrk2) != tracksV0.cend())
return etac;
913 std::vector<double> massesV0;
915 massesV0 = m_massesV0_ppi;
917 else if(V0==LAMBDABAR) {
918 massesV0 = m_massesV0_pip;
921 massesV0 = m_massesV0_pipi;
924 TLorentzVector p4_v0, tmp1,
tmp2;
926 tmp1.SetPtEtaPhiM(extraTrk1->
pt(),extraTrk1->
eta(),extraTrk1->
phi(),m_extraTrk1MassHypo);
927 tmp2.SetPtEtaPhiM(extraTrk2->
pt(),extraTrk2->
eta(),extraTrk2->
phi(),m_extraTrk2MassHypo);
928 if((p4_v0+tmp1+
tmp2).M() < m_V0ExtraMassLower || (p4_v0+tmp1+
tmp2).M() > m_V0ExtraMassUpper)
return etac;
930 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
932 m_iVertexFitter->setRobustness(robustness, *state);
933 std::vector<Trk::VertexID> vrtList;
935 Trk::VertexID vID = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
936 vrtList.push_back(vID);
938 std::vector<const xAOD::TrackParticle*> extraTracks{extraTrk1, extraTrk2};
939 std::vector<double> extraMasses{m_extraTrk1MassHypo, m_extraTrk2MassHypo};
940 m_iVertexFitter->nextVertex(extraTracks,extraMasses,vrtList,*state);
942 std::unique_ptr<Trk::VxCascadeInfo> cascade_info = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
945 double chi2NDF = cascade_info->
fitChi2()/cascade_info->
nDoF();
946 if(m_chi2cut_V0Extra<=0 || chi2NDF < m_chi2cut_V0Extra) {
947 const std::vector<std::vector<TLorentzVector> > &moms = cascade_info->
getParticleMoms();
948 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->
vertices();
949 double lxy = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
950 if(lxy > m_lxyV0_cut) {
951 TLorentzVector totalMom;
952 for(
size_t it=0;
it<moms[1].size();
it++) totalMom += moms[1][
it];
955 etac.
chi2NDF = chi2NDF; etac.
pt = totalMom.Pt();
965 std::vector<const xAOD::TrackParticle*> tracksJX;
968 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk1) != tracksJX.cend())
return Dpm;
969 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk2) != tracksJX.cend())
return Dpm;
970 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk3) != tracksJX.cend())
return Dpm;
972 TLorentzVector tmp1,
tmp2, tmp3;
973 tmp1.SetPtEtaPhiM(extraTrk1->
pt(),extraTrk1->
eta(),extraTrk1->
phi(),m_extraTrk1MassHypo);
974 tmp2.SetPtEtaPhiM(extraTrk2->
pt(),extraTrk2->
eta(),extraTrk2->
phi(),m_extraTrk2MassHypo);
975 tmp3.SetPtEtaPhiM(extraTrk3->
pt(),extraTrk3->
eta(),extraTrk3->
phi(),m_extraTrk3MassHypo);
976 if((tmp1+
tmp2+tmp3).M() < m_DpmMassLower || (tmp1+
tmp2+tmp3).M() > m_DpmMassUpper)
return Dpm;
978 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
980 m_iVertexFitter->setRobustness(robustness, *state);
981 std::vector<Trk::VertexID> vrtList;
983 std::vector<const xAOD::TrackParticle*> extraTracks{extraTrk1, extraTrk2, extraTrk3};
984 std::vector<double> extraMasses{m_extraTrk1MassHypo, m_extraTrk2MassHypo, m_extraTrk3MassHypo};
985 Trk::VertexID vID = m_iVertexFitter->startVertex(extraTracks,extraMasses,*state);
986 vrtList.push_back(vID);
988 m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
990 std::unique_ptr<Trk::VxCascadeInfo> cascade_info = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
993 double chi2NDF = cascade_info->
fitChi2()/cascade_info->
nDoF();
994 if(m_chi2cut_JXDpm<=0 || chi2NDF < m_chi2cut_JXDpm) {
995 const std::vector<std::vector<TLorentzVector> > &moms = cascade_info->
getParticleMoms();
996 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->
vertices();
997 double lxy = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
998 if(lxy > m_lxyDpm_cut) {
1000 Dpm.
chi2NDF = chi2NDF; Dpm.
pt = moms[1][tracksJX.size()].Pt();
1010 std::vector<const xAOD::TrackParticle*> tracksJX;
1013 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk1) != tracksJX.cend())
return Dstpm;
1014 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk2) != tracksJX.cend())
return Dstpm;
1015 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), extraTrk3) != tracksJX.cend())
return Dstpm;
1017 TLorentzVector tmp1,
tmp2, tmp3;
1018 tmp1.SetPtEtaPhiM(extraTrk1->
pt(),extraTrk1->
eta(),extraTrk1->
phi(),m_extraTrk1MassHypo);
1019 tmp2.SetPtEtaPhiM(extraTrk2->
pt(),extraTrk2->
eta(),extraTrk2->
phi(),m_extraTrk2MassHypo);
1020 tmp3.SetPtEtaPhiM(extraTrk3->
pt(),extraTrk3->
eta(),extraTrk3->
phi(),m_extraTrk3MassHypo);
1021 if((tmp1+
tmp2).M() < m_D0MassLower || (tmp1+
tmp2).M() > m_D0MassUpper)
return Dstpm;
1022 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;
1024 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1026 m_iVertexFitter->setRobustness(robustness, *state);
1027 std::vector<Trk::VertexID> vrtList;
1029 std::vector<const xAOD::TrackParticle*> extraTracks{extraTrk1, extraTrk2};
1030 std::vector<double> extraMasses{m_extraTrk1MassHypo, m_extraTrk2MassHypo};
1031 Trk::VertexID vID = m_iVertexFitter->startVertex(extraTracks,extraMasses,*state);
1032 vrtList.push_back(vID);
1034 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX;
1035 tracksJXExtra.push_back(extraTrk3);
1036 std::vector<double> massesJXExtra = massesJX;
1037 massesJXExtra.push_back(m_extraTrk3MassHypo);
1038 m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state);
1040 std::unique_ptr<Trk::VxCascadeInfo> cascade_info = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1043 double chi2NDF = cascade_info->
fitChi2()/cascade_info->
nDoF();
1044 if(m_chi2cut_JXDstpm<=0 || chi2NDF < m_chi2cut_JXDstpm) {
1045 const std::vector<std::vector<TLorentzVector> > &moms = cascade_info->
getParticleMoms();
1046 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->
vertices();
1047 double lxy = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
1048 if(lxy > m_lxyD0_cut) {
1049 TLorentzVector totalMom;
1050 for(
size_t it=tracksJX.size();
it<moms[1].size();
it++) totalMom += moms[1][
it];
1052 Dstpm.
chi2NDF = chi2NDF; Dstpm.
pt = totalMom.Pt();
1060 std::vector<Trk::VxCascadeInfo*>
result;
1062 std::vector<const xAOD::TrackParticle*> tracksJX;
1065 if (tracksJX.size() != massesJX.size()) {
1066 ATH_MSG_ERROR(
"Problems with JX input: number of tracks or track mass inputs is not correct!");
1072 std::vector<const xAOD::TrackParticle*> tracksV0;
1076 std::vector<const xAOD::TrackParticle*> tracksJpsi{tracksJX[0], tracksJX[1]};
1077 std::vector<const xAOD::TrackParticle*> tracksX;
1078 if(m_jxDaug_num>=3) tracksX.push_back(tracksJX[2]);
1079 if(m_jxDaug_num==4) tracksX.push_back(tracksJX[3]);
1081 std::vector<double> massesV0;
1083 massesV0 = m_massesV0_ppi;
1085 else if(V0==LAMBDABAR) {
1086 massesV0 = m_massesV0_pip;
1089 massesV0 = m_massesV0_pipi;
1092 TLorentzVector p4_moth, p4_v0,
tmp;
1099 p4_moth += V0_helper.
refTrk(
it,massesV0[
it]);
1124 std::vector<float> trk_px;
1125 std::vector<float> trk_py;
1126 std::vector<float> trk_pz;
1128 if(m_extraTrk1MassHypo<=0) {
1129 if (p4_moth.M() < m_MassLower || p4_moth.M() > m_MassUpper)
return result;
1132 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1135 m_iVertexFitter->setRobustness(robustness, *state);
1138 std::vector<Trk::VertexID> vrtList;
1143 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1145 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1147 vrtList.push_back(vID1);
1151 if (m_constrJX && m_jxDaug_num>2) {
1152 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state,m_massJX);
1154 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state);
1156 vrtList.push_back(vID2);
1158 std::vector<const xAOD::TrackParticle*>
tp;
1159 std::vector<double> tp_masses;
1161 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state,m_massMainV);
1163 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state);
1169 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massMainV);
1171 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
1173 if (m_constrJX && m_jxDaug_num>2) {
1174 std::vector<Trk::VertexID> cnstV;
1175 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1181 std::vector<Trk::VertexID> cnstV;
1182 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1186 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1187 std::vector<Trk::VertexID> cnstV;
1188 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1193 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1197 if(
v->nTrackParticles()==0) {
1198 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1199 v->setTrackParticleLinks(nullLinkVector);
1203 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1209 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1210 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1212 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1213 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1214 size_t iMoth = cascadeVertices.size()-1;
1215 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1216 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut) {
1217 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1218 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1220 type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1222 else if(V0==LAMBDABAR) {
1223 type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1226 type_V1_decor(*cascadeVertices[0]) =
"Ks";
1228 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1229 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1230 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1231 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1232 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1233 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1234 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1235 trk_px.reserve(V0_helper.
nRefTrks());
1236 trk_py.reserve(V0_helper.
nRefTrks());
1237 trk_pz.reserve(V0_helper.
nRefTrks());
1238 for(
auto&& vec3 : V0_helper.
refTrks()) {
1239 trk_px.push_back( vec3.Px() );
1240 trk_py.push_back( vec3.Py() );
1241 trk_pz.push_back( vec3.Pz() );
1243 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1244 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1245 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1247 result.push_back( fit_result.release() );
1251 else if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo<=0) {
1252 std::vector<double> massesJXExtra = massesJX;
1253 massesJXExtra.push_back(m_extraTrk1MassHypo);
1256 if( tpExtra->pt()<m_extraTrk1MinPt )
continue;
1257 if( !m_trkSelector->decision(*tpExtra,
nullptr) )
continue;
1259 if(
std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend())
continue;
1260 if(
std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend())
continue;
1263 tmp.SetPtEtaPhiM(tpExtra->pt(),tpExtra->eta(),tpExtra->phi(),m_extraTrk1MassHypo);
1264 if((p4_moth+
tmp).M() < m_MassLower || (p4_moth+
tmp).M() > m_MassUpper)
continue;
1266 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX;
1267 tracksJXExtra.push_back(tpExtra);
1270 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1273 m_iVertexFitter->setRobustness(robustness, *state);
1276 std::vector<Trk::VertexID> vrtList;
1281 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1283 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1285 vrtList.push_back(vID1);
1289 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,*state);
1290 vrtList.push_back(vID2);
1292 std::vector<const xAOD::TrackParticle*>
tp;
1293 std::vector<double> tp_masses;
1295 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state,m_massMainV);
1297 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state);
1303 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state,m_massMainV);
1305 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state);
1308 if (m_constrJX && m_jxDaug_num>2) {
1309 std::vector<Trk::VertexID> cnstV;
1310 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1315 std::vector<Trk::VertexID> cnstV;
1316 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1320 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1321 std::vector<Trk::VertexID> cnstV;
1322 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1327 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1331 if(
v->nTrackParticles()==0) {
1332 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1333 v->setTrackParticleLinks(nullLinkVector);
1337 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1343 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1344 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1345 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1346 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1347 size_t iMoth = cascadeVertices.size()-1;
1348 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1349 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut) {
1350 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1351 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1353 type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1355 else if(V0==LAMBDABAR) {
1356 type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1359 type_V1_decor(*cascadeVertices[0]) =
"Ks";
1361 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1362 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1363 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1364 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1365 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1366 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1367 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1368 trk_px.reserve(V0_helper.
nRefTrks());
1369 trk_py.reserve(V0_helper.
nRefTrks());
1370 trk_pz.reserve(V0_helper.
nRefTrks());
1371 for(
auto&& vec3 : V0_helper.
refTrks()) {
1372 trk_px.push_back( vec3.Px() );
1373 trk_py.push_back( vec3.Py() );
1374 trk_pz.push_back( vec3.Pz() );
1376 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1377 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1378 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1380 result.push_back( fit_result.release() );
1385 else if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo<=0) {
1386 std::vector<const xAOD::TrackParticle*> tracksPlus;
1387 std::vector<const xAOD::TrackParticle*> tracksMinus;
1389 if( tpExtra->pt() < std::fmin(m_extraTrk1MinPt,m_extraTrk2MinPt) )
continue;
1390 if( !m_trkSelector->decision(*tpExtra,
nullptr) )
continue;
1392 if(
std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend())
continue;
1393 if(
std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend())
continue;
1394 if(tpExtra->charge()>0) {
1395 tracksPlus.push_back(tpExtra);
1398 tracksMinus.push_back(tpExtra);
1403 TLorentzVector p4_ExtraTrk1, p4_ExtraTrk2;
1406 if((tp1->pt()>m_extraTrk1MinPt && tp2->pt()>m_extraTrk2MinPt) ||
1407 (tp1->pt()>m_extraTrk2MinPt && tp2->pt()>m_extraTrk1MinPt)) {
1408 p4_ExtraTrk1.SetPtEtaPhiM(tp1->pt(), tp1->eta(), tp1->phi(), m_extraTrk1MassHypo);
1409 p4_ExtraTrk2.SetPtEtaPhiM(tp2->pt(), tp2->eta(), tp2->phi(), m_extraTrk2MassHypo);
1410 if((p4_moth+p4_ExtraTrk1+p4_ExtraTrk2).M() < m_MassLower || (p4_moth+p4_ExtraTrk1+p4_ExtraTrk2).M() > m_MassUpper)
continue;
1411 auto etac = getEtacCandidate(V0vtx,V0,tp1,tp2);
1412 if(etac.V0vtx) etacCandidates.
push_back(etac);
1417 std::vector<double> massesJXExtra = massesJX;
1418 massesJXExtra.push_back(m_extraTrk1MassHypo);
1419 massesJXExtra.push_back(m_extraTrk2MassHypo);
1421 for(
auto&& etac : etacCandidates.
vector()) {
1422 std::vector<const xAOD::TrackParticle*> tracksExtra{etac.extraTrack1, etac.extraTrack2};
1423 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX;
1424 tracksJXExtra.push_back(etac.extraTrack1);
1425 tracksJXExtra.push_back(etac.extraTrack2);
1428 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1431 m_iVertexFitter->setRobustness(robustness, *state);
1434 std::vector<Trk::VertexID> vrtList;
1439 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1441 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1443 vrtList.push_back(vID1);
1447 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,*state);
1448 vrtList.push_back(vID2);
1450 std::vector<const xAOD::TrackParticle*>
tp;
1451 std::vector<double> tp_masses;
1453 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state,m_massMainV);
1455 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList,*state);
1461 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state,m_massMainV);
1463 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state);
1466 if (m_constrJX && m_jxDaug_num>2) {
1467 std::vector<Trk::VertexID> cnstV;
1468 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1473 std::vector<Trk::VertexID> cnstV;
1474 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1478 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1479 std::vector<Trk::VertexID> cnstV;
1480 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1484 if (m_constrV0Extra && m_massV0Extra>0) {
1485 std::vector<Trk::VertexID> cnstV{vID1};
1486 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksExtra,cnstV,*state,m_massV0Extra).isSuccess() ) {
1491 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1495 if(
v->nTrackParticles()==0) {
1496 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1497 v->setTrackParticleLinks(nullLinkVector);
1501 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1507 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1508 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1509 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1510 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1511 size_t iMoth = cascadeVertices.size()-1;
1512 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1513 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut) {
1514 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1515 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1517 type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1519 else if(V0==LAMBDABAR) {
1520 type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1523 type_V1_decor(*cascadeVertices[0]) =
"Ks";
1525 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1526 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1527 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1528 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1529 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1530 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1531 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1532 trk_px.reserve(V0_helper.
nRefTrks());
1533 trk_py.reserve(V0_helper.
nRefTrks());
1534 trk_pz.reserve(V0_helper.
nRefTrks());
1535 for(
auto&& vec3 : V0_helper.
refTrks()) {
1536 trk_px.push_back( vec3.Px() );
1537 trk_py.push_back( vec3.Py() );
1538 trk_pz.push_back( vec3.Pz() );
1540 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1541 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1542 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1544 result.push_back( fit_result.release() );
1549 else if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo>0) {
1550 std::vector<const xAOD::TrackParticle*> tracksPlus;
1551 std::vector<const xAOD::TrackParticle*> tracksMinus;
1552 double minTrkPt = std::fmin(std::fmin(m_extraTrk1MinPt,m_extraTrk2MinPt),m_extraTrk3MinPt);
1554 if( tpExtra->pt() < minTrkPt )
continue;
1555 if( !m_trkSelector->decision(*tpExtra,
nullptr) )
continue;
1557 if(
std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend())
continue;
1558 if(
std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend())
continue;
1559 if(tpExtra->charge()>0) {
1560 tracksPlus.push_back(tpExtra);
1563 tracksMinus.push_back(tpExtra);
1569 TLorentzVector p4_ExtraTrk1, p4_ExtraTrk2, p4_ExtraTrk3;
1572 if( tp1->pt() < m_extraTrk1MinPt )
continue;
1573 for(
auto tp2Itr=tracksMinus.cbegin(); tp2Itr!=tracksMinus.cend(); ++tp2Itr) {
1575 for(
auto tp3Itr=tp2Itr+1; tp3Itr!=tracksMinus.cend(); ++tp3Itr) {
1577 if((tp2->
pt()>m_extraTrk2MinPt && tp3->
pt()>m_extraTrk3MinPt) ||
1578 (tp2->
pt()>m_extraTrk3MinPt && tp3->
pt()>m_extraTrk2MinPt)) {
1579 p4_ExtraTrk1.SetPtEtaPhiM(tp1->pt(), tp1->eta(), tp1->phi(), m_extraTrk1MassHypo);
1580 p4_ExtraTrk2.SetPtEtaPhiM(tp2->
pt(), tp2->
eta(), tp2->
phi(), m_extraTrk2MassHypo);
1581 p4_ExtraTrk3.SetPtEtaPhiM(tp3->
pt(), tp3->
eta(), tp3->
phi(), m_extraTrk3MassHypo);
1582 if((p4_moth+p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M() < m_MassLower || (p4_moth+p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M() > m_MassUpper)
continue;
1583 auto Dpm = getDpmCandidate(JXvtx,massesJX,tp1,tp2,tp3);
1584 if(Dpm.extraTrack1) DpmCandidates.
push_back(Dpm);
1585 auto Dstpm = getDstpmCandidate(JXvtx,massesJX,tp1,tp2,tp3);
1586 if(Dstpm.extraTrack1) DstpmCandidates.
push_back(Dstpm);
1593 if( tp1->pt() < m_extraTrk1MinPt )
continue;
1594 for(
auto tp2Itr=tracksPlus.cbegin(); tp2Itr!=tracksPlus.cend(); ++tp2Itr) {
1596 for(
auto tp3Itr=tp2Itr+1; tp3Itr!=tracksPlus.cend(); ++tp3Itr) {
1598 if((tp2->
pt()>m_extraTrk2MinPt && tp3->
pt()>m_extraTrk3MinPt) ||
1599 (tp2->
pt()>m_extraTrk3MinPt && tp3->
pt()>m_extraTrk2MinPt)) {
1600 p4_ExtraTrk1.SetPtEtaPhiM(tp1->pt(), tp1->eta(), tp1->phi(), m_extraTrk1MassHypo);
1601 p4_ExtraTrk2.SetPtEtaPhiM(tp2->
pt(), tp2->
eta(), tp2->
phi(), m_extraTrk2MassHypo);
1602 p4_ExtraTrk3.SetPtEtaPhiM(tp3->
pt(), tp3->
eta(), tp3->
phi(), m_extraTrk3MassHypo);
1603 if((p4_moth+p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M() < m_MassLower || (p4_moth+p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M() > m_MassUpper)
continue;
1604 auto Dpm = getDpmCandidate(JXvtx,massesJX,tp1,tp2,tp3);
1605 if(Dpm.extraTrack1) DpmCandidates.
push_back(Dpm);
1606 auto Dstpm = getDstpmCandidate(JXvtx,massesJX,tp1,tp2,tp3);
1607 if(Dstpm.extraTrack1) DstpmCandidates.
push_back(Dstpm);
1613 std::vector<double> massesExtra{m_extraTrk1MassHypo,m_extraTrk2MassHypo,m_extraTrk3MassHypo};
1615 for(
auto&& Dpm : DpmCandidates.
vector()) {
1616 std::vector<const xAOD::TrackParticle*> tracksExtra{Dpm.extraTrack1,Dpm.extraTrack2,Dpm.extraTrack3};
1619 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1622 m_iVertexFitter->setRobustness(robustness, *state);
1625 std::vector<Trk::VertexID> vrtList;
1630 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1632 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1634 vrtList.push_back(vID1);
1637 if (m_constrDpm && m_mass_Dpm>0) {
1638 vID2 = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state,m_mass_Dpm);
1640 vID2 = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state);
1642 vrtList.push_back(vID2);
1646 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massMainV);
1648 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
1650 if (m_constrJX && m_jxDaug_num>2) {
1651 std::vector<Trk::VertexID> cnstV;
1652 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1657 std::vector<Trk::VertexID> cnstV;
1658 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1662 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1663 std::vector<Trk::VertexID> cnstV;
1664 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1669 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1673 if(
v->nTrackParticles()==0) {
1674 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1675 v->setTrackParticleLinks(nullLinkVector);
1679 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1685 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1686 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1687 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1688 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1689 size_t iMoth = cascadeVertices.size()-1;
1690 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1691 double lxy_SV2 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
1692 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut && lxy_SV2>m_lxyDpm_cut) {
1693 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1694 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1696 type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1698 else if(V0==LAMBDABAR) {
1699 type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1702 type_V1_decor(*cascadeVertices[0]) =
"Ks";
1704 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1705 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1706 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1707 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1708 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1709 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1710 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1711 trk_px.reserve(V0_helper.
nRefTrks());
1712 trk_py.reserve(V0_helper.
nRefTrks());
1713 trk_pz.reserve(V0_helper.
nRefTrks());
1714 for(
auto&& vec3 : V0_helper.
refTrks()) {
1715 trk_px.push_back( vec3.Px() );
1716 trk_py.push_back( vec3.Py() );
1717 trk_pz.push_back( vec3.Pz() );
1719 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1720 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1721 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1723 result.push_back( fit_result.release() );
1728 std::vector<double> massesJXExtra = massesJX;
1729 massesJXExtra.push_back(m_extraTrk3MassHypo);
1730 std::vector<double> massesExtra12{m_extraTrk1MassHypo,m_extraTrk2MassHypo};
1732 for(
auto&& Dstpm : DstpmCandidates.
vector()) {
1733 std::vector<const xAOD::TrackParticle*> tracksExtra12{Dstpm.extraTrack1,Dstpm.extraTrack2};
1734 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX;
1735 tracksJXExtra.push_back(Dstpm.extraTrack3);
1738 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1741 m_iVertexFitter->setRobustness(robustness, *state);
1744 std::vector<Trk::VertexID> vrtList;
1749 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1751 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1753 vrtList.push_back(vID1);
1756 if (m_constrD0 && m_mass_D0>0) {
1757 vID2 = m_iVertexFitter->nextVertex(tracksExtra12,massesExtra12,*state,m_mass_D0);
1759 vID2 = m_iVertexFitter->nextVertex(tracksExtra12,massesExtra12,*state);
1761 vrtList.push_back(vID2);
1765 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state,m_massMainV);
1767 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state);
1769 if (m_constrJX && m_jxDaug_num>2) {
1770 std::vector<Trk::VertexID> cnstV;
1771 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1776 std::vector<Trk::VertexID> cnstV;
1777 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1781 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1782 std::vector<Trk::VertexID> cnstV;
1783 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1787 if (m_constrDstpm && m_mass_Dstpm>0) {
1788 std::vector<Trk::VertexID> cnstV{vID2};
1789 std::vector<const xAOD::TrackParticle*> tracksExtra3{Dstpm.extraTrack3};
1790 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksExtra3,cnstV,*state,m_mass_Dstpm).isSuccess() ) {
1795 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1799 if(
v->nTrackParticles()==0) {
1800 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1801 v->setTrackParticleLinks(nullLinkVector);
1805 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1811 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1812 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1813 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1814 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1815 size_t iMoth = cascadeVertices.size()-1;
1816 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1817 double lxy_SV2 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
1818 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut && lxy_SV2>m_lxyD0_cut) {
1819 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1820 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1822 type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1824 else if(V0==LAMBDABAR) {
1825 type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1828 type_V1_decor(*cascadeVertices[0]) =
"Ks";
1830 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1831 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1832 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1833 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1834 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1835 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1836 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1837 trk_px.reserve(V0_helper.
nRefTrks());
1838 trk_py.reserve(V0_helper.
nRefTrks());
1839 trk_pz.reserve(V0_helper.
nRefTrks());
1840 for(
auto&& vec3 : V0_helper.
refTrks()) {
1841 trk_px.push_back( vec3.Px() );
1842 trk_py.push_back( vec3.Py() );
1843 trk_pz.push_back( vec3.Pz() );
1845 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1846 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1847 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1849 result.push_back( fit_result.release() );
1858 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 {
1859 std::vector<Trk::VxCascadeInfo*>
result;
1861 std::vector<const xAOD::TrackParticle*> tracksJX;
1864 if (tracksJX.size() != massesJX.size()) {
1865 ATH_MSG_ERROR(
"Problems with JX input: number of tracks or track mass inputs is not correct!");
1871 std::vector<const xAOD::TrackParticle*> tracksV0;
1875 if(
std::find(tracksJX.cbegin(), tracksJX.cend(), disVtx.
track) != tracksJX.cend())
return result;
1876 std::vector<const xAOD::TrackParticle*> tracks3{disVtx.
track};
1877 std::vector<double> massesDis3{m_disVDaug3MassHypo};
1879 std::vector<const xAOD::TrackParticle*> tracksJpsi{tracksJX[0], tracksJX[1]};
1880 std::vector<const xAOD::TrackParticle*> tracksX;
1881 if(m_jxDaug_num>=3) tracksX.push_back(tracksJX[2]);
1882 if(m_jxDaug_num==4) tracksX.push_back(tracksJX[3]);
1884 std::vector<double> massesV0;
1885 if(disVtx.
V0type==LAMBDA) {
1886 massesV0 = m_massesV0_ppi;
1888 else if(disVtx.
V0type==LAMBDABAR) {
1889 massesV0 = m_massesV0_pip;
1891 else if(disVtx.
V0type==KS) {
1892 massesV0 = m_massesV0_pipi;
1895 std::vector<double> massesDisV = massesV0;
1896 massesDisV.push_back(m_disVDaug3MassHypo);
1898 TLorentzVector p4_moth,
tmp;
1929 std::vector<float> trk_px;
1930 std::vector<float> trk_py;
1931 std::vector<float> trk_pz;
1933 if(m_extraTrk1MassHypo<=0) {
1934 if (p4_moth.M() < m_MassLower || p4_moth.M() > m_MassUpper)
return result;
1937 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1940 m_iVertexFitter->setRobustness(robustness, *state);
1943 std::vector<Trk::VertexID> vrtList;
1944 std::vector<Trk::VertexID> vrtList2;
1949 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
1951 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1953 vrtList.push_back(vID1);
1957 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state,m_massDisV);
1959 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state);
1961 vrtList2.push_back(vID2);
1965 if (m_constrJX && m_jxDaug_num>2) {
1966 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state,m_massJX);
1968 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state);
1970 vrtList2.push_back(vID3);
1972 std::vector<const xAOD::TrackParticle*>
tp;
1973 std::vector<double> tp_masses;
1975 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList2,*state,m_massMainV);
1977 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList2,*state);
1983 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state,m_massMainV);
1985 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state);
1987 if (m_constrJX && m_jxDaug_num>2) {
1988 std::vector<Trk::VertexID> cnstV;
1989 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1995 std::vector<Trk::VertexID> cnstV;
1996 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
2000 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
2001 std::vector<Trk::VertexID> cnstV;
2002 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
2007 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
2011 if(
v->nTrackParticles()==0) {
2012 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
2013 v->setTrackParticleLinks(nullLinkVector);
2017 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
2023 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
2024 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
2026 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
2027 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
2028 size_t iMoth = cascadeVertices.size()-1;
2029 double lxy_SV1_sub = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
2030 double lxy_SV1 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
2032 if(chi2CutPassed && lxy_SV1>m_lxyDisV_cut && lxy_SV1_sub>m_lxyV0_cut) {
2035 if(disVtx.
V0type==LAMBDA) {
2036 type_V0_decor(*cascadeVertices[0]) =
"Lambda";
2038 else if(disVtx.
V0type==LAMBDABAR) {
2039 type_V0_decor(*cascadeVertices[0]) =
"Lambdabar";
2041 else if(disVtx.
V0type==KS) {
2042 type_V0_decor(*cascadeVertices[0]) =
"Ks";
2044 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*disVtx.
V0vtx) ? mAcc_gfit(*disVtx.
V0vtx) : 0;
2045 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*disVtx.
V0vtx) ? mAcc_gmass(*disVtx.
V0vtx) : -1;
2046 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*disVtx.
V0vtx) ? mAcc_gmasserr(*disVtx.
V0vtx) : -1;
2047 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*disVtx.
V0vtx) ? mAcc_gchisq(*disVtx.
V0vtx) : 999999;
2048 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*disVtx.
V0vtx) ? mAcc_gndof(*disVtx.
V0vtx) : 0;
2049 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*disVtx.
V0vtx) ? mAcc_gprob(*disVtx.
V0vtx) : -1;
2050 trk_px.clear(); trk_py.clear(); trk_pz.clear();
2054 trk_pxDeco(*cascadeVertices[0]) = trk_px;
2055 trk_pyDeco(*cascadeVertices[0]) = trk_py;
2056 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
2057 trk_px_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Px();
2058 trk_py_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Py();
2059 trk_pz_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Pz();
2061 result.push_back( fit_result.release() );
2066 std::vector<double> massesJXExtra = massesJX;
2067 massesJXExtra.push_back(m_extraTrk1MassHypo);
2070 if ( tpExtra->pt()<m_extraTrk1MinPt )
continue;
2071 if ( !m_trkSelector->decision(*tpExtra,
nullptr) )
continue;
2073 if(
std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend())
continue;
2074 if(
std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend())
continue;
2075 if(tpExtra == disVtx.
track)
continue;
2078 tmp.SetPtEtaPhiM(tpExtra->pt(),tpExtra->eta(),tpExtra->phi(),m_extraTrk1MassHypo);
2079 if ((p4_moth+
tmp).M() < m_MassLower || (p4_moth+
tmp).M() > m_MassUpper)
continue;
2081 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX;
2082 tracksJXExtra.push_back(tpExtra);
2085 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
2088 m_iVertexFitter->setRobustness(robustness, *state);
2091 std::vector<Trk::VertexID> vrtList;
2092 std::vector<Trk::VertexID> vrtList2;
2097 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,m_massV0);
2099 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
2101 vrtList.push_back(vID1);
2105 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state,m_massDisV);
2107 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state);
2109 vrtList2.push_back(vID2);
2113 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,*state);
2114 vrtList2.push_back(vID3);
2116 std::vector<const xAOD::TrackParticle*>
tp;
2117 std::vector<double> tp_masses;
2119 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList2,*state,m_massMainV);
2121 m_iVertexFitter->nextVertex(
tp,tp_masses,vrtList2,*state);
2127 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList2,*state,m_massMainV);
2129 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList2,*state);
2132 if (m_constrJX && m_jxDaug_num>2) {
2133 std::vector<Trk::VertexID> cnstV;
2134 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
2139 std::vector<Trk::VertexID> cnstV;
2140 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
2144 if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
2145 std::vector<Trk::VertexID> cnstV;
2146 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
2151 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
2155 if(
v->nTrackParticles()==0) {
2156 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
2157 v->setTrackParticleLinks(nullLinkVector);
2161 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
2167 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
2168 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
2170 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
2171 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
2172 size_t iMoth = cascadeVertices.size()-1;
2173 double lxy_SV1_sub = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
2174 double lxy_SV1 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
2176 if(chi2CutPassed && lxy_SV1>m_lxyDisV_cut && lxy_SV1_sub>m_lxyV0_cut) {
2179 if(disVtx.
V0type==LAMBDA) {
2180 type_V0_decor(*cascadeVertices[0]) =
"Lambda";
2182 else if(disVtx.
V0type==LAMBDABAR) {
2183 type_V0_decor(*cascadeVertices[0]) =
"Lambdabar";
2185 else if(disVtx.
V0type==KS) {
2186 type_V0_decor(*cascadeVertices[0]) =
"Ks";
2188 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*disVtx.
V0vtx) ? mAcc_gfit(*disVtx.
V0vtx) : 0;
2189 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*disVtx.
V0vtx) ? mAcc_gmass(*disVtx.
V0vtx) : -1;
2190 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*disVtx.
V0vtx) ? mAcc_gmasserr(*disVtx.
V0vtx) : -1;
2191 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*disVtx.
V0vtx) ? mAcc_gchisq(*disVtx.
V0vtx) : 999999;
2192 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*disVtx.
V0vtx) ? mAcc_gndof(*disVtx.
V0vtx) : 0;
2193 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*disVtx.
V0vtx) ? mAcc_gprob(*disVtx.
V0vtx) : -1;
2194 trk_px.clear(); trk_py.clear(); trk_pz.clear();
2198 trk_pxDeco(*cascadeVertices[0]) = trk_px;
2199 trk_pyDeco(*cascadeVertices[0]) = trk_py;
2200 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
2201 trk_px_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Px();
2202 trk_py_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Py();
2203 trk_pz_deco(*cascadeVertices[1]) = disVtx.
p4_disVtrack.Pz();
2205 result.push_back( fit_result.release() );
2214 void JpsiXPlusDisplaced::fitV0Container(
xAOD::VertexContainer* V0ContainerNew,
const std::vector<const xAOD::TrackParticle*>& selectedTracks,
const std::vector<const xAOD::TrackParticleContainer*>& trackCols)
const {
2215 const EventContext& ctx = Gaudi::Hive::currentContext();
2225 std::vector<const xAOD::TrackParticle*> posTracks;
2226 std::vector<const xAOD::TrackParticle*> negTracks;
2228 if(TP->charge()>0) posTracks.push_back(TP);
2229 else negTracks.push_back(TP);
2233 const Trk::Perigee& aPerigee1 = TP1->perigeeParameters();
2235 const Trk::Perigee& aPerigee2 = TP2->perigeeParameters();
2236 int sflag(0), errorcode(0);
2237 Amg::Vector3D startingPoint = m_vertexEstimator->getCirclesIntersectionPoint(&aPerigee1,&aPerigee2,sflag,errorcode);
2238 if (errorcode != 0) {startingPoint(0) = 0.0; startingPoint(1) = 0.0; startingPoint(2) = 0.0;}
2240 if (errorcode == 0 || errorcode == 5 || errorcode == 6 || errorcode == 8) {
2242 const Trk::TrackParameters* extrapolatedPerigee1 = m_extrapolator->extrapolate(ctx,TP1->perigeeParameters(), perigeeSurface).release();
2243 const Trk::TrackParameters* extrapolatedPerigee2 = m_extrapolator->extrapolate(ctx,TP2->perigeeParameters(), perigeeSurface).release();
2244 std::vector<std::unique_ptr<const Trk::TrackParameters> > cleanup;
2245 if(!extrapolatedPerigee1) extrapolatedPerigee1 = &TP1->perigeeParameters();
2246 else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee1));
2247 if(!extrapolatedPerigee2) extrapolatedPerigee2 = &TP2->perigeeParameters();
2248 else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee2));
2249 if(extrapolatedPerigee1 && extrapolatedPerigee2) {
2251 TLorentzVector v1; TLorentzVector
v2;
2253 v1.SetXYZM(extrapolatedPerigee1->
momentum().x(),extrapolatedPerigee1->
momentum().y(),extrapolatedPerigee1->
momentum().z(),m_mass_proton);
2254 v2.SetXYZM(extrapolatedPerigee2->
momentum().x(),extrapolatedPerigee2->
momentum().y(),extrapolatedPerigee2->
momentum().z(),m_mass_pion);
2255 if((v1+
v2).M()>900.0 && (v1+
v2).M()<1350.0) pass =
true;
2258 v1.SetXYZM(extrapolatedPerigee1->
momentum().x(),extrapolatedPerigee1->
momentum().y(),extrapolatedPerigee1->
momentum().z(),m_mass_pion);
2259 v2.SetXYZM(extrapolatedPerigee2->
momentum().x(),extrapolatedPerigee2->
momentum().y(),extrapolatedPerigee2->
momentum().z(),m_mass_proton);
2260 if((v1+
v2).M()>900.0 && (v1+
v2).M()<1350.0) pass =
true;
2263 v1.SetXYZM(extrapolatedPerigee1->
momentum().x(),extrapolatedPerigee1->
momentum().y(),extrapolatedPerigee1->
momentum().z(),m_mass_pion);
2264 v2.SetXYZM(extrapolatedPerigee2->
momentum().x(),extrapolatedPerigee2->
momentum().y(),extrapolatedPerigee2->
momentum().z(),m_mass_pion);
2265 if((v1+
v2).M()>300.0 && (v1+
v2).M()<700.0) pass =
true;
2268 std::vector<const xAOD::TrackParticle*> tracksV0;
2269 tracksV0.push_back(TP1); tracksV0.push_back(TP2);
2270 std::unique_ptr<xAOD::Vertex> V0vtx = std::unique_ptr<xAOD::Vertex>( m_iV0Fitter->fit(tracksV0, startingPoint) );
2273 if(chi2DOF>m_chi2cut_V0)
continue;
2275 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);
2276 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);
2277 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);
2278 if(massSig_V0_Lambda1<=massSig_V0_Lambda2 && massSig_V0_Lambda1<=massSig_V0_Ks) {
2279 mDec_type(*V0vtx.get()) =
"Lambda";
2281 else if(massSig_V0_Lambda2<=massSig_V0_Lambda1 && massSig_V0_Lambda2<=massSig_V0_Ks) {
2282 mDec_type(*V0vtx.get()) =
"Lambdabar";
2284 else if(massSig_V0_Ks<=massSig_V0_Lambda1 && massSig_V0_Ks<=massSig_V0_Lambda2) {
2285 mDec_type(*V0vtx.get()) =
"Ks";
2288 int gamma_fit = 0;
int gamma_ndof = 0;
double gamma_chisq = 999999.;
2289 double gamma_prob = -1., gamma_mass = -1., gamma_massErr = -1.;
2290 std::unique_ptr<xAOD::Vertex> gammaVtx = std::unique_ptr<xAOD::Vertex>( m_iGammaFitter->fit(tracksV0, m_V0Tools->vtx(V0vtx.get())) );
2293 gamma_mass = m_V0Tools->invariantMass(gammaVtx.get(),m_mass_e,m_mass_e);
2294 gamma_massErr = m_V0Tools->invariantMassError(gammaVtx.get(),m_mass_e,m_mass_e);
2295 gamma_chisq = m_V0Tools->chisq(gammaVtx.get());
2296 gamma_ndof = m_V0Tools->ndof(gammaVtx.get());
2297 gamma_prob = m_V0Tools->vertexProbability(gammaVtx.get());
2299 mDec_gfit(*V0vtx.get()) = gamma_fit;
2300 mDec_gmass(*V0vtx.get()) = gamma_mass;
2301 mDec_gmasserr(*V0vtx.get()) = gamma_massErr;
2302 mDec_gchisq(*V0vtx.get()) = gamma_chisq;
2303 mDec_gndof(*V0vtx.get()) = gamma_ndof;
2304 mDec_gprob(*V0vtx.get()) = gamma_prob;
2309 if(not trackCols.empty()){
2311 JpsiUpsilonCommon::RelinkVertexTracks(trackCols, V0vtx.get());
2312 }
catch (std::runtime_error
const&
e) {
2318 V0ContainerNew->
push_back(std::move(V0vtx));
2327 template<
size_t NTracks>
2330 assert(v1->nTrackParticles() == NTracks);
2331 std::array<const xAOD::TrackParticle*, NTracks> a1;
2332 std::array<const xAOD::TrackParticle*, NTracks> a2;
2333 for(
size_t i=0;
i<NTracks;
i++){
2334 a1[
i] = v1->trackParticle(
i);
2335 a2[
i] =
v->trackParticle(
i);
2337 std::sort(a1.begin(), a1.end());
2338 std::sort(a2.begin(), a2.end());
2339 if(a1 == a2)
return v1;