Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Public Member Functions | Private Member Functions | Private Attributes | List of all members
DerivationFramework::BPhysConversionFinder Class Reference

#include <BPhysConversionFinder.h>

Inheritance diagram for DerivationFramework::BPhysConversionFinder:
Collaboration diagram for DerivationFramework::BPhysConversionFinder:

Public Member Functions

 BPhysConversionFinder (const std::string &t, const std::string &n, const IInterface *p)
 
StatusCode initialize () override
 
StatusCode finalize () override
 
virtual StatusCode addBranches () const override
 

Private Member Functions

StatusCode doCascadeFit (const xAOD::Vertex *diMuonVertex, const xAOD::Vertex *convVertex, const double diMuonMassConstraint, TLorentzVector &fitMom, float &chiSq) const
 

Private Attributes

std::string m_diMuonCollectionToCheck
 
std::vector< std::string > m_passFlagsToCheck
 
ToolHandle< Trk::V0Toolsm_v0Tools
 
ToolHandle< Trk::IVertexFitterm_vertexFitter
 
ToolHandle< InDet::VertexPointEstimatorm_vertexEstimator
 
ToolHandle< Trk::ITrkDistanceFinderm_distanceTool
 
ToolHandle< InDet::ConversionPostSelectorm_postSelector
 
ToolHandle< Trk::TrkVKalVrtFitterm_cascadeFitter
 
std::string m_inputTrackParticleContainerName
 
std::string m_conversionContainerName
 
float m_maxDistBetweenTracks
 
float m_maxDeltaCotTheta
 
bool m_requireDeltaM
 
float m_maxDeltaM
 

Detailed Description

Definition at line 33 of file BPhysConversionFinder.h.

Constructor & Destructor Documentation

◆ BPhysConversionFinder()

DerivationFramework::BPhysConversionFinder::BPhysConversionFinder ( const std::string &  t,
const std::string &  n,
const IInterface *  p 
)

Definition at line 22 of file BPhysConversionFinder.cxx.

24  :
25  base_class(t,n,p),
26  m_v0Tools("Trk::V0Tools"),
27  m_vertexFitter("Trk::TrkVKalVrtFitter"),
28  m_vertexEstimator("InDet::VertexPointEstimator"),
29  m_distanceTool("Trk::SeedNewtonTrkDistanceFinder/InDetConversionTrkDistanceFinder"),
30  m_postSelector("InDet::ConversionPostSelector"),
31  m_cascadeFitter("Trk::TrkVKalVrtFitter"),
32  m_inputTrackParticleContainerName("InDetTrackParticles"),
33  m_conversionContainerName("BPhysConversionCandidates"),
35  m_maxDeltaCotTheta(0.3),
36  m_requireDeltaM(true),
37  m_maxDeltaM(3000.0)
38  {
39 
40  // Declare user-defined properties
41  declareProperty("DiMuonVertexContainer", m_diMuonCollectionToCheck);
42  declareProperty("PassFlagsToCheck", m_passFlagsToCheck);
43  declareProperty("V0Tools", m_v0Tools);
44  declareProperty("VertexFitterTool", m_vertexFitter);
45  declareProperty("VertexEstimator", m_vertexEstimator);
46  declareProperty("DistanceTool", m_distanceTool);
47  declareProperty("ConversionPostSelector", m_postSelector);
48  declareProperty("CascadeFitter", m_cascadeFitter);
49  declareProperty("InputTrackParticleContainerName", m_inputTrackParticleContainerName);
50  declareProperty("ConversionContainerName", m_conversionContainerName);
51  declareProperty("MaxDistBetweenTracks", m_maxDistBetweenTracks = 10.0); // Maximum allowed distance of minimum approach
52  declareProperty("MaxDeltaCotTheta", m_maxDeltaCotTheta = 0.3); // Maximum allowed dCotTheta between tracks
53  declareProperty("RequireDeltaM", m_requireDeltaM = true); // Only save a conversions if it's a chi_c,b candidate (must then pass "MaxDeltaM" requirement), if "False" all conversions in the event will be saved
54  declareProperty("MaxDeltaM", m_maxDeltaM = 3000.0); // Maximum mass difference between di-muon+conversion and di-muon
55 
56  }

Member Function Documentation

◆ addBranches()

StatusCode DerivationFramework::BPhysConversionFinder::addBranches ( ) const
overridevirtual

Definition at line 86 of file BPhysConversionFinder.cxx.

