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 auto track =
muon->trackParticle( xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
280 if(track==nullptr) continue;
282 muonTracks.push_back(track);
283 }
284 }
285
287 ElectronBag theElectronsAfterSelection;
288 if (importedElectronCollection && !importedElectronCollection->
empty()) {
289 for(auto electron : *importedElectronCollection) {
290 if (!
electron->trackParticleLink().isValid())
continue;
292 elTrk =
electron->trackParticleLink().cachedElement();
293 if (!elTrk) continue;
294 theElectronsAfterSelection.push_back(electron);
295 electronTracks.push_back(elTrk);
296 }
297 if (
m_skipNoElectron && theElectronsAfterSelection.size() == 0)
return StatusCode::SUCCESS;
298 ATH_MSG_DEBUG(
"Number of electrons after selection: " << theElectronsAfterSelection.size());
299 }
300
301 std::vector<const xAOD::TrackParticle*> tracks(3, nullptr);
302
303 for(auto jpsiItr=selectedJpsiCandidates.cbegin(); jpsiItr!=selectedJpsiCandidates.cend(); ++jpsiItr) {
304
305
306
309
310
312 jpsiTracks.resize(2);
313 jpsiTracks[0] = jpsiTP1;
314 jpsiTracks[1] = jpsiTP2;
315 }
316
317
318 for (auto trkItr=theIDTracksAfterSelection.cbegin(); trkItr!=theIDTracksAfterSelection.cend(); ++trkItr) {
321 return StatusCode::SUCCESS;
322 }
324 int linkedMuonTrk = 0;
327 if (linkedMuonTrk)
ATH_MSG_DEBUG(
"This id track is a muon track!");
329 if (linkedMuonTrk)
ATH_MSG_DEBUG(
"ID track removed: id track is slected to build Jpsi!");
330 continue;
331
332 }
333 }
335 int linkedElectronTrk = 0;
337 if (linkedElectronTrk)
ATH_MSG_DEBUG(
"This id track is an electron track!");
339 if (linkedElectronTrk)
ATH_MSG_DEBUG(
"ID track removed: id track is selected to build Jpsi!");
340 continue;
341 }
344 continue;
345 }
346 }
347
348
350
353 fabs(theThirdTP->
z0() + theThirdTP->
vz() - (*jpsiItr)->z()) >
m_trkDeltaZ )
354 continue;
357 continue;
358 }
359
360
361 bool passRoughMassCuts(true);
362
364 massCuts.clear();
368 }
369 if (!passRoughMassCuts) continue;
370
371
372
373 std::unique_ptr<xAOD::Vertex> bVertex(
fit(ctx, tracks, importedTrackCollection, importedGSFTrackCollection));
374 if (bVertex) {
375
376
377 double bChi2DOF = bVertex->chiSquared()/bVertex->numberDoF();
379
381 if(!chi2CutPassed) {
ATH_MSG_DEBUG(
"Chi Cut failed!");
continue; }
382
383
384 xAOD::BPhysHelper bHelper(bVertex.get());
385
386 bHelper.setRefTrks();
387
388 bool masspTpassed = true;
390 masspTpassed = false;
391 for (double masshypo3rd : massHypotheses) {
392 tripletMasses.push_back(masshypo3rd);
393 TLorentzVector bMomentum = bHelper.totalP(tripletMasses);
394 tripletMasses.pop_back();
395 double bpt = bMomentum.Pt();
397 double bMass = bMomentum.M();
398 ATH_MSG_DEBUG(
"candidate pt/mass under track mass hypothesis of " << masshypo3rd <<
" is " << bpt <<
" / " << bMass);
400 if(masscut && PtPassed) { masspTpassed = true; break; }
401 }
402 }
403 if (masspTpassed) {
404
405 std::vector<const xAOD::Vertex*> theJpsiPreceding;
406 theJpsiPreceding.push_back(*jpsiItr);
407 bHelper.setPrecedingVertices(theJpsiPreceding, importedJpsiCollection);
409 } else {
411 }
413
414 }
415
416 }
418 return StatusCode::SUCCESS;
419
420 }
#define ATH_MSG_WARNING(x)
std::unique_ptr< xAOD::Vertex > fit(const EventContext &ctx, const std::vector< const xAOD::TrackParticle * > &, const xAOD::TrackParticleContainer *, const xAOD::TrackParticleContainer *) const
static bool cutRange(double value, double min, double max) noexcept
static double getInvariantMass(const xAOD::TrackParticle *trk1, double mass1, const xAOD::TrackParticle *trk2, double mass2)
static bool cutRangeOR(std::span< double const > values, double min, double max) noexcept
static bool isContainedIn(const xAOD::TrackParticle *, std::span< const xAOD::TrackParticle *const >) noexcept
static double getPt(std::span< const xAOD::TrackParticle *const > tracks)
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".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".