163 {
165
167 if(!muonhandle.isValid()){
169 return StatusCode::FAILURE;
170 }
171
174
175
176 std::vector<const xAOD::TrackParticleContainer*> importedMuonTrackCollections;
178
179 for (SG::ReadHandle<xAOD::TrackParticleContainer>& handle:
m_MuonTrackKeys.makeHandles(ctx)) {
180 if(!handle.isValid()){
181 ATH_MSG_WARNING(
"No muon TrackParticle collection with name " << handle.key() <<
" found in StoreGate!");
182 return StatusCode::FAILURE;
183 } else {
184 ATH_MSG_DEBUG(
"Found muon TrackParticle collection " << handle.key() <<
" in StoreGate!");
185 ATH_MSG_DEBUG(
"Muon TrackParticle container size "<< handle->size());
186 importedMuonTrackCollections.push_back(handle.cptr());
187 }
188 }
189 }
190
191
194 if(!handle.isValid()){
195 ATH_MSG_WARNING(
"No TrackParticle collection with name " << handle.key() <<
" found in StoreGate!");
196 return StatusCode::FAILURE;
197 } else {
198 importedTrackCollection = handle.cptr();
199 ATH_MSG_DEBUG(
"Found TrackParticle collection " << handle.key() <<
" in StoreGate!");
200 }
201 ATH_MSG_DEBUG(
"ID TrackParticle container size "<< handle->size());
202
203
204 typedef std::vector<const xAOD::TrackParticle*>
TrackBag;
205 typedef std::vector<const xAOD::Muon*> MuonBag;
206
207
212 for (trkCItr=importedTrackCollection->
begin(); trkCItr!=importedTrackCollection->
end(); ++trkCItr) {
216 theIDTracksAfterSelection.push_back(TP);
217 }
218 if (theIDTracksAfterSelection.size() == 0) return StatusCode::SUCCESS;;
219 ATH_MSG_DEBUG(
"Number of tracks after ID track selection: " << theIDTracksAfterSelection.size());
220 }
221
222
223 MuonBag theMuonsAfterSelection;
225 for (
auto muItr=importedMuonCollection->
begin(); muItr!=importedMuonCollection->
end(); ++muItr) {
226 if ( *muItr == NULL ) continue;
227 if (!(*muItr)->inDetTrackParticleLink().isValid()) continue;
229 if ( muonTrk==NULL) continue;
233 if (
m_combOnly && (*muItr)->muonType() != xAOD::Muon::Combined )
continue;
234 if ( (*muItr)->muonType() == xAOD::Muon::SiliconAssociatedForwardMuon && !
m_useCombMeasurement)
continue;
235 theMuonsAfterSelection.push_back(*muItr);
236 }
237 if (theMuonsAfterSelection.size() == 0) return StatusCode::SUCCESS;;
238 ATH_MSG_DEBUG(
"Number of muons after selection: " << theMuonsAfterSelection.size());
239 }
240
241
242 std::vector<JpsiCandidate> jpsiCandidates;
246
247
248
250 std::vector<JpsiCandidate> selectCandidates;
251 for(
auto &cand : jpsiCandidates) {
if(cand.muonTypes!=
TT) selectCandidates.push_back(cand); }
252 selectCandidates.swap(jpsiCandidates);
253 ATH_MSG_DEBUG(
"Number of candidates after requirement of at least 1 combined muon: " << jpsiCandidates.size() );
254 }
255
256
257
258
259
261 for (auto jpsiItr=jpsiCandidates.begin(); jpsiItr!=jpsiCandidates.end(); ++jpsiItr) {
262 (*jpsiItr).collection1 = importedTrackCollection;
263 (*jpsiItr).collection2 = importedTrackCollection;
264 }
265 }
266
268 for (auto jpsiItr=jpsiCandidates.begin(); jpsiItr!=jpsiCandidates.end(); ++jpsiItr) {
270 (*jpsiItr).trackParticle1 = (*jpsiItr).muon1->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
271 (*jpsiItr).trackParticle2 = (*jpsiItr).muon2->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
272 (*jpsiItr).collection1 = importedTrackCollection;
273 (*jpsiItr).collection2 = importedTrackCollection;
274 }
276 if (!(*jpsiItr).muon1->combinedTrackParticleLink().isValid()) {
277 (*jpsiItr).trackParticle1 = (*jpsiItr).muon1->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
278 (*jpsiItr).collection1 = importedTrackCollection;
279 }
280
281 if (!(*jpsiItr).muon2->combinedTrackParticleLink().isValid()) {
282 (*jpsiItr).trackParticle2 = (*jpsiItr).muon2->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
283 (*jpsiItr).collection2 = importedTrackCollection;
284 }
285
286 if ((*jpsiItr).muon1->combinedTrackParticleLink().isValid()) {
287 (*jpsiItr).trackParticle1 = (*jpsiItr).muon1->trackParticle( xAOD::Muon::CombinedTrackParticle );
288 bool foundCollection(false);
289
290 for (auto muTrkCollItr=importedMuonTrackCollections.begin(); muTrkCollItr!=importedMuonTrackCollections.end(); ++muTrkCollItr) {
291 if (
isContainedIn((*jpsiItr).trackParticle1,*muTrkCollItr)) { (*jpsiItr).collection1 = *muTrkCollItr; foundCollection=
true;
break;}
292 }
293 if (!foundCollection) {
294 (*jpsiItr).trackParticle1 = (*jpsiItr).muon1->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
295 (*jpsiItr).collection1 = importedTrackCollection;
296 ATH_MSG_WARNING(
"Muon track from muon of author " << (*jpsiItr).muon1->author() <<
" not found in muon track collections you have provided.");
297 ATH_MSG_WARNING(
"Defaulting to ID track collection - combined measurement will not be used");
298 }
299 }
300
301 if ((*jpsiItr).muon2->combinedTrackParticleLink().isValid()) {
302 (*jpsiItr).trackParticle2 = (*jpsiItr).muon2->trackParticle( xAOD::Muon::CombinedTrackParticle );
303 bool foundCollection(false);
304
305 for (auto muTrkCollItr=importedMuonTrackCollections.begin(); muTrkCollItr!=importedMuonTrackCollections.end(); ++muTrkCollItr) {
306 if (
isContainedIn((*jpsiItr).trackParticle2,*muTrkCollItr)) { (*jpsiItr).collection2 = *muTrkCollItr; foundCollection=
true;
break;}
307 }
308 if (!foundCollection) {
309 (*jpsiItr).trackParticle2 = (*jpsiItr).muon2->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
310 (*jpsiItr).collection2 = importedTrackCollection;
311 ATH_MSG_WARNING(
"Muon track from muon of author " << (*jpsiItr).muon2->author() <<
" not found in muon track collections you have provided.");
312 ATH_MSG_WARNING(
"Defaulting to ID track collection - combined measurement will not be used");
313 }
314 }
315 }
316 }
317 }
318
319
320
322 std::vector<JpsiCandidate> selectCandidates;
323 for(auto& cand : jpsiCandidates){
324 bool reject = (fabs(cand.trackParticle1->pt()) <
m_higherPt) && (fabs(cand.trackParticle2->pt()) <
m_higherPt);
325 if(!reject) selectCandidates.push_back(cand);
326 }
327 selectCandidates.swap(jpsiCandidates);
328 ATH_MSG_DEBUG(
"Number of candidates after higherPt cut: " << jpsiCandidates.size() );
329 }
330
331
332 std::vector<JpsiCandidate> sortedJpsiCandidates;
334
335 ATH_MSG_DEBUG(
"Number of candidates after charge selection: " << sortedJpsiCandidates.size() );
336
337
339 std::vector<JpsiCandidate> selectCandidates;
340 for(auto& cand : sortedJpsiCandidates){
341 double deltatheta = fabs( cand.trackParticle1->theta() - cand.trackParticle2->theta() );
344 if(!reject) selectCandidates.push_back(cand);
345 }
346 sortedJpsiCandidates.swap(selectCandidates);
347 ATH_MSG_DEBUG(
"Number of collimated candidates: " << sortedJpsiCandidates.size() );
348 }
349
350
353 std::vector<JpsiCandidate> selectCandidates;
354 for(auto& cand : sortedJpsiCandidates){
356 bool reject = invMass < m_invMassLower || invMass >
m_invMassUpper;
357 if(!reject) selectCandidates.push_back(cand);
358 }
359 selectCandidates.swap(sortedJpsiCandidates);
360 ATH_MSG_DEBUG(
"Number of candidates passing invariant mass selection: " << sortedJpsiCandidates.size() );
361 }
362
363 ATH_MSG_DEBUG(
"Number of pairs passing all selections and going to vertexing: " << sortedJpsiCandidates.size() );
364 if (sortedJpsiCandidates.size() == 0) return StatusCode::SUCCESS;;
365 std::vector<const xAOD::TrackParticle*> theTracks;
366 std::vector<const xAOD::Muon*> theStoredMuons;
367
368 for(auto jpsiItr=sortedJpsiCandidates.begin(); jpsiItr!=sortedJpsiCandidates.end(); ++jpsiItr) {
369 theTracks.clear();
370 theTracks.push_back((*jpsiItr).trackParticle1);
371 theTracks.push_back((*jpsiItr).trackParticle2);
372 std::unique_ptr<xAOD::Vertex> myVxCandidate {
fit(theTracks,importedTrackCollection)};
373 if (myVxCandidate) {
374
375 double chi2 = myVxCandidate->chiSquared();
378
379 xAOD::BPhysHelper jpsiHelper(myVxCandidate.get());
380 bool validtrk = jpsiHelper.setRefTrks();
381 if(!validtrk)
ATH_MSG_WARNING(
"Problem setting tracks " << __FILE__ <<
':' << __LINE__);
383 theStoredMuons.clear();
384 theStoredMuons.push_back((*jpsiItr).muon1);
385 if (
m_mumu) theStoredMuons.push_back((*jpsiItr).muon2);
386 bool valid = jpsiHelper.setMuons(theStoredMuons,importedMuonCollection);
387 if(!valid)
ATH_MSG_WARNING(
"Problem setting muons " << __FILE__ <<
':' << __LINE__);
388 }
389
390 vxContainer.
push_back(std::move(myVxCandidate));
391 }
392 } else {
394
395
396
397 }
398 }
400
401 return StatusCode::SUCCESS;;
402 }
xAOD::Vertex * fit(const std::vector< const xAOD::TrackParticle * > &, const xAOD::TrackParticleContainer *importedTrackCollection) const
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
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)
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[
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".