87  {
88 
89  int nTrackPairs_Init = 0;
90  int nTrackPairs_Selected = 0;
91  int nConv_VertexFit = 0;
92  int nConv_Selected = 0;
93  int nConv_Selected_DeltaM = 0;
94 
95  std::vector<const xAOD::Vertex*> oniaVertices;
96  oniaVertices.clear();
97 
98  //------------------------------------
99  // Look for di-muons
100  //------------------------------------
101  const xAOD::VertexContainer* diMuonContainer = NULL;
102  ATH_CHECK( evtStore()->retrieve(diMuonContainer, m_diMuonCollectionToCheck) );
103 
104  if(diMuonContainer->size() == 0) {
105 
106  ATH_MSG_DEBUG("Vertex Container (" << m_diMuonCollectionToCheck << ") is empty");
107 
108  } else {
109 
110  ATH_MSG_DEBUG("Vertex Container (" << m_diMuonCollectionToCheck << ") contains " << diMuonContainer->size() << " vertices");
111 
112  for(xAOD::VertexContainer::const_iterator vtxItr = diMuonContainer->begin(); vtxItr != diMuonContainer->end(); ++vtxItr) {
113 
114  const xAOD::Vertex* vertex = (*vtxItr);
115 
116  bool passedHypothesis = false;
117 
118  for(const auto &flag : m_passFlagsToCheck) {
120  bool pass = acc(*vertex);
121  if(pass) passedHypothesis = true;
122  }
123 
124  if(passedHypothesis) {
125  oniaVertices.push_back(vertex);
126  }
127 
128  }
129  }
130  //------------------------------------
131 
132  // Output conversion container
133  std::unique_ptr<xAOD::VertexContainer> conversionContainer( new xAOD::VertexContainer() );
134  std::unique_ptr<xAOD::VertexAuxContainer> conversionAuxContainer( new xAOD::VertexAuxContainer() );
135  conversionContainer->setStore(conversionAuxContainer.get());
136 
137  // Only call conversion finder if we've found a di-muon candidate or
138  // we really want to look for conversions independently
139  const bool callConvFinder = !m_requireDeltaM || oniaVertices.size() > 0;
140 
141  if(callConvFinder) {
142 
143  // Retrieve track particles from StoreGate
144  const xAOD::TrackParticleContainer* inputTrackParticles = NULL;
145  ATH_CHECK( evtStore()->retrieve(inputTrackParticles,m_inputTrackParticleContainerName) );
146 
147  ATH_MSG_DEBUG("Track particle container size " << inputTrackParticles->size());
148 
149  // Track Selection
150  std::vector<const xAOD::TrackParticle*> posTracks; posTracks.clear();
151  std::vector<const xAOD::TrackParticle*> negTracks; negTracks.clear();
152 
153  // Track Loop
154  for(xAOD::TrackParticleContainer::const_iterator trkItr = inputTrackParticles->begin(); trkItr != inputTrackParticles->end(); ++trkItr) {
155 
156  const xAOD::TrackParticle* track = (*trkItr);
157 
158  uint8_t nSCT(0);
159  uint8_t nPIX(0);
160 
161  track->summaryValue(nPIX,xAOD::numberOfPixelHits);
162  track->summaryValue(nSCT,xAOD::numberOfSCTHits);
163 
164  // Don't want TRT-only tracks
165  // Require Si hits on all tracks
166  if( nSCT + nPIX < 1 ) continue;
167 
168  if( track->charge() > 0.0) {
169  posTracks.push_back(track);
170  } else {
171  negTracks.push_back(track);
172  }
173 
174  } // Track Loop
175 
176  ATH_MSG_DEBUG(posTracks.size() + negTracks.size() << " tracks pass pre-selection");
177 
178  std::vector<const xAOD::TrackParticle*>::const_iterator tpIt1;
179  std::vector<const xAOD::TrackParticle*>::const_iterator tpIt2;
180 
181  // Pos Track Loop
182  for(tpIt1 = posTracks.begin(); tpIt1 != posTracks.end(); ++tpIt1) {
183 
184  const xAOD::TrackParticle* trackParticle1 = (*tpIt1);
185 
186  const Trk::Perigee& trackPerigee1 = trackParticle1->perigeeParameters();
187 
188  // Neg Track Loop
189  for(tpIt2 = negTracks.begin(); tpIt2 != negTracks.end(); ++tpIt2) {
190 
191  if (*tpIt1 == *tpIt2) continue;
192 
193  const xAOD::TrackParticle* trackParticle2 = (*tpIt2);
194 
195  const Trk::Perigee& trackPerigee2 = trackParticle2->perigeeParameters();
196 
197  nTrackPairs_Init++;
198 
199  //------------------------------------
200  // Track pair selection
201  //------------------------------------
202  const double deltaCotTheta = fabs(1./tan(trackPerigee1.parameters()[Trk::theta]) - 1./tan(trackPerigee2.parameters()[Trk::theta]));
203  if(deltaCotTheta > m_maxDeltaCotTheta) continue;
204 
205  double distance = 1000000.;
206  std::optional<std::pair<Amg::Vector3D,Amg::Vector3D>> result = m_distanceTool->CalculateMinimumDistance(trackParticle1->perigeeParameters(),trackParticle2->perigeeParameters() );
207  bool gotDistance = result.has_value();
208  if(gotDistance) distance = Amg::distance (result->first, result->second);
209  if(!gotDistance || (distance > m_maxDistBetweenTracks)) continue;
210  //------------------------------------
211 
212  //------------------------------------
213  // Estimate starting point + cuts on compatiblity of tracks
214  //------------------------------------
215  int sflag = 0;
216  int errorcode = 0;
217  std::map<std::string, float> vertexOutput;
218  Amg::Vector3D startingPoint = m_vertexEstimator->getCirclesIntersectionPoint(&trackPerigee1,&trackPerigee2,sflag,errorcode, vertexOutput);
219  if(errorcode != 0) continue;
220  //------------------------------------
221 
222  nTrackPairs_Selected++;
223 
224  std::vector<const xAOD::TrackParticle*> trackPair;
225  trackPair.clear();
226  trackPair.push_back(trackParticle1);
227  trackPair.push_back(trackParticle2);
228 
229  // Do the vertex fit
230  std::unique_ptr<xAOD::Vertex> convVertexCandidate( m_vertexFitter->fit(trackPair, startingPoint) );
231 
232  // Check for successful fit
233  if(convVertexCandidate != NULL) {
234 
235  ATH_MSG_DEBUG("Vertex Fit Succeeded");
236 
237  convVertexCandidate->clearTracks();
239  newLink1.setElement(*tpIt1);
240  newLink1.setStorableObject(*inputTrackParticles);
242  newLink2.setElement(*tpIt2);
243  newLink2.setStorableObject(*inputTrackParticles);
244  convVertexCandidate->addTrackAtVertex(newLink1);
245  convVertexCandidate->addTrackAtVertex(newLink2);
246 
247  nConv_VertexFit++;
248 
249  //------------------------------------
250  // Post-vertexing cuts
251  //------------------------------------
252 
253  // This is empty and only present for compatiblity.
254  // The cut this informtion pertains to is not used for Si-Si conversions so this is OK
255  std::vector<Amg::Vector3D> positionList;
256 
257  // Apply Si-Si converion post-selection
258  if( !m_postSelector->selectConversionCandidate(convVertexCandidate.get(),0,positionList) ) {
259  convVertexCandidate.reset();
260  continue;
261  }
262  //------------------------------------
263 
264  nConv_Selected++;
265 
266  // Get photon momentum 3-vector
267  const xAOD::Vertex * constConvVertex = convVertexCandidate.get();
268  Amg::Vector3D momentum = m_v0Tools->V0Momentum(constConvVertex);
269 
270  TLorentzVector photon;
271  photon.SetXYZM(momentum.x(),momentum.y(),momentum.z(),0.0);
272 
273  //------------------------------------
274  // Check if conversion is consistent with a chi_c,b candidate
275  // by requiring a small mass difference w.r.t. any di-muon in event
276  //------------------------------------
277  bool passDeltaM = false;
278 
279  // Use to keep track of which dimuon(s) gave a chi_c/b candidate
280  std::vector<const xAOD::Vertex*> candidateOniaVertices;
281  candidateOniaVertices.clear();
282 
283  for ( std::vector<const xAOD::Vertex*>::const_iterator vtxItr = oniaVertices.begin(); vtxItr != oniaVertices.end(); ++vtxItr ) {
284 
285  const xAOD::Vertex* oniaVertex = (*vtxItr);
286 
287  static const SG::ConstAccessor<std::vector<float> > RefTrackPxAcc("RefTrackPx");
288  static const SG::ConstAccessor<std::vector<float> > RefTrackPyAcc("RefTrackPy");
289  static const SG::ConstAccessor<std::vector<float> > RefTrackPzAcc("RefTrackPz");
290  std::vector<float> diMuon_Px = RefTrackPxAcc(*oniaVertex);
291  std::vector<float> diMuon_Py = RefTrackPyAcc(*oniaVertex);
292  std::vector<float> diMuon_Pz = RefTrackPzAcc(*oniaVertex);
293 
294  TLorentzVector muon1, muon2;
295  muon1.SetXYZM(diMuon_Px.at(0),diMuon_Py.at(0),diMuon_Pz.at(0),105.658);
296  muon2.SetXYZM(diMuon_Px.at(1),diMuon_Py.at(1),diMuon_Pz.at(1),105.658);
297 
298  TLorentzVector diMuon = muon1 + muon2;
299 
300  const double deltaM = (diMuon+photon).M() - diMuon.M();
301 
302  ATH_MSG_DEBUG("Candidate DeltaM = " << deltaM << " MeV DiMuon " << oniaVertex->index() << " ( Mass = " << diMuon.M() << " MeV )");
303 
304  // Did we find a one di-muon + photon candidate with a mass diff. consistent with chi_c/b?
305  if(deltaM < m_maxDeltaM) {
306  passDeltaM = true;
307  candidateOniaVertices.push_back(oniaVertex);
308  }
309 
310  }
311 
312  // Only keep the conversion candidate if it's consistent with a chi_c,b decay
313  if(m_requireDeltaM && !passDeltaM) {
314  convVertexCandidate.reset();
315  continue;
316  }
317  //------------------------------------
318 
319  //------------------------------------
320  // Final conversion candidates
321  //------------------------------------
322  nConv_Selected_DeltaM++;
323 
324  // Keep track of which dimuon(s) gave a chi_c/b candidate
325  std::vector< ElementLink<xAOD::VertexContainer> > diMuonLinks;
326  diMuonLinks.clear();
327 
328  // Output of cascade fits with various di-muon mass hypotheses
329  std::vector<float> fit_Psi1S_Px, fit_Psi1S_Py, fit_Psi1S_Pz, fit_Psi1S_M, fit_Psi1S_ChiSq;
330  std::vector<float> fit_Psi2S_Px, fit_Psi2S_Py, fit_Psi2S_Pz, fit_Psi2S_M, fit_Psi2S_ChiSq;
331  std::vector<float> fit_Upsi1S_Px, fit_Upsi1S_Py, fit_Upsi1S_Pz, fit_Upsi1S_M, fit_Upsi1S_ChiSq;
332  std::vector<float> fit_Upsi2S_Px, fit_Upsi2S_Py, fit_Upsi2S_Pz, fit_Upsi2S_M, fit_Upsi2S_ChiSq;
333  std::vector<float> fit_Upsi3S_Px, fit_Upsi3S_Py, fit_Upsi3S_Pz, fit_Upsi3S_M, fit_Upsi3S_ChiSq;
334 
335  // Loop over di-muon vertices associated with a candidate
336  for(std::vector<const xAOD::Vertex*>::const_iterator vtxItr = candidateOniaVertices.begin(); vtxItr != candidateOniaVertices.end(); ++vtxItr ) {
337 
338  //------------------------------------
339  // Add an element link to each dimuon which formed a
340  // candidate, leading to the decision to save this conversion
341  //------------------------------------
343  myLink.setElement(*vtxItr);
344  myLink.setStorableObject(*diMuonContainer);
345 
346  if(!myLink.isValid()) {
347  ATH_MSG_WARNING("Invalid DiMuon ElementLink!");
348  }
349 
350  diMuonLinks.push_back(myLink);
351  //------------------------------------
352 
353  // Check which mass window this di-muon passed
354  static const SG::ConstAccessor<Char_t> passed_PsiAcc("passed_Psi");
355  static const SG::ConstAccessor<Char_t> passed_UpsiAcc("passed_Upsi");
356  bool passed_Psi = passed_PsiAcc(**vtxItr);
357  bool passed_Upsi = passed_UpsiAcc(**vtxItr);
358 
359  //------------------------------------
360  // Cascade fit with J/psi mass hypothesis
361  //------------------------------------
362  float fitChiSq_Psi1S = 99999;
363  TLorentzVector fitResult_Psi1S;
364 
365  // Only bother with the fit if di-muon mass is within the relveant range,
366  // but still fill an dummy 4-vector to preserve one to one correspondance with "DiMuonLinks"
367  if(passed_Psi) {
368  ATH_CHECK( doCascadeFit(*vtxItr,constConvVertex,3096.916,fitResult_Psi1S,fitChiSq_Psi1S) );
369  }
370 
371  fit_Psi1S_Px.push_back(fitResult_Psi1S.Px());
372  fit_Psi1S_Py.push_back(fitResult_Psi1S.Py());
373  fit_Psi1S_Pz.push_back(fitResult_Psi1S.Pz());
374  fit_Psi1S_M.push_back(fitResult_Psi1S.M());
375  fit_Psi1S_ChiSq.push_back(fitChiSq_Psi1S);
376 
377  //------------------------------------
378  // Cascade fit with psi(2S) mass hypothesis
379  //------------------------------------
380  float fitChiSq_Psi2S = 99999;
381  TLorentzVector fitResult_Psi2S;
382 
383  // Only bother with the fit if di-muon mass is within the relveant range,
384  // but still fill an dummy 4-vector to preserve one to one correspondance with "DiMuonLinks"
385  if(passed_Psi) {
386  ATH_CHECK( doCascadeFit(*vtxItr,constConvVertex,3686.097,fitResult_Psi2S,fitChiSq_Psi2S) );
387  }
388 
389  fit_Psi2S_Px.push_back(fitResult_Psi2S.Px());
390  fit_Psi2S_Py.push_back(fitResult_Psi2S.Py());
391  fit_Psi2S_Pz.push_back(fitResult_Psi2S.Pz());
392  fit_Psi2S_M.push_back(fitResult_Psi2S.M());
393  fit_Psi2S_ChiSq.push_back(fitChiSq_Psi2S);
394 
395  //------------------------------------
396  // Cascade fit with Upsi(1S) mass hypothesis
397  //------------------------------------
398  float fitChiSq_Upsi1S = 99999;
399  TLorentzVector fitResult_Upsi1S;
400 
401  // Only bother with the fit if di-muon mass is within the relveant range,
402  // but still fill an dummy 4-vector to preserve one to one correspondance with "DiMuonLinks"
403  if(passed_Upsi) {
404  ATH_CHECK( doCascadeFit(*vtxItr,constConvVertex,9460.30,fitResult_Upsi1S,fitChiSq_Upsi1S) );
405  }
406 
407  fit_Upsi1S_Px.push_back(fitResult_Upsi1S.Px());
408  fit_Upsi1S_Py.push_back(fitResult_Upsi1S.Py());
409  fit_Upsi1S_Pz.push_back(fitResult_Upsi1S.Pz());
410  fit_Upsi1S_M.push_back(fitResult_Upsi1S.M());
411  fit_Upsi1S_ChiSq.push_back(fitChiSq_Upsi1S);
412 
413  //------------------------------------
414  // Cascade fit with Upsi(2S) mass hypothesis
415  //------------------------------------
416  float fitChiSq_Upsi2S = 99999;
417  TLorentzVector fitResult_Upsi2S;
418 
419  // Only bother with the fit if di-muon mass is within the relveant range,
420  // but still fill an dummy 4-vector to preserve one to one correspondance with "DiMuonLinks"
421  if(passed_Upsi) {
422  ATH_CHECK( doCascadeFit(*vtxItr,constConvVertex,10023.26,fitResult_Upsi2S,fitChiSq_Upsi2S) );
423  }
424 
425  fit_Upsi2S_Px.push_back(fitResult_Upsi2S.Px());
426  fit_Upsi2S_Py.push_back(fitResult_Upsi2S.Py());
427  fit_Upsi2S_Pz.push_back(fitResult_Upsi2S.Pz());
428  fit_Upsi2S_M.push_back(fitResult_Upsi2S.M());
429  fit_Upsi2S_ChiSq.push_back(fitChiSq_Upsi2S);
430 
431  //------------------------------------
432  // Cascade fit with Upsi(3S) mass hypothesis
433  //------------------------------------
434  float fitChiSq_Upsi3S = 99999;
435  TLorentzVector fitResult_Upsi3S;
436 
437  // Only bother with the fit if di-muon mass is within the relveant range,
438  // but still fill an dummy 4-vector to preserve one to one correspondance with "DiMuonLinks"
439  if(passed_Upsi) {
440  ATH_CHECK( doCascadeFit(*vtxItr,constConvVertex,10355.2,fitResult_Upsi3S,fitChiSq_Upsi3S) );
441  }
442 
443  fit_Upsi3S_Px.push_back(fitResult_Upsi3S.Px());
444  fit_Upsi3S_Py.push_back(fitResult_Upsi3S.Py());
445  fit_Upsi3S_Pz.push_back(fitResult_Upsi3S.Pz());
446  fit_Upsi3S_M.push_back(fitResult_Upsi3S.M());
447  fit_Upsi3S_ChiSq.push_back(fitChiSq_Upsi3S);
448 
449  }
450 
451  //------------------------------------
452  // Decorate selected conversions
453  //------------------------------------
454  ATH_MSG_DEBUG("Decorating conversion vertices");
455 
456  static const SG::Accessor< std::vector< ElementLink<xAOD::VertexContainer> > > DiMuonLinksAcc("DiMuonLinks");
457  DiMuonLinksAcc(*convVertexCandidate) = diMuonLinks;
458 
459  static const SG::Accessor< std::vector<float> > CascadeFit_Psi1S_PxAcc("CascadeFit_Psi1S_Px");
460  static const SG::Accessor< std::vector<float> > CascadeFit_Psi1S_PyAcc("CascadeFit_Psi1S_Py");
461  static const SG::Accessor< std::vector<float> > CascadeFit_Psi1S_PzAcc("CascadeFit_Psi1S_Pz");
462  static const SG::Accessor< std::vector<float> > CascadeFit_Psi1S_MAcc("CascadeFit_Psi1S_M");
463  static const SG::Accessor< std::vector<float> > CascadeFit_Psi1S_ChiSqAcc("CascadeFit_Psi1S_ChiSq");
464  CascadeFit_Psi1S_PxAcc(*convVertexCandidate) = fit_Psi1S_Px;
465  CascadeFit_Psi1S_PyAcc(*convVertexCandidate) = fit_Psi1S_Py;
466  CascadeFit_Psi1S_PzAcc(*convVertexCandidate) = fit_Psi1S_Pz;
467  CascadeFit_Psi1S_MAcc(*convVertexCandidate) = fit_Psi1S_M;
468  CascadeFit_Psi1S_ChiSqAcc(*convVertexCandidate) = fit_Psi1S_ChiSq;
469 
470  static const SG::Accessor< std::vector<float> > CascadeFit_Psi2S_PxAcc("CascadeFit_Psi2S_Px");
471  static const SG::Accessor< std::vector<float> > CascadeFit_Psi2S_PyAcc("CascadeFit_Psi2S_Py");
472  static const SG::Accessor< std::vector<float> > CascadeFit_Psi2S_PzAcc("CascadeFit_Psi2S_Pz");
473  static const SG::Accessor< std::vector<float> > CascadeFit_Psi2S_MAcc("CascadeFit_Psi2S_M");
474  static const SG::Accessor< std::vector<float> > CascadeFit_Psi2S_ChiSqAcc("CascadeFit_Psi2S_ChiSq");
475  CascadeFit_Psi2S_PxAcc(*convVertexCandidate) = fit_Psi2S_Px;
476  CascadeFit_Psi2S_PyAcc(*convVertexCandidate) = fit_Psi2S_Py;
477  CascadeFit_Psi2S_PzAcc(*convVertexCandidate) = fit_Psi2S_Pz;
478  CascadeFit_Psi2S_MAcc(*convVertexCandidate) = fit_Psi2S_M;
479  CascadeFit_Psi2S_ChiSqAcc(*convVertexCandidate) = fit_Psi2S_ChiSq;
480 
481  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi1S_PxAcc("CascadeFit_Upsi1S_Px");
482  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi1S_PyAcc("CascadeFit_Upsi1S_Py");
483  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi1S_PzAcc("CascadeFit_Upsi1S_Pz");
484  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi1S_MAcc("CascadeFit_Upsi1S_M");
485  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi1S_ChiSqAcc("CascadeFit_Upsi1S_ChiSq");
486  CascadeFit_Upsi1S_PxAcc(*convVertexCandidate) = fit_Upsi1S_Px;
487  CascadeFit_Upsi1S_PyAcc(*convVertexCandidate) = fit_Upsi1S_Py;
488  CascadeFit_Upsi1S_PzAcc(*convVertexCandidate) = fit_Upsi1S_Pz;
489  CascadeFit_Upsi1S_MAcc(*convVertexCandidate) = fit_Upsi1S_M;
490  CascadeFit_Upsi1S_ChiSqAcc(*convVertexCandidate) = fit_Upsi1S_ChiSq;
491 
492  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi2S_PxAcc("CascadeFit_Upsi2S_Px");
493  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi2S_PyAcc("CascadeFit_Upsi2S_Py");
494  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi2S_PzAcc("CascadeFit_Upsi2S_Pz");
495  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi2S_MAcc("CascadeFit_Upsi2S_M");
496  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi2S_ChiSqAcc("CascadeFit_Upsi2S_ChiSq");
497  CascadeFit_Upsi2S_PxAcc(*convVertexCandidate) = fit_Upsi2S_Px;
498  CascadeFit_Upsi2S_PyAcc(*convVertexCandidate) = fit_Upsi2S_Py;
499  CascadeFit_Upsi2S_PzAcc(*convVertexCandidate) = fit_Upsi2S_Pz;
500  CascadeFit_Upsi2S_MAcc(*convVertexCandidate) = fit_Upsi2S_M;
501  CascadeFit_Upsi2S_ChiSqAcc(*convVertexCandidate) = fit_Upsi2S_ChiSq;
502 
503  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi3S_PxAcc("CascadeFit_Upsi3S_Px");
504  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi3S_PyAcc("CascadeFit_Upsi3S_Py");
505  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi3S_PzAcc("CascadeFit_Upsi3S_Pz");
506  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi3S_MAcc("CascadeFit_Upsi3S_M");
507  static const SG::Accessor< std::vector<float> > CascadeFit_Upsi3S_ChiSqAcc("CascadeFit_Upsi3S_ChiSq");
508  CascadeFit_Upsi3S_PxAcc(*convVertexCandidate) = fit_Upsi3S_Px;
509  CascadeFit_Upsi3S_PyAcc(*convVertexCandidate) = fit_Upsi3S_Py;
510  CascadeFit_Upsi3S_PzAcc(*convVertexCandidate) = fit_Upsi3S_Pz;
511  CascadeFit_Upsi3S_MAcc(*convVertexCandidate) = fit_Upsi3S_M;
512  CascadeFit_Upsi3S_ChiSqAcc(*convVertexCandidate) = fit_Upsi3S_ChiSq;
513 
514  static const SG::Accessor<float> pxAcc("px");
515  static const SG::Accessor<float> pyAcc("py");
516  static const SG::Accessor<float> pzAcc("pz");
517  pxAcc(*convVertexCandidate) = momentum.x();
518  pyAcc(*convVertexCandidate) = momentum.y();
519  pzAcc(*convVertexCandidate) = momentum.z();
520 
521  static const SG::Accessor<float> deltaCotThetaTrkAcc("deltaCotThetaTrk");
522  static const SG::Accessor<float> minimumDistanceTrkAcc("minimumDistanceTrk");
523  deltaCotThetaTrkAcc(*convVertexCandidate) = deltaCotTheta;
524  minimumDistanceTrkAcc(*convVertexCandidate) = distance;
525 
526  static const SG::Accessor<float> deltaPhiTracksAcc("deltaPhiTracks");
527  static const SG::Accessor<float> DR1R2Acc("DR1R2");
528  deltaPhiTracksAcc(*convVertexCandidate) = vertexOutput["deltaPhiTracks"];
529  DR1R2Acc(*convVertexCandidate) = vertexOutput["DR1R2"];
530 
531  static const SG::Accessor<Char_t> passedAcc("passed");
532  passedAcc(*convVertexCandidate) = true; // Used in event skimming
533 
534  conversionContainer->push_back(convVertexCandidate.release());
535 
536  } else {
537  ATH_MSG_DEBUG("Vertex Fit Failed");
538  }
539 
540  } // Neg Track Loop
541 
542  } // Pos Track Loop
543 
544  } // callConvFinder
545 
546  // Write the results to StoreGate
547  CHECK(evtStore()->record(conversionContainer.release(), m_conversionContainerName));
548  CHECK(evtStore()->record(conversionAuxContainer.release(), m_conversionContainerName+"Aux."));
549 
550  ATH_MSG_DEBUG("-------------------------");
551  ATH_MSG_DEBUG("Number of track pairs: " << nTrackPairs_Init);
552  ATH_MSG_DEBUG("Number of track pairs selected: " << nTrackPairs_Selected);
553  ATH_MSG_DEBUG("Number of successful vertex fits: " << nConv_VertexFit);
554  ATH_MSG_DEBUG("Number of selected vertices: " << nConv_Selected);
555  ATH_MSG_DEBUG("Number of selected vertices (after DeltaM req.): " << nConv_Selected_DeltaM);
556 
557  return StatusCode::SUCCESS;
558  }

