21 #include "AthLinks/ElementLink.h"
57 return StatusCode::FAILURE;
68 return StatusCode::SUCCESS;
76 m_trkThresholdPt(0.0),
81 m_jpsiCollectionKey(
"JpsiCandidates"),
84 m_TrkParticleCollection(
"TrackParticleCandidate"),
85 m_MuonsUsedInJpsi(
""),
86 m_excludeJpsiMuonsOnly(true),
87 m_excludeCrossJpsiTracks(false),
88 m_iVertexFitter(
"Trk::TrkVKalVrtFitter"),
89 m_trkSelector(
"InDet::TrackSelectorTool"),
93 m_trkTrippletMassUpper(-1.0),
94 m_trkTrippletMassLower(-1.0),
95 m_trkTrippletPt(-1.0),
97 m_TrkParticleGSFCollection(
""),
98 m_electronCollectionKey(
""),
99 m_candidateLimit(std::numeric_limits<size_t>::
max())
101 declareInterface<JpsiPlus1Track>(
this);
149 if(!jpsiCollectionhandle.
isValid()){
151 return StatusCode::FAILURE;
153 importedJpsiCollection = jpsiCollectionhandle.
cptr();
161 if(!TrkParticleHandle.
isValid()){
163 return StatusCode::FAILURE;
165 importedTrackCollection = TrkParticleHandle.
cptr();
168 ATH_MSG_DEBUG(
"Track container size "<< importedTrackCollection->size());
174 importedGSFTrackCollection =
h.cptr();
184 return StatusCode::FAILURE;
186 importedMuonCollection =
h.cptr();
198 return StatusCode::FAILURE;
200 importedElectronCollection =
h.cptr();
208 typedef std::vector<const xAOD::TrackParticle*>
TrackBag;
209 typedef std::vector<const xAOD::Electron*> ElectronBag;
214 for (
auto trkPBItr=importedTrackCollection->cbegin(); trkPBItr!=importedTrackCollection->cend(); ++trkPBItr) {
226 ATH_MSG_DEBUG(
"importedTrackCollection contains GSF tracks " << importedGSFTrackCollection->
size());
227 for (
auto trkPBItr=importedGSFTrackCollection->
cbegin(); trkPBItr!=importedGSFTrackCollection->
cend(); ++trkPBItr) {
237 if (theIDTracksAfterSelection.empty())
return StatusCode::SUCCESS;
238 ATH_MSG_DEBUG(
"Number of tracks after ID trkSelector: " << theIDTracksAfterSelection.size());
241 std::vector<const xAOD::Vertex*> selectedJpsiCandidates;
242 std::vector<const xAOD::TrackParticle*> jpsiTracks;
243 for(
auto vxcItr=importedJpsiCollection->
cbegin(); vxcItr!=importedJpsiCollection->
cend(); ++vxcItr) {
251 selectedJpsiCandidates.push_back(*vxcItr);
258 jpsiTracks.push_back(jpsiTP1);
259 jpsiTracks.push_back(jpsiTP2);
264 std::vector<double> massHypotheses;
268 massHypotheses.push_back(
kMass); massHypotheses.push_back(
piMass);
274 std::vector<double> massCuts;
278 for(
auto muon : *importedMuonCollection){
279 if(!
muon->inDetTrackParticleLink().isValid())
continue;
280 auto track =
muon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
281 if(
track==
nullptr)
continue;
283 muonTracks.push_back(
track);
288 ElectronBag theElectronsAfterSelection;
289 if (importedElectronCollection && !importedElectronCollection->
empty()) {
290 for(
auto electron : *importedElectronCollection) {
291 if (!
electron->trackParticleLink().isValid())
continue;
293 elTrk =
electron->trackParticleLink().cachedElement();
294 if (!elTrk)
continue;
295 theElectronsAfterSelection.push_back(
electron);
296 electronTracks.push_back(elTrk);
298 if (
m_skipNoElectron && theElectronsAfterSelection.size() == 0)
return StatusCode::SUCCESS;
299 ATH_MSG_DEBUG(
"Number of electrons after selection: " << theElectronsAfterSelection.size());
302 std::vector<const xAOD::TrackParticle*> tracks(3,
nullptr);
304 for(
auto jpsiItr=selectedJpsiCandidates.cbegin(); jpsiItr!=selectedJpsiCandidates.cend(); ++jpsiItr) {
313 jpsiTracks.resize(2);
314 jpsiTracks[0] = jpsiTP1;
315 jpsiTracks[1] = jpsiTP2;
319 for (
auto trkItr=theIDTracksAfterSelection.cbegin(); trkItr!=theIDTracksAfterSelection.cend(); ++trkItr) {
322 return StatusCode::SUCCESS;
325 int linkedMuonTrk = 0;
328 if (linkedMuonTrk)
ATH_MSG_DEBUG(
"This id track is a muon track!");
330 if (linkedMuonTrk)
ATH_MSG_DEBUG(
"ID track removed: id track is slected to build Jpsi!");
336 int linkedElectronTrk = 0;
338 if (linkedElectronTrk)
ATH_MSG_DEBUG(
"This id track is an electron track!");
340 if (linkedElectronTrk)
ATH_MSG_DEBUG(
"ID track removed: id track is selected to build Jpsi!");
354 fabs(theThirdTP->
z0() + theThirdTP->
vz() - (*jpsiItr)->z()) >
m_trkDeltaZ )
362 bool passRoughMassCuts(
true);
370 if (!passRoughMassCuts)
continue;
374 std::unique_ptr<xAOD::Vertex> bVertex(
fit(tracks, importedTrackCollection, importedGSFTrackCollection));
382 if(!chi2CutPassed) {
ATH_MSG_DEBUG(
"Chi Cut failed!");
continue; }
389 bool masspTpassed =
true;
391 masspTpassed =
false;
392 for (
double masshypo3rd : massHypotheses) {
393 tripletMasses.push_back(masshypo3rd);
394 TLorentzVector bMomentum = bHelper.
totalP(tripletMasses);
395 tripletMasses.pop_back();
396 double bpt = bMomentum.Pt();
398 double bMass = bMomentum.M();
399 ATH_MSG_DEBUG(
"candidate pt/mass under track mass hypothesis of " << masshypo3rd <<
" is " << bpt <<
" / " << bMass);
401 if(masscut && PtPassed) { masspTpassed =
true;
break; }
406 std::vector<const xAOD::Vertex*> theJpsiPreceding;
407 theJpsiPreceding.push_back(*jpsiItr);
419 return StatusCode::SUCCESS;
441 std::array<int,2>
indices = {1, 2};
456 std::vector<ElementLink<DataVector<xAOD::TrackParticle> > > newLinkVector;
461 newLinkVector.push_back( mylink );
475 double mass2,
double mass3)
477 const auto trk1V = trk[0]->p4();
478 double px1 = trk1V.Px();
479 double py1 = trk1V.Py();
480 double pz1 = trk1V.Pz();
481 double e1 = sqrt(px1*px1+py1*py1+pz1*pz1+mass1*mass1);
483 const auto trk2V = trk[1]->p4();
484 double px2 = trk2V.Px();
485 double py2 = trk2V.Py();
486 double pz2 = trk2V.Pz();
487 double e2 = sqrt(px2*px2+py2*py2+pz2*pz2+mass2*mass2);
489 const auto trk3V = trk[2]->p4();
490 double px3 = trk3V.Px();
491 double py3 = trk3V.Py();
492 double pz3 = trk3V.Pz();
493 double e3 = sqrt(px3*px3+py3*py3+pz3*pz3+mass3*mass3);
496 double pxSum=px1+px2+px3;
497 double pySum=py1+py2+py3;
498 double pzSum=pz1+pz2+pz3;
501 double M=sqrt((eSum*eSum)-(pxSum*pxSum)-(pySum*pySum)-(pzSum*pzSum));