157 {
159
161 if(!muonhandle.isValid()){
163 return StatusCode::FAILURE;
164 }
165
168
169
170 std::vector<const xAOD::TrackParticleContainer*> importedMuonTrackCollections;
172
173 for (SG::ReadHandle<xAOD::TrackParticleContainer>& handle:
m_MuonTrackKeys.makeHandles(ctx)) {
175 ATH_MSG_WARNING(
"No muon TrackParticle collection with name " <<
handle.key() <<
" found in StoreGate!");
176 return StatusCode::FAILURE;
177 } else {
180 importedMuonTrackCollections.push_back(
handle.cptr());
181 }
182 }
183 }
184
185
190 return StatusCode::FAILURE;
191 } else {
192 importedTrackCollection =
handle.cptr();
194 }
196
197
198 typedef std::vector<const xAOD::TrackParticle*>
TrackBag;
199 typedef std::vector<const xAOD::Muon*> MuonBag;
200
201
206 for (trkCItr=importedTrackCollection->
begin(); trkCItr!=importedTrackCollection->
end(); ++trkCItr) {
210 theIDTracksAfterSelection.push_back(TP);
211 }
212 if (theIDTracksAfterSelection.size() == 0) return StatusCode::SUCCESS;;
213 ATH_MSG_DEBUG(
"Number of tracks after ID track selection: " << theIDTracksAfterSelection.size());
214 }
215
216
217 MuonBag theMuonsAfterSelection;
219 for (
auto muItr=importedMuonCollection->
begin(); muItr!=importedMuonCollection->
end(); ++muItr) {
220 if ( *muItr == nullptr ) continue;
221 const xAOD::TrackParticle* muonTrk = (*muItr)->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
222 if ( muonTrk==NULL) continue;
226 if (
m_combOnly && (*muItr)->muonType() != xAOD::Muon::MuonType::Combined )
continue;
227 if ( (*muItr)->muonType() == xAOD::Muon::MuonType::SiliconAssociatedForwardMuon && !
m_useCombMeasurement)
continue;
228 theMuonsAfterSelection.push_back(*muItr);
229 }
230 if (theMuonsAfterSelection.size() == 0) return StatusCode::SUCCESS;;
231 ATH_MSG_DEBUG(
"Number of muons after selection: " << theMuonsAfterSelection.size());
232 }
233
234
235 std::vector<JpsiCandidate> jpsiCandidates;
239
240
241
243 std::vector<JpsiCandidate> selectCandidates;
244 for(
auto &cand : jpsiCandidates) {
if(cand.muonTypes!=
TT) selectCandidates.push_back(cand); }
245 selectCandidates.swap(jpsiCandidates);
246 ATH_MSG_DEBUG(
"Number of candidates after requirement of at least 1 combined muon: " << jpsiCandidates.size() );
247 }
248
249
250
251
252
254 for (auto jpsiItr=jpsiCandidates.begin(); jpsiItr!=jpsiCandidates.end(); ++jpsiItr) {
255 (*jpsiItr).collection1 = importedTrackCollection;
256 (*jpsiItr).collection2 = importedTrackCollection;
257 }
258 }
259
261 using enum xAOD::Muon::TrackParticleType;
262 for (auto jpsiItr=jpsiCandidates.begin(); jpsiItr!=jpsiCandidates.end(); ++jpsiItr) {
264 (*jpsiItr).trackParticle1 = (*jpsiItr).muon1->trackParticle(InnerDetectorTrackParticle);
265 (*jpsiItr).trackParticle2 = (*jpsiItr).muon2->trackParticle(InnerDetectorTrackParticle);
266 (*jpsiItr).collection1 = importedTrackCollection;
267 (*jpsiItr).collection2 = importedTrackCollection;
268 }
270 if (!(*jpsiItr).muon1->trackParticle(CombinedTrackParticle)) {
271 (*jpsiItr).trackParticle1 = (*jpsiItr).muon1->trackParticle(InnerDetectorTrackParticle );
272 (*jpsiItr).collection1 = importedTrackCollection;
273 }
274
275 if (!(*jpsiItr).muon2->trackParticle(CombinedTrackParticle)) {
276 (*jpsiItr).trackParticle2 = (*jpsiItr).muon2->trackParticle(InnerDetectorTrackParticle );
277 (*jpsiItr).collection2 = importedTrackCollection;
278 }
279
280 if ((*jpsiItr).muon1->trackParticle(CombinedTrackParticle)) {
281 (*jpsiItr).trackParticle1 = (*jpsiItr).muon1->trackParticle(CombinedTrackParticle);
282 bool foundCollection(false);
283
284 for (auto muTrkCollItr=importedMuonTrackCollections.begin(); muTrkCollItr!=importedMuonTrackCollections.end(); ++muTrkCollItr) {
285 if (
isContainedIn((*jpsiItr).trackParticle1,*muTrkCollItr)) { (*jpsiItr).collection1 = *muTrkCollItr; foundCollection=
true;
break;}
286 }
287 if (!foundCollection) {
288 (*jpsiItr).trackParticle1 = (*jpsiItr).muon1->trackParticle( InnerDetectorTrackParticle );
289 (*jpsiItr).collection1 = importedTrackCollection;
290 ATH_MSG_WARNING(
"Muon track from muon of author " << (*jpsiItr).muon1->author() <<
" not found in muon track collections you have provided.");
291 ATH_MSG_WARNING(
"Defaulting to ID track collection - combined measurement will not be used");
292 }
293 }
294
295 if ((*jpsiItr).muon2->trackParticle(CombinedTrackParticle)) {
296 (*jpsiItr).trackParticle2 = (*jpsiItr).muon2->trackParticle(CombinedTrackParticle );
297 bool foundCollection(false);
298
299 for (auto muTrkCollItr=importedMuonTrackCollections.begin(); muTrkCollItr!=importedMuonTrackCollections.end(); ++muTrkCollItr) {
300 if (
isContainedIn((*jpsiItr).trackParticle2,*muTrkCollItr)) { (*jpsiItr).collection2 = *muTrkCollItr; foundCollection=
true;
break;}
301 }
302 if (!foundCollection) {
303 (*jpsiItr).trackParticle2 = (*jpsiItr).muon2->trackParticle(InnerDetectorTrackParticle);
304 (*jpsiItr).collection2 = importedTrackCollection;
305 ATH_MSG_WARNING(
"Muon track from muon of author " << (*jpsiItr).muon2->author() <<
" not found in muon track collections you have provided.");
306 ATH_MSG_WARNING(
"Defaulting to ID track collection - combined measurement will not be used");
307 }
308 }
309 }
310 }
311 }
312
313
314
316 std::vector<JpsiCandidate> selectCandidates;
317 for(auto& cand : jpsiCandidates){
318 bool reject = (fabs(cand.trackParticle1->pt()) <
m_higherPt) && (fabs(cand.trackParticle2->pt()) <
m_higherPt);
319 if(!reject) selectCandidates.push_back(cand);
320 }
321 selectCandidates.swap(jpsiCandidates);
322 ATH_MSG_DEBUG(
"Number of candidates after higherPt cut: " << jpsiCandidates.size() );
323 }
324
325
326 std::vector<JpsiCandidate> sortedJpsiCandidates;
328
329 ATH_MSG_DEBUG(
"Number of candidates after charge selection: " << sortedJpsiCandidates.size() );
330
331
333 std::vector<JpsiCandidate> selectCandidates;
334 for(auto& cand : sortedJpsiCandidates){
335 double deltatheta = fabs( cand.trackParticle1->theta() - cand.trackParticle2->theta() );
338 if(!reject) selectCandidates.push_back(cand);
339 }
340 sortedJpsiCandidates.swap(selectCandidates);
341 ATH_MSG_DEBUG(
"Number of collimated candidates: " << sortedJpsiCandidates.size() );
342 }
343
344
347 std::vector<JpsiCandidate> selectCandidates;
348 for(auto& cand : sortedJpsiCandidates){
350 bool reject = invMass < m_invMassLower || invMass >
m_invMassUpper;
351 if(!reject) selectCandidates.push_back(cand);
352 }
353 selectCandidates.swap(sortedJpsiCandidates);
354 ATH_MSG_DEBUG(
"Number of candidates passing invariant mass selection: " << sortedJpsiCandidates.size() );
355 }
356
357 ATH_MSG_DEBUG(
"Number of pairs passing all selections and going to vertexing: " << sortedJpsiCandidates.size() );
358 if (sortedJpsiCandidates.size() == 0) return StatusCode::SUCCESS;;
359 std::vector<const xAOD::TrackParticle*> theTracks;
360 std::vector<const xAOD::Muon*> theStoredMuons;
361
362 for(auto jpsiItr=sortedJpsiCandidates.begin(); jpsiItr!=sortedJpsiCandidates.end(); ++jpsiItr) {
363 theTracks.clear();
364 theTracks.push_back((*jpsiItr).trackParticle1);
365 theTracks.push_back((*jpsiItr).trackParticle2);
366 std::unique_ptr<xAOD::Vertex> myVxCandidate {
fit(ctx, theTracks,importedTrackCollection)};
367 if (myVxCandidate) {
368
369 double chi2 = myVxCandidate->chiSquared();
372
373 xAOD::BPhysHelper jpsiHelper(myVxCandidate.get());
374 bool validtrk = jpsiHelper.setRefTrks();
375 if(!validtrk)
ATH_MSG_WARNING(
"Problem setting tracks " << __FILE__ <<
':' << __LINE__);
377 theStoredMuons.clear();
378 theStoredMuons.push_back((*jpsiItr).muon1);
379 if (
m_mumu) theStoredMuons.push_back((*jpsiItr).muon2);
380 bool valid = jpsiHelper.setMuons(theStoredMuons,importedMuonCollection);
381 if(!valid)
ATH_MSG_WARNING(
"Problem setting muons " << __FILE__ <<
':' << __LINE__);
382 }
383
384 vxContainer.
push_back(std::move(myVxCandidate));
385 }
386 } else {
388
389
390 }
391 }
393
394 return StatusCode::SUCCESS;;
395 }
std::vector< JpsiCandidate > getPairs(const std::vector< const xAOD::TrackParticle * > &) const
std::vector< JpsiCandidate > getPairs2Colls(const std::vector< const xAOD::TrackParticle * > &, const std::vector< const xAOD::Muon * > &, bool) const
bool passesMCPCuts(const xAOD::Muon *) const
std::vector< JpsiCandidate > selectCharges(const std::vector< JpsiCandidate > &) const
bool isContainedIn(const xAOD::TrackParticle *, const xAOD::TrackParticleContainer *) const
double getInvariantMass(const JpsiCandidate &, std::span< const double >) const
std::unique_ptr< xAOD::Vertex > fit(const EventContext &ctx, const std::vector< const xAOD::TrackParticle * > &, const xAOD::TrackParticleContainer *importedTrackCollection) const
DataModel_detail::const_iterator< DataVector > const_iterator
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
double chi2(TH1 *h0, TH1 *h1)
virtual void handle(const Incident &inc)
Handle end of run incidents to save the metadata at that point.
std::vector< const xAOD::TrackParticle * > TrackBag
double invMass(const I4Momentum &pA, const I4Momentum &pB)
invariant mass from two I4momentum references
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
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".