◆ doCascadeFit()

StatusCode DerivationFramework::BPhysConversionFinder::doCascadeFit ( const xAOD::Vertex diMuonVertex,
const xAOD::Vertex convVertex,
const double  diMuonMassConstraint,
TLorentzVector &  fitMom,
float &  chiSq 
) const
private

Definition at line 560 of file BPhysConversionFinder.cxx.

560  {
561 
562  std::vector<const xAOD::TrackParticle*> diMuonTracks;
563  diMuonTracks.push_back(diMuonVertex->trackParticle(0));
564  diMuonTracks.push_back(diMuonVertex->trackParticle(1));
565 
566  std::vector<double> diMuonTrackMasses;
567  diMuonTrackMasses.push_back(105.658);
568  diMuonTrackMasses.push_back(105.658);
569 
570  std::vector<const xAOD::TrackParticle*> convTracks;
571  convTracks.push_back(convVertex->trackParticle(0));
572  convTracks.push_back(convVertex->trackParticle(1));
573 
574  std::vector<double> convTrackMasses;
575  convTrackMasses.push_back(0.511);
576  convTrackMasses.push_back(0.511);
577 
578  // Reset
579  std::unique_ptr<Trk::IVKalState> state = m_cascadeFitter->makeState();
580 
581  // Set Robustness
582  m_cascadeFitter->setRobustness(0, *state);
583 
584  // Build up the topology
585 
586  // Vertex list
587  std::vector<Trk::VertexID> vrtList;
588  // V0 vertex
589  Trk::VertexID vID;
590  vID = m_cascadeFitter->startVertex(convTracks,convTrackMasses,*state,0.0); // Constrain converision mass to zero
591 
592  vrtList.push_back(vID);
593 
594  // chi_c/b vertex
595  Trk::VertexID vID2 = m_cascadeFitter->nextVertex(diMuonTracks,diMuonTrackMasses,vrtList,*state);
596 
597  std::vector<Trk::VertexID> cnstV;
598  cnstV.clear();
599  if ( !m_cascadeFitter->addMassConstraint(vID2,diMuonTracks,cnstV,*state,diMuonMassConstraint).isSuccess() ) {
600  ATH_MSG_WARNING("addMassConstraint failed");
601  }
602 
603  // Do the fit
604  std::unique_ptr<Trk::VxCascadeInfo> result(m_cascadeFitter->fitCascade(*state));
605 
606  const std::vector< std::vector<TLorentzVector> > &moms = result->getParticleMoms();
607 
608  {
609 
610  if(moms.size() > 2) ATH_MSG_WARNING("DoCascadeFit - More than two output momentum!?");
611 
612  TLorentzVector conv_Fit = moms.at(0).at(0) + moms.at(0).at(1);
613  TLorentzVector diMuon_Fit = moms.at(1).at(0) + moms.at(1).at(1);
614 
615  // Momentum of DiMuon + photon system
616  fitMom = diMuon_Fit + conv_Fit;
617 
618  chiSq = result->fitChi2()/result->nDoF();
619 
620  // Done with the fit result
621  result.reset();
622 
623  }
624 
625  return StatusCode::SUCCESS;
626 
627  }

