14 #include "HepPDT/ParticleDataTable.hh"
59 return StatusCode::SUCCESS;
64 ATH_MSG_FATAL(
"Incorrect number of Psi daughters (should be 3 or 4)");
65 return StatusCode::FAILURE;
68 constexpr
int topoN = 3;
71 return StatusCode::FAILURE;
73 std::array<SG::WriteHandle<xAOD::VertexContainer>, topoN> VtxWriteHandles;
int ikey(0);
76 ATH_CHECK( VtxWriteHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
87 return StatusCode::RECOVERABLE;
96 ATH_CHECK( refPvContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
99 std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer;
100 std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer_noConstr;
145 for(
size_t ic=0;
ic<cascadeinfoContainer.size();
ic++) {
147 if(cascade_info==
nullptr) {
154 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->
vertices();
155 if(cascadeVertices.size() != topoN)
ATH_MSG_ERROR(
"Incorrect number of vertices");
156 if(cascadeVertices[0]==
nullptr || cascadeVertices[1]==
nullptr || cascadeVertices[2]==
nullptr)
ATH_MSG_ERROR(
"Error null vertex");
158 for(
int i=0;
i<topoN;
i++) VtxWriteHandles[
i].
ptr()->push_back(cascadeVertices[
i]);
161 const auto mainVertex = cascadeVertices[2];
162 const std::vector< std::vector<TLorentzVector> > &moms = cascade_info->
getParticleMoms();
165 std::vector<VertexLink> precedingVertexLinks;
169 if( vertexLink1.
isValid() ) precedingVertexLinks.push_back( vertexLink1 );
173 if( vertexLink2.
isValid() ) precedingVertexLinks.push_back( vertexLink2 );
174 CascadeLinksDecor(*mainVertex) = precedingVertexLinks;
177 const xAOD::Vertex* jpsiVertex = BPhysPVCascadeTools::FindVertex<2>(jpsiContainer.
cptr(), cascadeVertices[1]);
180 if(
m_vtx1Daug_num==4) psiVertex = BPhysPVCascadeTools::FindVertex<4>(psiContainer.
cptr(), cascadeVertices[0]);
181 else psiVertex = BPhysPVCascadeTools::FindVertex<3>(psiContainer.
cptr(), cascadeVertices[0]);
184 std::vector<const xAOD::Vertex*> jpsiVerticestoLink;
185 if(jpsiVertex) jpsiVerticestoLink.push_back(jpsiVertex);
189 std::vector<const xAOD::Vertex*> psiVerticestoLink;
190 if(psiVertex) psiVerticestoLink.push_back(psiVertex);
211 chi2_decor(*mainVertex) = cascade_info->
fitChi2();
212 ndof_decor(*mainVertex) = cascade_info->
nDoF();
213 chi2_nc_decor(*mainVertex) = cascade_info_noConstr ? cascade_info_noConstr->
fitChi2() : -999999.;
214 ndof_nc_decor(*mainVertex) = cascade_info_noConstr ? cascade_info_noConstr->
nDoF() : -1;
217 chi2_SV1_decor(*cascadeVertices[0]) =
m_V0Tools->chisq(cascadeVertices[0]);
218 chi2_nc_SV1_decor(*cascadeVertices[0]) = cascade_info_noConstr ?
m_V0Tools->chisq(cascade_info_noConstr->
vertices()[0]) : -999999.;
219 chi2_V1_decor(*cascadeVertices[0]) =
m_V0Tools->chisq(psiVertex);
220 ndof_V1_decor(*cascadeVertices[0]) =
m_V0Tools->ndof(psiVertex);
221 lxy_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
222 lxyErr_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->lxyError(moms[0],cascade_info->
getCovariance()[0],cascadeVertices[0],mainVertex);
223 a0z_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
224 a0zErr_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->a0zError(moms[0],cascade_info->
getCovariance()[0],cascadeVertices[0],mainVertex);
225 a0xy_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
226 a0xyErr_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->a0xyError(moms[0],cascade_info->
getCovariance()[0],cascadeVertices[0],mainVertex);
229 chi2_SV2_decor(*cascadeVertices[1]) =
m_V0Tools->chisq(cascadeVertices[1]);
230 chi2_nc_SV2_decor(*cascadeVertices[1]) = cascade_info_noConstr ?
m_V0Tools->chisq(cascade_info_noConstr->
vertices()[1]) : -999999.;
231 chi2_V2_decor(*cascadeVertices[1]) =
m_V0Tools->chisq(jpsiVertex);
232 ndof_V2_decor(*cascadeVertices[1]) =
m_V0Tools->ndof(jpsiVertex);
233 lxy_SV2_decor(*cascadeVertices[1]) =
m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
234 lxyErr_SV2_decor(*cascadeVertices[1]) =
m_CascadeTools->lxyError(moms[1],cascade_info->
getCovariance()[1],cascadeVertices[1],mainVertex);
235 a0z_SV2_decor(*cascadeVertices[1]) =
m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
236 a0zErr_SV2_decor(*cascadeVertices[1]) =
m_CascadeTools->a0zError(moms[1],cascade_info->
getCovariance()[1],cascadeVertices[1],mainVertex);
237 a0xy_SV2_decor(*cascadeVertices[1]) =
m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
238 a0xyErr_SV2_decor(*cascadeVertices[1]) =
m_CascadeTools->a0xyError(moms[1],cascade_info->
getCovariance()[1],cascadeVertices[1],mainVertex);
246 for (
auto cascade_info : cascadeinfoContainer)
delete cascade_info;
247 for (
auto cascade_info_noConstr : cascadeinfoContainer_noConstr)
delete cascade_info_noConstr;
249 return StatusCode::SUCCESS;
253 m_vertexContainerKey(
""),
254 m_vertexPsiContainerKey(
""),
255 m_cascadeOutputsKeys({
"JpsiPlusPsiCascadeVtx1",
"JpsiPlusPsiCascadeVtx2",
"JpsiPlusPsiCascadeVtx3"}),
256 m_VxPrimaryCandidateName(
"PrimaryVertices"),
257 m_trackContainerName(
"InDetTrackParticles"),
258 m_eventInfo_key(
"EventInfo"),
259 m_jpsiMassLower(0.0),
260 m_jpsiMassUpper(20000.0),
261 m_diTrackMassLower(-1.0),
262 m_diTrackMassUpper(-1.0),
264 m_psiMassUpper(25000.0),
265 m_jpsi2MassLower(0.0),
266 m_jpsi2MassUpper(20000.0),
268 m_MassUpper(31000.0),
270 m_vtx1Daug1MassHypo(-1),
271 m_vtx1Daug2MassHypo(-1),
272 m_vtx1Daug3MassHypo(-1),
273 m_vtx1Daug4MassHypo(-1),
274 m_vtx2Daug1MassHypo(-1),
275 m_vtx2Daug2MassHypo(-1),
282 m_constrDiTrk(
false),
283 m_constrJpsi2(
false),
285 m_chi2cut_Jpsi(-1.0),
288 m_iVertexFitter(
"Trk::TrkVKalVrtFitter"),
289 m_pvRefitter(
"Analysis::PrimaryVertexRefitter",
this),
290 m_V0Tools(
"Trk::V0Tools"),
291 m_CascadeTools(
"DerivationFramework::CascadeTools")
293 declareProperty(
"JpsiVertices", m_vertexContainerKey);
294 declareProperty(
"PsiVertices", m_vertexPsiContainerKey);
295 declareProperty(
"JpsiVtxHypoNames", m_vertexJpsiHypoNames);
296 declareProperty(
"PsiVtxHypoNames", m_vertexPsiHypoNames);
297 declareProperty(
"VxPrimaryCandidateName", m_VxPrimaryCandidateName);
298 declareProperty(
"TrackContainerName", m_trackContainerName);
299 declareProperty(
"RefPVContainerName", m_refPVContainerName =
"RefittedPrimaryVertices");
300 declareProperty(
"JpsiMassLowerCut", m_jpsiMassLower);
301 declareProperty(
"JpsiMassUpperCut", m_jpsiMassUpper);
302 declareProperty(
"DiTrackMassLower", m_diTrackMassLower);
303 declareProperty(
"DiTrackMassUpper", m_diTrackMassUpper);
304 declareProperty(
"PsiMassLowerCut", m_psiMassLower);
305 declareProperty(
"PsiMassUpperCut", m_psiMassUpper);
306 declareProperty(
"Jpsi2MassLowerCut", m_jpsi2MassLower);
307 declareProperty(
"Jpsi2MassUpperCut", m_jpsi2MassUpper);
308 declareProperty(
"MassLowerCut", m_MassLower);
309 declareProperty(
"MassUpperCut", m_MassUpper);
310 declareProperty(
"HypothesisName", m_hypoName =
"TQ");
311 declareProperty(
"NumberOfPsiDaughters", m_vtx1Daug_num);
312 declareProperty(
"Vtx1Daug1MassHypo", m_vtx1Daug1MassHypo);
313 declareProperty(
"Vtx1Daug2MassHypo", m_vtx1Daug2MassHypo);
314 declareProperty(
"Vtx1Daug3MassHypo", m_vtx1Daug3MassHypo);
315 declareProperty(
"Vtx1Daug4MassHypo", m_vtx1Daug4MassHypo);
316 declareProperty(
"Vtx2Daug1MassHypo", m_vtx2Daug1MassHypo);
317 declareProperty(
"Vtx2Daug2MassHypo", m_vtx2Daug2MassHypo);
318 declareProperty(
"JpsiMass", m_mass_jpsi);
319 declareProperty(
"DiTrackMass", m_mass_diTrk);
320 declareProperty(
"PsiMass", m_mass_psi);
321 declareProperty(
"Jpsi2Mass", m_mass_jpsi2);
322 declareProperty(
"ApplyJpsiMassConstraint", m_constrJpsi);
323 declareProperty(
"ApplyDiTrackMassConstraint", m_constrDiTrk);
324 declareProperty(
"ApplyPsiMassConstraint", m_constrPsi);
325 declareProperty(
"ApplyJpsi2MassConstraint", m_constrJpsi2);
326 declareProperty(
"Chi2CutPsi", m_chi2cut_Psi);
327 declareProperty(
"Chi2CutJpsi", m_chi2cut_Jpsi);
328 declareProperty(
"Chi2Cut", m_chi2cut);
329 declareProperty(
"MaxCandidates", m_maxCandidates);
330 declareProperty(
"RefitPV", m_refitPV =
true);
331 declareProperty(
"MaxnPV", m_PV_max = 1000);
332 declareProperty(
"MinNTracksInPV", m_PV_minNTracks = 0);
333 declareProperty(
"DoVertexType", m_DoVertexType = 7);
334 declareProperty(
"TrkVertexFitterTool", m_iVertexFitter);
335 declareProperty(
"PVRefitter", m_pvRefitter);
336 declareProperty(
"V0Tools", m_V0Tools);
337 declareProperty(
"CascadeTools", m_CascadeTools);
338 declareProperty(
"CascadeVertexCollections", m_cascadeOutputsKeys);
343 assert(cascadeinfoContainer!=
nullptr && cascadeinfoContainer_noConstr!=
nullptr);
349 std::vector<const xAOD::TrackParticle*> tracksJpsi;
350 std::vector<const xAOD::TrackParticle*> tracksDiTrk;
351 std::vector<const xAOD::TrackParticle*> tracksPsi;
352 std::vector<const xAOD::TrackParticle*> tracksJpsi2;
353 std::vector<double> massesPsi;
369 std::vector<const xAOD::Vertex*> selectedJpsiCandidates;
370 for(
auto vxcItr=jpsiContainer.
cptr()->
cbegin(); vxcItr!=jpsiContainer.
cptr()->
cend(); ++vxcItr) {
383 double mass_jpsi2 =
m_V0Tools->invariantMass(*vxcItr, massesJpsi2);
384 if (mass_jpsi2 < m_jpsi2MassLower || mass_jpsi2 >
m_jpsi2MassUpper)
continue;
386 double chi2DOF = (*vxcItr)->chiSquared()/(*vxcItr)->numberDoF();
389 selectedJpsiCandidates.push_back(*vxcItr);
391 if(selectedJpsiCandidates.size()==0)
return StatusCode::SUCCESS;
394 std::vector<const xAOD::Vertex*> selectedPsiCandidates;
395 for(
auto vxcItr=psiContainer.
cptr()->
cbegin(); vxcItr!=psiContainer.
cptr()->
cend(); ++vxcItr) {
408 double mass_psi =
m_V0Tools->invariantMass(*vxcItr,massesPsi);
409 if(mass_psi < m_psiMassLower || mass_psi >
m_psiMassUpper)
continue;
412 TLorentzVector p4_mu1, p4_mu2;
413 p4_mu1.SetPtEtaPhiM( (*vxcItr)->trackParticle(0)->pt(),
414 (*vxcItr)->trackParticle(0)->eta(),
416 p4_mu2.SetPtEtaPhiM( (*vxcItr)->trackParticle(1)->pt(),
417 (*vxcItr)->trackParticle(1)->eta(),
419 double mass_jpsi = (p4_mu1 + p4_mu2).M();
420 if (mass_jpsi < m_jpsiMassLower || mass_jpsi >
m_jpsiMassUpper)
continue;
423 TLorentzVector p4_trk1, p4_trk2;
424 p4_trk1.SetPtEtaPhiM( (*vxcItr)->trackParticle(2)->pt(),
425 (*vxcItr)->trackParticle(2)->eta(),
427 p4_trk2.SetPtEtaPhiM( (*vxcItr)->trackParticle(3)->pt(),
428 (*vxcItr)->trackParticle(3)->eta(),
430 double mass_diTrk = (p4_trk1 + p4_trk2).M();
434 double chi2DOF = (*vxcItr)->chiSquared()/(*vxcItr)->numberDoF();
437 selectedPsiCandidates.push_back(*vxcItr);
439 if(selectedPsiCandidates.size()==0)
return StatusCode::SUCCESS;
441 std::vector<std::pair<const xAOD::Vertex*, const xAOD::Vertex*> > candidatePairs;
442 for(
auto jpsiItr=selectedJpsiCandidates.cbegin(); jpsiItr!=selectedJpsiCandidates.cend(); ++jpsiItr) {
444 for(
size_t i=0;
i<(*jpsiItr)->nTrackParticles();
i++) tracksJpsi2.push_back((*jpsiItr)->trackParticle(
i));
445 for(
auto psiItr=selectedPsiCandidates.cbegin(); psiItr!=selectedPsiCandidates.cend(); ++psiItr) {
447 for(
size_t j=0; j<(*psiItr)->nTrackParticles(); j++) {
448 if(
std::find(tracksJpsi2.cbegin(), tracksJpsi2.cend(), (*psiItr)->trackParticle(j)) != tracksJpsi2.cend()) {
skip =
true;
break; }
451 candidatePairs.push_back(std::pair<const xAOD::Vertex*, const xAOD::Vertex*>(*jpsiItr,*psiItr));
455 std::sort( candidatePairs.begin(), candidatePairs.end(), [](std::pair<const xAOD::Vertex*, const xAOD::Vertex*>
a, std::pair<const xAOD::Vertex*, const xAOD::Vertex*>
b) { return a.first->chiSquared()/a.first->numberDoF()+a.second->chiSquared()/a.second->numberDoF() < b.first->chiSquared()/b.first->numberDoF()+b.second->chiSquared()/b.second->numberDoF(); } );
457 candidatePairs.erase(candidatePairs.begin()+
m_maxCandidates, candidatePairs.end());
460 for(
size_t ic=0;
ic<candidatePairs.size();
ic++) {
466 if (tracksJpsi2.size() != 2 || massesJpsi2.size() != 2) {
467 ATH_MSG_ERROR(
"Problems with Jpsi input: number of tracks or track mass inputs is not 2!");
471 if (tracksPsi.size() != massesPsi.size()) {
472 ATH_MSG_ERROR(
"Problems with Psi input: number of tracks or track mass inputs is not correct!");
484 TLorentzVector p4_moth;
503 std::vector<Trk::VertexID> vrtList;
512 vrtList.push_back(vID1);
520 vrtList.push_back(vID2);
522 std::vector<const xAOD::TrackParticle*>
tp;
tp.clear();
523 std::vector<double> tp_masses; tp_masses.clear();
526 std::vector<Trk::VertexID> cnstV; cnstV.clear();
532 std::vector<Trk::VertexID> cnstV; cnstV.clear();
542 for(
auto v :
result->vertices()) {
543 if(
v->nTrackParticles()==0) {
544 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
545 v->setTrackParticleLinks(nullLinkVector);
552 result->setSVOwnership(
true);
559 cascadeinfoContainer->push_back(
result.release());
569 std::vector<Trk::VertexID> vrtList_nc;
572 vrtList_nc.push_back(vID1_nc);
574 vrtList_nc.push_back(vID2_nc);
576 std::vector<const xAOD::TrackParticle*>
tp;
tp.clear();
577 std::vector<double> tp_masses; tp_masses.clear();
580 std::unique_ptr<Trk::VxCascadeInfo> result_nc(
m_iVertexFitter->fitCascade(*state));
582 if (result_nc !=
nullptr) {
584 if(
v->nTrackParticles()==0) {
585 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
586 v->setTrackParticleLinks(nullLinkVector);
594 cascadeinfoContainer_noConstr->push_back(result_nc.release());
596 else cascadeinfoContainer_noConstr->push_back(0);
598 else cascadeinfoContainer_noConstr->push_back(0);
602 return StatusCode::SUCCESS;