143 {
145
146
149 if(!jpsiCollectionhandle.isValid()){
151 return StatusCode::FAILURE;
152 }else{
153 importedJpsiCollection = jpsiCollectionhandle.cptr();
155 }
156 ATH_MSG_DEBUG(
"VxCandidate container size " << importedJpsiCollection->size());
157
158
161 if(!TrkParticleHandle.isValid()){
163 return StatusCode::FAILURE;
164 } else {
165 importedTrackCollection = TrkParticleHandle.cptr();
167 }
169
174 importedGSFTrackCollection =
h.cptr();
175 }
176
177
178
184 return StatusCode::FAILURE;
185 } else {
186 importedMuonCollection =
h.cptr();
188 }
189 ATH_MSG_DEBUG(
"Muon container size "<< importedMuonCollection->size());
190 }
191
192
198 return StatusCode::FAILURE;
199 } else {
200 importedElectronCollection =
h.cptr();
202 }
204 }
205
206
207
208 typedef std::vector<const xAOD::TrackParticle*>
TrackBag;
209 typedef std::vector<const xAOD::Electron*> ElectronBag;
210
211
214 for (
auto trkPBItr=importedTrackCollection->
cbegin(); trkPBItr!=importedTrackCollection->
cend(); ++trkPBItr) {
220 }
221 if (
m_trkSelector->decision(*tp, vx) ) theIDTracksAfterSelection.push_back(tp);
222 }
223
224
226 ATH_MSG_DEBUG(
"importedTrackCollection contains GSF tracks " << importedGSFTrackCollection->size());
227 for (auto trkPBItr=importedGSFTrackCollection->cbegin(); trkPBItr!=importedGSFTrackCollection->cend(); ++trkPBItr) {
233 }
234 if (
m_trkSelector->decision(*tp, vx)) theIDTracksAfterSelection.push_back(tp);
235 }
236 }
237 if (theIDTracksAfterSelection.empty()) return StatusCode::SUCCESS;
238 ATH_MSG_DEBUG(
"Number of tracks after ID trkSelector: " << theIDTracksAfterSelection.size());
239
240
241 std::vector<const xAOD::Vertex*> selectedJpsiCandidates;
242 std::vector<const xAOD::TrackParticle*> jpsiTracks;
243 for(auto vxcItr=importedJpsiCollection->cbegin(); vxcItr!=importedJpsiCollection->cend(); ++vxcItr) {
244
246 xAOD::BPhysHelper jpsiCandidate(*vxcItr);
247 double jpsiMass = jpsiCandidate.totalP(
m_muonMasses).M();
249 if (!pass) continue;
250 }
251 selectedJpsiCandidates.push_back(*vxcItr);
252
253
255
258 jpsiTracks.push_back(jpsiTP1);
259 jpsiTracks.push_back(jpsiTP2);
260 }
261 }
262
263
264 std::vector<double> massHypotheses;
268 massHypotheses.push_back(
kMass); massHypotheses.push_back(
piMass);
269 }
271
272
273
274 std::vector<double> massCuts;
275
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);
284 }
285 }
286
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);
297 }
298 if (
m_skipNoElectron && theElectronsAfterSelection.size() == 0)
return StatusCode::SUCCESS;
299 ATH_MSG_DEBUG(
"Number of electrons after selection: " << theElectronsAfterSelection.size());
300 }
301
302 std::vector<const xAOD::TrackParticle*> tracks(3, nullptr);
303
304 for(auto jpsiItr=selectedJpsiCandidates.cbegin(); jpsiItr!=selectedJpsiCandidates.cend(); ++jpsiItr) {
305
306
307
310
311
313 jpsiTracks.resize(2);
314 jpsiTracks[0] = jpsiTP1;
315 jpsiTracks[1] = jpsiTP2;
316 }
317
318
319 for (auto trkItr=theIDTracksAfterSelection.cbegin(); trkItr!=theIDTracksAfterSelection.cend(); ++trkItr) {
322 return StatusCode::SUCCESS;
323 }
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!");
331 continue;
332
333 }
334 }
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!");
341 continue;
342 }
345 continue;
346 }
347 }
348
349
351
354 fabs(theThirdTP->
z0() + theThirdTP->
vz() - (*jpsiItr)->z()) >
m_trkDeltaZ )
355 continue;
358 continue;
359 }
360
361
362 bool passRoughMassCuts(true);
363
365 massCuts.clear();
369 }
370 if (!passRoughMassCuts) continue;
371
372
373
374 std::unique_ptr<xAOD::Vertex> bVertex(
fit(tracks, importedTrackCollection, importedGSFTrackCollection));
375 if (bVertex) {
376
377
378 double bChi2DOF = bVertex->chiSquared()/bVertex->numberDoF();
380
382 if(!chi2CutPassed) {
ATH_MSG_DEBUG(
"Chi Cut failed!");
continue; }
383
384
385 xAOD::BPhysHelper bHelper(bVertex.get());
386
387 bHelper.setRefTrks();
388
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; }
402 }
403 }
404 if (masspTpassed) {
405
406 std::vector<const xAOD::Vertex*> theJpsiPreceding;
407 theJpsiPreceding.push_back(*jpsiItr);
408 bHelper.setPrecedingVertices(theJpsiPreceding, importedJpsiCollection);
410 } else {
412 }
414
415 }
416
417 }
419 return StatusCode::SUCCESS;
420
421 }
#define ATH_MSG_WARNING(x)
xAOD::Vertex * fit(const std::vector< const xAOD::TrackParticle * > &, const xAOD::TrackParticleContainer *, const xAOD::TrackParticleContainer *) const
static double getInvariantMass(const std::vector< const xAOD::TrackParticle * > &trk, double mass1, double mass2, double mass3)
static bool cutRange(double value, double min, double max)
static bool isContainedIn(const xAOD::TrackParticle *, const std::vector< const xAOD::TrackParticle * > &)
static bool cutRangeOR(const std::vector< double > &values, double min, double max)
static double getPt(const xAOD::TrackParticle *, const xAOD::TrackParticle *)
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const_iterator cbegin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
const_iterator cend() const noexcept
Return a const_iterator pointing past the end of the collection.
bool empty() const noexcept
Returns true if the collection is empty.
float z0() const
Returns the parameter.
float vz() const
The z origin for the parameters.
std::vector< const xAOD::TrackParticle * > TrackBag
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".