◆ finalize()

StatusCode DerivationFramework::BPhysConversionFinder::finalize ( )
override

Definition at line 78 of file BPhysConversionFinder.cxx.

79  {
80  // everything all right
81  return StatusCode::SUCCESS;
82  }

◆ initialize()

StatusCode DerivationFramework::BPhysConversionFinder::initialize ( )
override

Definition at line 60 of file BPhysConversionFinder.cxx.

61  {
62 
63  ATH_MSG_DEBUG("in initialize()");
64 
65  ATH_CHECK( m_v0Tools.retrieve() );
66  ATH_CHECK( m_vertexFitter.retrieve() );
67  ATH_CHECK( m_vertexEstimator.retrieve() );
68  ATH_CHECK( m_distanceTool.retrieve() );
69  ATH_CHECK( m_postSelector.retrieve() );
70  ATH_CHECK( m_cascadeFitter.retrieve() );
71 
72  return StatusCode::SUCCESS;
73 
74  }

Member Data Documentation

◆ m_cascadeFitter

ToolHandle<Trk::TrkVKalVrtFitter > DerivationFramework::BPhysConversionFinder::m_cascadeFitter
private

Definition at line 56 of file BPhysConversionFinder.h.

◆ m_conversionContainerName

std::string DerivationFramework::BPhysConversionFinder::m_conversionContainerName
private

Definition at line 59 of file BPhysConversionFinder.h.

◆ m_diMuonCollectionToCheck

std::string DerivationFramework::BPhysConversionFinder::m_diMuonCollectionToCheck
private

Definition at line 48 of file BPhysConversionFinder.h.

◆ m_distanceTool

ToolHandle<Trk::ITrkDistanceFinder> DerivationFramework::BPhysConversionFinder::m_distanceTool
private

Definition at line 54 of file BPhysConversionFinder.h.

◆ m_inputTrackParticleContainerName

std::string DerivationFramework::BPhysConversionFinder::m_inputTrackParticleContainerName
private

Definition at line 58 of file BPhysConversionFinder.h.

◆ m_maxDeltaCotTheta

float DerivationFramework::BPhysConversionFinder::m_maxDeltaCotTheta
private

Definition at line 62 of file BPhysConversionFinder.h.

◆ m_maxDeltaM

float DerivationFramework::BPhysConversionFinder::m_maxDeltaM
private

Definition at line 65 of file BPhysConversionFinder.h.

◆ m_maxDistBetweenTracks

float DerivationFramework::BPhysConversionFinder::m_maxDistBetweenTracks
private

Definition at line 61 of file BPhysConversionFinder.h.

◆ m_passFlagsToCheck

std::vector<std::string> DerivationFramework::BPhysConversionFinder::m_passFlagsToCheck
private

Definition at line 49 of file BPhysConversionFinder.h.

◆ m_postSelector

ToolHandle<InDet::ConversionPostSelector> DerivationFramework::BPhysConversionFinder::m_postSelector
private

Definition at line 55 of file BPhysConversionFinder.h.

◆ m_requireDeltaM

bool DerivationFramework::BPhysConversionFinder::m_requireDeltaM
private

Definition at line 64 of file BPhysConversionFinder.h.

◆ m_v0Tools

ToolHandle<Trk::V0Tools> DerivationFramework::BPhysConversionFinder::m_v0Tools
private

Definition at line 51 of file BPhysConversionFinder.h.

◆ m_vertexEstimator

ToolHandle<InDet::VertexPointEstimator> DerivationFramework::BPhysConversionFinder::m_vertexEstimator
private

Definition at line 53 of file BPhysConversionFinder.h.

◆ m_vertexFitter

ToolHandle<Trk::IVertexFitter> DerivationFramework::BPhysConversionFinder::m_vertexFitter
private

Definition at line 52 of file BPhysConversionFinder.h.


The documentation for this class was generated from the following files:
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
DerivationFramework::BPhysConversionFinder::m_v0Tools
ToolHandle< Trk::V0Tools > m_v0Tools
Definition: BPhysConversionFinder.h:51
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
get_generator_info.result
result
Definition: get_generator_info.py:21
xAOD::VertexAuxContainer_v1
Temporary container used until we have I/O for AuxStoreInternal.
Definition: VertexAuxContainer_v1.h:32
Trk::VertexID
int VertexID
Definition: IVertexCascadeFitter.h:23
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
DerivationFramework::BPhysConversionFinder::m_conversionContainerName
std::string m_conversionContainerName
Definition: BPhysConversionFinder.h:59
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
DerivationFramework::BPhysConversionFinder::m_maxDistBetweenTracks
float m_maxDistBetweenTracks
Definition: BPhysConversionFinder.h:61
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
DerivationFramework::BPhysConversionFinder::m_diMuonCollectionToCheck
std::string m_diMuonCollectionToCheck
Definition: BPhysConversionFinder.h:48
xAOD::numberOfPixelHits
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Definition: TrackingPrimitives.h:260
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
DerivationFramework::BPhysConversionFinder::doCascadeFit
StatusCode doCascadeFit(const xAOD::Vertex *diMuonVertex, const xAOD::Vertex *convVertex, const double diMuonMassConstraint, TLorentzVector &fitMom, float &chiSq) const
Definition: BPhysConversionFinder.cxx:560
DerivationFramework::BPhysConversionFinder::m_distanceTool
ToolHandle< Trk::ITrkDistanceFinder > m_distanceTool
Definition: BPhysConversionFinder.h:54
DerivationFramework::BPhysConversionFinder::m_cascadeFitter
ToolHandle< Trk::TrkVKalVrtFitter > m_cascadeFitter
Definition: BPhysConversionFinder.h:56
xAOD::TrackParticle_v1::perigeeParameters
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
Definition: TrackParticle_v1.cxx:485
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
DerivationFramework::BPhysConversionFinder::m_vertexFitter
ToolHandle< Trk::IVertexFitter > m_vertexFitter
Definition: BPhysConversionFinder.h:52
DerivationFramework::BPhysConversionFinder::m_passFlagsToCheck
std::vector< std::string > m_passFlagsToCheck
Definition: BPhysConversionFinder.h:49
ParticleGun_EoverP_Config.momentum
momentum
Definition: ParticleGun_EoverP_Config.py:63
beamspotman.n
n
Definition: beamspotman.py:731
Trk::theta
@ theta
Definition: ParamDefs.h:66
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
master.flag
bool flag
Definition: master.py:29
AthenaPoolTestRead.acc
acc
Definition: AthenaPoolTestRead.py:16
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
xAOD::Vertex_v1::trackParticle
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
Definition: Vertex_v1.cxx:249
SG::AuxElement::index
size_t index() const
Return the index of this element within its container.
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
DerivationFramework::BPhysConversionFinder::m_requireDeltaM
bool m_requireDeltaM
Definition: BPhysConversionFinder.h:64
DerivationFramework::BPhysConversionFinder::m_vertexEstimator
ToolHandle< InDet::VertexPointEstimator > m_vertexEstimator
Definition: BPhysConversionFinder.h:53
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
DerivationFramework::BPhysConversionFinder::m_postSelector
ToolHandle< InDet::ConversionPostSelector > m_postSelector
Definition: BPhysConversionFinder.h:55
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
xAOD::photon
@ photon
Definition: TrackingPrimitives.h:200
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DerivationFramework::BPhysConversionFinder::m_inputTrackParticleContainerName
std::string m_inputTrackParticleContainerName
Definition: BPhysConversionFinder.h:58
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:269
DerivationFramework::BPhysConversionFinder::m_maxDeltaCotTheta
float m_maxDeltaCotTheta
Definition: BPhysConversionFinder.h:62
DerivationFramework::BPhysConversionFinder::m_maxDeltaM
float m_maxDeltaM
Definition: BPhysConversionFinder.h:65
xAOD::track
@ track
Definition: TrackingPrimitives.h:513
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.