Belle II Software  release-06-01-15
V0Fitter.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include <tracking/v0Finding/fitter/V0Fitter.h>
9 
10 #include <framework/logging/Logger.h>
11 #include <framework/datastore/StoreArray.h>
12 #include <tracking/v0Finding/dataobjects/VertexVector.h>
13 #include <tracking/dataobjects/RecoTrack.h>
14 #include <tracking/trackFitting/fitter/base/TrackFitter.h>
15 #include <tracking/trackFitting/trackBuilder/factories/TrackBuilder.h>
16 
17 #include <mdst/dataobjects/HitPatternVXD.h>
18 #include <mdst/dataobjects/HitPatternCDC.h>
19 #include <mdst/dataobjects/Track.h>
20 #include <mdst/dataobjects/TrackFitResult.h>
21 #include <cdc/dataobjects/CDCRecoHit.h>
22 #include <pxd/reconstruction/PXDRecoHit.h>
23 #include <svd/reconstruction/SVDRecoHit.h>
24 #include <svd/reconstruction/SVDRecoHit2D.h>
25 
26 #include <genfit/Track.h>
27 #include <genfit/TrackPoint.h>
28 #include <genfit/MeasuredStateOnPlane.h>
29 #include <genfit/GFRaveVertexFactory.h>
30 #include <genfit/GFRaveVertex.h>
31 #include <genfit/FieldManager.h>
32 #include <genfit/MaterialEffects.h>
33 #include <genfit/FitStatus.h>
34 #include <genfit/KalmanFitStatus.h>
35 #include <genfit/KalmanFitterInfo.h>
36 
37 #include <framework/utilities/IOIntercept.h>
38 
39 using namespace Belle2;
40 
41 V0Fitter::V0Fitter(const std::string& trackFitResultsName, const std::string& v0sName,
42  const std::string& v0ValidationVerticesName, const std::string& recoTracksName,
43  const std::string& copiedRecoTracksName, bool enableValidation)
44  : m_validation(enableValidation), m_recoTracksName(recoTracksName), m_v0FitterMode(1), m_forcestore(false),
45  m_useOnlyOneSVDHitPair(true)
46 {
47  m_trackFitResults.isRequired(trackFitResultsName);
49  //Relation to RecoTracks from Tracks is already tested at the module level.
50 
51  if (m_validation) {
52  B2DEBUG(24, "Register DataStore for validation.");
53  m_validationV0s.registerInDataStore(v0ValidationVerticesName, DataStore::c_ErrorIfAlreadyRegistered);
54  m_v0s.registerRelationTo(m_validationV0s);
55  }
56 
58  m_recoTracks.isRequired(m_recoTracksName);
59 
61  m_copiedRecoTracks.registerInDataStore(copiedRecoTracksName,
64 
66  m_copiedRecoTracks.registerRelationTo(m_recoTracks);
67 
68 
69  B2ASSERT("Material effects not set up. Please use SetupGenfitExtrapolationModule.",
70  genfit::MaterialEffects::getInstance()->isInitialized());
71  B2ASSERT("Magnetic field not set up. Please use SetupGenfitExtrapolationModule.",
72  genfit::FieldManager::getInstance()->isInitialized());
73 }
74 
75 void V0Fitter::setFitterMode(int fitterMode)
76 {
77  if (not(0 <= fitterMode && fitterMode <= 2)) {
78  B2FATAL("Invalid fitter mode!");
79  } else {
80  m_v0FitterMode = fitterMode;
81  if (fitterMode == 0)
82  m_forcestore = true;
83  else
84  m_forcestore = false;
85  if (fitterMode == 2)
86  m_useOnlyOneSVDHitPair = false;
87  else
89  }
90 }
91 
92 void V0Fitter::initializeCuts(double beamPipeRadius,
93  double vertexChi2CutOutside,
94  std::tuple<double, double> invMassRangeKshort,
95  std::tuple<double, double> invMassRangeLambda,
96  std::tuple<double, double> invMassRangePhoton)
97 {
98  m_beamPipeRadius = beamPipeRadius;
99  m_vertexChi2CutOutside = vertexChi2CutOutside;
100  m_invMassRangeKshort = invMassRangeKshort;
101  m_invMassRangeLambda = invMassRangeLambda;
102  m_invMassRangePhoton = invMassRangePhoton;
103 }
104 
105 
107 {
108  VertexVector vertexVector;
109  std::vector<genfit::Track*> trackPair {&trackPlus, &trackMinus};
110 
111  try {
113  logCapture("V0Fitter GFRaveVertexFactory", LogConfig::c_Debug, LogConfig::c_Debug);
114  logCapture.start();
115 
116  genfit::GFRaveVertexFactory vertexFactory;
117  vertexFactory.findVertices(&vertexVector.v, trackPair);
118  } catch (...) {
119  B2ERROR("Exception during vertex fit.");
120  return false;
121  }
122 
123  if (vertexVector.size() != 1) {
124  B2DEBUG(21, "Vertex fit failed. Size of vertexVector not 1, but: " << vertexVector.size());
125  return false;
126  }
127 
128  if ((*vertexVector[0]).getNTracks() != 2) {
129  B2DEBUG(20, "Wrong number of tracks in vertex.");
130  return false;
131  }
132 
133  vertex = *vertexVector[0];
134  return true;
135 }
136 
140  const TVector3& vertexPosition, unsigned int& hasInnerHitStatus)
141 {
143  hasInnerHitStatus = 0;
144 
145  try {
148  double extralengthPlus = stPlus.extrapolateToPoint(vertexPosition);
149  double extralengthMinus = stMinus.extrapolateToPoint(vertexPosition);
150  if (extralengthPlus > 0) hasInnerHitStatus |= 0x1;
151  if (extralengthMinus > 0) hasInnerHitStatus |= 0x2;
152  B2DEBUG(22, "extralengthPlus=" << extralengthPlus << ", extralengthMinus=" << extralengthMinus);
153  } catch (...) {
157  B2DEBUG(22, "Could not extrapolate track to vertex.");
158  return false;
159  }
160  return true;
161 }
162 
163 double V0Fitter::getBzAtVertex(const TVector3& vertexPosition)
164 {
165  double Bx, By, Bz;
166  genfit::FieldManager::getInstance()->getFieldVal(vertexPosition.X(), vertexPosition.Y(), vertexPosition.Z(),
167  Bx, By, Bz);
168  Bz = Bz / 10;
169  return Bz;
170 }
171 
172 
174  const genfit::MeasuredStateOnPlane& msop, const double Bz,
175  const Const::ParticleType& trackHypothesis,
176  const int sharedInnermostCluster)
177 {
178  const uint64_t hitPatternCDCInitializer = TrackBuilder::getHitPatternCDCInitializer(*recoTrack);
179  uint32_t hitPatternVXDInitializer = TrackBuilder::getHitPatternVXDInitializer(*recoTrack);
180 
181  // If the innermost hit is shared among V0 daughters, assign flag in the infoLayer.
182  if (sharedInnermostCluster > 0 && sharedInnermostCluster < 4) {
183  HitPatternVXD hitPatternVXD_forflag = HitPatternVXD(hitPatternVXDInitializer);
184  hitPatternVXD_forflag.setInnermostHitShareStatus(sharedInnermostCluster);
185  hitPatternVXDInitializer = hitPatternVXD_forflag.getInteger();
186  }
187 
188  TrackFitResult* v0TrackFitResult
189  = m_trackFitResults.appendNew(msop.getPos(), msop.getMom(),
190  msop.get6DCov(), msop.getCharge(),
191  trackHypothesis,
192  track.getFitStatus()->getPVal(),
193  Bz, hitPatternCDCInitializer, hitPatternVXDInitializer, track.getFitStatus()->getNdf());
194  return v0TrackFitResult;
195 }
196 
197 std::pair<Const::ParticleType, Const::ParticleType> V0Fitter::getTrackHypotheses(const Const::ParticleType& v0Hypothesis) const
198 {
199  if (v0Hypothesis == Const::Kshort) {
200  return std::make_pair(Const::pion, Const::pion);
201  } else if (v0Hypothesis == Const::photon) {
202  return std::make_pair(Const::electron, Const::electron);
203  } else if (v0Hypothesis == Const::Lambda) {
204  return std::make_pair(Const::proton, Const::pion);
205  } else if (v0Hypothesis == Const::antiLambda) {
206  return std::make_pair(Const::pion, Const::proton);
207  }
208  B2FATAL("Given V0Hypothesis not available.");
209  return std::make_pair(Const::invalidParticle, Const::invalidParticle); // return something to avoid triggering cppcheck
210 }
211 
213 bool V0Fitter::fitAndStore(const Track* trackPlus, const Track* trackMinus,
214  const Const::ParticleType& v0Hypothesis,
215  bool& isForceStored, bool& isHitRemoved)
216 {
218  isForceStored = false;
219  isHitRemoved = false;
220 
222  RecoTrack* recoTrackPlus = trackPlus->getRelated<RecoTrack>(m_recoTracksName);
223  RecoTrack* recoTrackMinus = trackMinus->getRelated<RecoTrack>(m_recoTracksName);
224 
228  unsigned int hasInnerHitStatus = 0;
229 
231  TVector3 vertexPos(0, 0, 0);
232 
238  if (not vertexFitWithRecoTracks(trackPlus, trackMinus, recoTrackPlus, recoTrackMinus, v0Hypothesis,
239  hasInnerHitStatus, vertexPos, m_forcestore))
240  return false;
241 
242  if ((hasInnerHitStatus == 0) or m_forcestore)
243  return true;
244 
249  bool failflag = false;
251  const auto trackHypotheses = getTrackHypotheses(v0Hypothesis);
252  const int pdg_trackPlus = trackPlus->getTrackFitResultWithClosestMass(
253  trackHypotheses.first)->getParticleType().getPDGCode();
254  const int pdg_trackMinus = trackMinus->getTrackFitResultWithClosestMass(
255  trackHypotheses.second)->getParticleType().getPDGCode();
256 
257  RecoTrack* recoTrackPlus_forRefit = nullptr;
258  RecoTrack* recoTrackMinus_forRefit = nullptr;
259  RecoTrack* cache_recoTrackPlus = nullptr;
260  RecoTrack* cache_recoTrackMinus = nullptr;
261 
262  unsigned int count_removeInnerHits = 0;
263  while (hasInnerHitStatus != 0) {
264  ++count_removeInnerHits;
267 
269  if (hasInnerHitStatus & 0x1) {
270  // create a copy of the original RecoTrack w/o track fit
271  recoTrackPlus_forRefit = copyRecoTrack(recoTrackPlus);
272  if (recoTrackPlus_forRefit == nullptr)
273  return false;
276  if (!cache_recoTrackPlus) {
277  if (not removeInnerHits(recoTrackPlus, recoTrackPlus_forRefit, pdg_trackPlus, vertexPos)) {
278  failflag = true;
279  break;
280  }
281  } else {
282  if (not removeInnerHits(cache_recoTrackPlus, recoTrackPlus_forRefit, pdg_trackPlus, vertexPos)) {
283  failflag = true;
284  break;
285  }
286  }
287  cache_recoTrackPlus = recoTrackPlus_forRefit;
288  } else if (recoTrackPlus_forRefit == nullptr) {
289  // create a copy of the original RecoTrack w/ track fit (only once)
290  recoTrackPlus_forRefit = copyRecoTrackAndFit(recoTrackPlus, pdg_trackPlus);
291  if (recoTrackPlus_forRefit == nullptr)
292  return false;
293  }
294 
296  if (hasInnerHitStatus & 0x2) {
297  // create a copy of the original RecoTrack w/o track fit
298  recoTrackMinus_forRefit = copyRecoTrack(recoTrackMinus);
299  if (recoTrackMinus_forRefit == nullptr)
300  return false;
303  if (!cache_recoTrackMinus) {
304  if (not removeInnerHits(recoTrackMinus, recoTrackMinus_forRefit, pdg_trackMinus, vertexPos)) {
305  failflag = true;
306  break;
307  }
308  } else {
309  if (not removeInnerHits(cache_recoTrackMinus, recoTrackMinus_forRefit, pdg_trackMinus, vertexPos)) {
310  failflag = true;
311  break;
312  }
313  }
314  cache_recoTrackMinus = recoTrackMinus_forRefit;
315  } else if (recoTrackMinus_forRefit == nullptr) {
316  // create a copy of the original RecoTrack w/ track fit (only once)
317  recoTrackMinus_forRefit = copyRecoTrackAndFit(recoTrackMinus, pdg_trackMinus);
318  if (recoTrackMinus_forRefit == nullptr)
319  return false;
320  }
321 
323  hasInnerHitStatus = 0;
326  if (not vertexFitWithRecoTracks(trackPlus, trackMinus, recoTrackPlus_forRefit, recoTrackMinus_forRefit,
327  v0Hypothesis, hasInnerHitStatus, vertexPos, false)) {
328  B2DEBUG(22, "Vertex refit failed, or rejected by invariant mass cut.");
329  failflag = true;
330  break;
331  } else if (hasInnerHitStatus == 0)
332  isHitRemoved = true;
333  if (count_removeInnerHits >= 5) {
334  B2WARNING("Inner hits remained after " << count_removeInnerHits << " times of removing inner hits!");
335  failflag = true;
336  break;
337  }
338  }
339 
341  if (failflag) {
342  bool forcestore = true;
343  if (not vertexFitWithRecoTracks(trackPlus, trackMinus, recoTrackPlus, recoTrackMinus, v0Hypothesis,
344  hasInnerHitStatus, vertexPos, forcestore)) {
345  B2DEBUG(22, "Original vertex fit fails. Possibly rejected by invariant mass cut.");
346  return false;
347  } else
348  isForceStored = true;
349  }
350 
351  return true;
352 }
353 
356 bool V0Fitter::vertexFitWithRecoTracks(const Track* trackPlus, const Track* trackMinus,
357  RecoTrack* recoTrackPlus, RecoTrack* recoTrackMinus,
358  const Const::ParticleType& v0Hypothesis,
359  unsigned int& hasInnerHitStatus, TVector3& vertexPos,
360  const bool forceStore)
361 {
362  const auto trackHypotheses = getTrackHypotheses(v0Hypothesis);
363 
365  *recoTrackPlus);
366  const int pdgTrackPlus = trackPlus->getTrackFitResultWithClosestMass(trackHypotheses.first)->getParticleType().getPDGCode();
367  genfit::AbsTrackRep* plusRepresentation = recoTrackPlus->getTrackRepresentationForPDG(pdgTrackPlus);
368  if ((plusRepresentation == nullptr) or (not recoTrackPlus->wasFitSuccessful(plusRepresentation))) {
369  B2ERROR("Track hypothesis with closest mass not available. Should never happen, but I can continue savely anyway.");
370  return false;
371  }
372 
374  *recoTrackMinus);
375  const int pdgTrackMinus = trackMinus->getTrackFitResultWithClosestMass(trackHypotheses.second)->getParticleType().getPDGCode();
376  genfit::AbsTrackRep* minusRepresentation = recoTrackMinus->getTrackRepresentationForPDG(pdgTrackMinus);
377  if ((minusRepresentation == nullptr) or (not recoTrackMinus->wasFitSuccessful(minusRepresentation))) {
378  B2ERROR("Track hypothesis with closest mass not available. Should never happen, but I can continue savely anyway.");
379  return false;
380  }
381 
383  std::vector<genfit::AbsTrackRep*> repsPlus = gfTrackPlus.getTrackReps();
384  std::vector<genfit::AbsTrackRep*> repsMinus = gfTrackMinus.getTrackReps();
385  if (repsPlus.size() == repsMinus.size()) {
386  for (unsigned int id = 0; id < repsPlus.size(); id++) {
387  if (abs(repsPlus[id]->getPDG()) == pdgTrackPlus)
388  gfTrackPlus.setCardinalRep(id);
389  if (abs(repsMinus[id]->getPDG()) == pdgTrackMinus)
390  gfTrackMinus.setCardinalRep(id);
391  }
392  }
394  else {
395  for (unsigned int id = 0; id < repsPlus.size(); id++) {
396  if (abs(repsPlus[id]->getPDG()) == pdgTrackPlus)
397  gfTrackPlus.setCardinalRep(id);
398  }
399  for (unsigned int id = 0; id < repsMinus.size(); id++) {
400  if (abs(repsMinus[id]->getPDG()) == pdgTrackMinus)
401  gfTrackMinus.setCardinalRep(id);
402  }
403  }
404 
406  genfit::MeasuredStateOnPlane stPlus = recoTrackPlus->getMeasuredStateOnPlaneFromFirstHit(plusRepresentation);
407  genfit::MeasuredStateOnPlane stMinus = recoTrackMinus->getMeasuredStateOnPlaneFromFirstHit(minusRepresentation);
408 
410  if (not fitGFRaveVertex(gfTrackPlus, gfTrackMinus, vert)) {
411  return false;
412  }
413 
414  const TVector3& posVert(vert.getPos());
415  vertexPos = posVert;
416 
419  if (posVert.Perp() < m_beamPipeRadius) {
420  return false;
421  } else {
422  if (vert.getChi2() > m_vertexChi2CutOutside) {
423  B2DEBUG(22, "Vertex outside beam pipe, chi^2 too large.");
424  return false;
425  }
426  }
427 
428  B2DEBUG(22, "Vertex accepted.");
429 
430  if (not extrapolateToVertex(stPlus, stMinus, posVert, hasInnerHitStatus)) {
431  return false;
432  }
433 
435  if (forceStore || hasInnerHitStatus == 0) {
437  const genfit::GFRaveTrackParameters* tr0 = vert.getParameters(0);
438  const genfit::GFRaveTrackParameters* tr1 = vert.getParameters(1);
439  TLorentzVector lv0, lv1;
441  lv0.SetVectM(tr0->getMom(), trackHypotheses.first.getMass());
442  lv1.SetVectM(tr1->getMom(), trackHypotheses.second.getMass());
443  double v0InvMass = (lv0 + lv1).M();
444  if (v0Hypothesis == Const::Kshort) {
445  if (v0InvMass < std::get<0>(m_invMassRangeKshort) || v0InvMass > std::get<1>(m_invMassRangeKshort)) {
446  B2DEBUG(22, "Kshort vertex rejected, invariant mass out of range.");
447  return false;
448  }
449  } else if (v0Hypothesis == Const::Lambda || v0Hypothesis == Const::antiLambda) {
450  if (v0InvMass < std::get<0>(m_invMassRangeLambda) || v0InvMass > std::get<1>(m_invMassRangeLambda)) {
451  B2DEBUG(22, "Lambda vertex rejected, invariant mass out of range.");
452  return false;
453  }
454  } else if (v0Hypothesis == Const::photon) {
455  if (v0InvMass < std::get<0>(m_invMassRangePhoton) || v0InvMass > std::get<1>(m_invMassRangePhoton)) {
456  B2DEBUG(22, "Photon vertex rejected, invariant mass out of range.");
457  return false;
458  }
459  }
460 
461 
465  const TVector3 origin(0, 0, 0);
466  const double Bz = getBzAtVertex(origin);
467 
468  int sharedInnermostCluster = checkSharedInnermostCluster(recoTrackPlus, recoTrackMinus);
469 
470  TrackFitResult* tfrPlusVtx = buildTrackFitResult(gfTrackPlus, recoTrackPlus, stPlus, Bz, trackHypotheses.first,
471  sharedInnermostCluster);
472  TrackFitResult* tfrMinusVtx = buildTrackFitResult(gfTrackMinus, recoTrackMinus, stMinus, Bz, trackHypotheses.second,
473  sharedInnermostCluster);
474 
475  B2DEBUG(20, "Creating new V0.");
476  auto v0 = m_v0s.appendNew(std::make_pair(trackPlus, tfrPlusVtx),
477  std::make_pair(trackMinus, tfrMinusVtx));
478 
479  if (m_validation) {
480  B2DEBUG(24, "Create StoreArray and Output for validation.");
481  auto validationV0 = m_validationV0s.appendNew(
482  std::make_pair(trackPlus, tfrPlusVtx),
483  std::make_pair(trackMinus, tfrMinusVtx),
484  vert.getPos(),
485  vert.getCov(),
486  (lv0 + lv1).P(),
487  (lv0 + lv1).M(),
488  vert.getChi2()
489  );
490  v0->addRelationTo(validationV0);
491  }
492  }
493  return true;
494 }
495 
497 {
498  RecoTrack* newRecoTrack = origRecoTrack->copyToStoreArray(m_copiedRecoTracks);
499  newRecoTrack->addHitsFromRecoTrack(origRecoTrack);
500  newRecoTrack->addRelationTo(origRecoTrack);
501  return newRecoTrack;
502 }
503 
504 RecoTrack* V0Fitter::copyRecoTrackAndFit(RecoTrack* origRecoTrack, const int trackPDG)
505 {
507  Const::ChargedStable particleUsedForFitting(std::abs(trackPDG));
508  const genfit::AbsTrackRep* origTrackRep = origRecoTrack->getTrackRepresentationForPDG(std::abs(
509  trackPDG));
510 
511  RecoTrack* newRecoTrack = copyRecoTrack(origRecoTrack);
512 
514  TrackFitter fitter;
515  if (not fitter.fit(*newRecoTrack, particleUsedForFitting)) {
516  // This is not expected, but happens sometimes.
517  B2DEBUG(20, "track fit failed for copied RecoTrack.");
519  if (not origRecoTrack->wasFitSuccessful(origTrackRep))
520  B2DEBUG(20, "\t original track fit was also failed.");
521  return nullptr;
522  }
523 
524  return newRecoTrack;
525 }
526 
527 bool V0Fitter::removeInnerHits(RecoTrack* prevRecoTrack, RecoTrack* recoTrack,
528  const int trackPDG, const TVector3& vertexPosition)
529 {
530  if (!prevRecoTrack || !recoTrack) {
531  B2ERROR("Input recotrack is nullptr!");
532  return false;
533  }
535  Const::ChargedStable particleUsedForFitting(std::abs(trackPDG));
536  const genfit::AbsTrackRep* prevTrackRep = prevRecoTrack->getTrackRepresentationForPDG(std::abs(
537  trackPDG));
538 
540  const std::vector<RecoHitInformation*>& recoHitInformations = recoTrack->getRecoHitInformations(true);
541  const std::vector<RecoHitInformation*>& prevRecoHitInformations = prevRecoTrack->getRecoHitInformations(
542  true);
543  unsigned int nRemoveHits = 0;
544  if (recoHitInformations.size() != prevRecoHitInformations.size()) {
545  B2WARNING("Copied RecoTrack has different number of hits from its original RecoTrack!");
546  return false;
547  }
549  for (nRemoveHits = 0; nRemoveHits < recoHitInformations.size(); ++nRemoveHits) {
550  if (!prevRecoHitInformations[nRemoveHits]->useInFit()) {
551  recoHitInformations[nRemoveHits]->setUseInFit(false);
552  continue;
553  }
554  try {
557  prevRecoHitInformations[nRemoveHits]);
560  double extralength = stPrevRecoHit.extrapolateToPoint(vertexPosition);
561  if (extralength > 0) {
562  recoHitInformations[nRemoveHits]->setUseInFit(false);
563  } else
564  break;
565  } catch (NoTrackFitResult()) {
566  B2WARNING("Exception: no FitterInfo assigned for TrackPoint created from this RecoHit.");
567  recoHitInformations[nRemoveHits]->setUseInFit(false);
568  continue;
569  } catch (...) {
573  B2DEBUG(22, "Could not extrapolate track to vertex when removing inner hits, aborting.");
574  return false;
575  }
576  }
577 
578  if (nRemoveHits == 0) {
579  // This is not expected, but can happen if the track fit is different between copied and original RecoTrack.
580  B2DEBUG(20, "No hits removed in removeInnerHits, aborted. Switching to use the original RecoTrack.");
581  return false;
582  }
583 
584  if (recoHitInformations.size() <= nRemoveHits) {
585  B2DEBUG(20, "Removed all the RecoHits in the RecoTrack, aborted. Switching to use the original RecoTrack.");
586  return false;
587  }
588 
591  if (recoHitInformations[nRemoveHits - 1]->getTrackingDetector() == RecoHitInformation::RecoHitDetector::c_SVD) {
592  if (recoHitInformations[nRemoveHits]->getTrackingDetector() == RecoHitInformation::RecoHitDetector::c_SVD) {
593  const SVDCluster* lastRemovedSVDHit = recoHitInformations[nRemoveHits - 1]->getRelatedTo<SVDCluster>();
594  const SVDCluster* nextSVDHit = recoHitInformations[nRemoveHits] ->getRelatedTo<SVDCluster>();
595  if (!lastRemovedSVDHit || !nextSVDHit) B2ERROR("Last/Next SVD hit is null!");
596  else {
597  if (lastRemovedSVDHit->getSensorID() == nextSVDHit->getSensorID() &&
598  lastRemovedSVDHit->isUCluster() && !(nextSVDHit->isUCluster())) {
599  recoHitInformations[nRemoveHits]->setUseInFit(false);
600  ++nRemoveHits;
601  }
602  }
603  }
604  }
605 
607  if (!m_useOnlyOneSVDHitPair &&
608  recoHitInformations[nRemoveHits - 1]->getTrackingDetector() == RecoHitInformation::RecoHitDetector::c_SVD &&
609  recoHitInformations.size() > nRemoveHits + 2) {
610  if (recoHitInformations[nRemoveHits ]->getTrackingDetector() == RecoHitInformation::RecoHitDetector::c_SVD &&
611  recoHitInformations[nRemoveHits + 1]->getTrackingDetector() == RecoHitInformation::RecoHitDetector::c_SVD &&
612  recoHitInformations[nRemoveHits + 2]->getTrackingDetector() != RecoHitInformation::RecoHitDetector::c_SVD) {
613  recoHitInformations[nRemoveHits ]->setUseInFit(false);
614  recoHitInformations[nRemoveHits + 1]->setUseInFit(false);
615  nRemoveHits += 2;
616  }
617  }
618 
619  B2DEBUG(22, nRemoveHits << " inner hits removed.");
620 
622  TrackFitter fitter;
623  if (not fitter.fit(*recoTrack, particleUsedForFitting)) {
624  B2DEBUG(20, "track fit failed after removing inner hits.");
626  if (not prevRecoTrack->wasFitSuccessful(prevTrackRep))
627  B2DEBUG(20, "\t previous track fit was also failed.");
628  return false;
629  }
630 
631  return true;
632 }
633 
634 int V0Fitter::checkSharedInnermostCluster(const RecoTrack* recoTrackPlus, const RecoTrack* recoTrackMinus)
635 {
638  int flag = 0; // -1 for exception
639 
640  // get the innermost hit for plus/minus-daughter
641  const std::vector<RecoHitInformation*>& recoHitInformationsPlus = recoTrackPlus->getRecoHitInformations(
642  true); // true for sorted info.
643  const std::vector<RecoHitInformation*>& recoHitInformationsMinus = recoTrackMinus->getRecoHitInformations(
644  true);// true for sorted info.
645  unsigned int iInnermostHitPlus, iInnermostHitMinus;
646  for (iInnermostHitPlus = 0 ; iInnermostHitPlus < recoHitInformationsPlus.size() ; ++iInnermostHitPlus)
647  if (recoHitInformationsPlus[iInnermostHitPlus]->useInFit()) break;
648  for (iInnermostHitMinus = 0 ; iInnermostHitMinus < recoHitInformationsMinus.size() ; ++iInnermostHitMinus)
649  if (recoHitInformationsMinus[iInnermostHitMinus]->useInFit()) break;
650  if (iInnermostHitPlus == recoHitInformationsPlus.size() || iInnermostHitMinus == recoHitInformationsMinus.size()) {
651  B2WARNING("checkSharedInnermostCluster function called for recoTrack including no hit used for fit! This should not happen!");
652  return -1;
653  }
654  const auto& recoHitInfoPlus = recoHitInformationsPlus[iInnermostHitPlus];
655  const auto& recoHitInfoMinus = recoHitInformationsMinus[iInnermostHitMinus];
656 
657  if (recoHitInfoPlus->getTrackingDetector() == recoHitInfoMinus->getTrackingDetector()) {
658  if (recoHitInfoPlus->getTrackingDetector() == RecoHitInformation::c_PXD) {
659  const PXDCluster* clusterPlus = recoHitInfoPlus->getRelatedTo<PXDCluster>();
660  const PXDCluster* clusterMinus = recoHitInfoMinus->getRelatedTo<PXDCluster>();
661  if (clusterPlus == clusterMinus) { // if they share a same PXDCluster, set the flag
662  flag = 3; // PXD cluster is a 2D-hit
663  }
664  } else if (recoHitInfoPlus->getTrackingDetector() == RecoHitInformation::c_SVD) {
667  const SVDCluster* clusterPlus = recoHitInfoPlus->getRelatedTo<SVDCluster>();
668  const SVDCluster* clusterMinus = recoHitInfoMinus->getRelatedTo<SVDCluster>();
669  if (clusterPlus->isUCluster() && clusterMinus->isUCluster()) {
670  if (recoHitInformationsPlus.size() > iInnermostHitPlus + 1
671  && recoHitInformationsMinus.size() > iInnermostHitMinus + 1) { // not to access an array out of boundary
672  const auto& recoHitInfoNextPlus = recoHitInformationsPlus[iInnermostHitPlus + 1];
673  const auto& recoHitInfoNextMinus = recoHitInformationsMinus[iInnermostHitMinus + 1];
674  // sanity check to access next hits
675  if (recoHitInfoNextPlus->useInFit() && recoHitInfoNextMinus->useInFit() // this should be satisfied by default
676  && recoHitInfoNextPlus->getTrackingDetector() == RecoHitInformation::c_SVD
677  && recoHitInfoNextMinus->getTrackingDetector() == RecoHitInformation::c_SVD) {
678  const SVDCluster* clusterNextPlus = recoHitInfoNextPlus->getRelatedTo<SVDCluster>();
679  const SVDCluster* clusterNextMinus = recoHitInfoNextMinus->getRelatedTo<SVDCluster>();
680  if (!(clusterNextPlus->isUCluster()) && !(clusterNextMinus->isUCluster())
681  && clusterPlus->getSensorID() == clusterNextPlus->getSensorID()
682  && clusterMinus->getSensorID() == clusterNextMinus->getSensorID()) {
683  if (clusterPlus == clusterMinus)
684  flag += 2; // SVD U-cluster is shared
685  if (clusterNextPlus == clusterNextMinus)
686  flag += 1; // SVD V-cluster is shared
687  } else {
688  B2WARNING("SVD cluster to be paired is not on V-side, or not on the same sensor.");
689  return -1;
690  }
691  } else {
692  B2WARNING("No SVD cluster to be paired.");
693  return -1;
694  }
695  } else {
696  B2WARNING("Innermost SVD U-cluster is the only hit in a daughter track. This should not happen.");
697  return -1;
698  }
699  } else {
700  B2WARNING("No SVD U-cluster in the innermost cluster.");
701  return -1;
702  }
703  }
704  }
705  return flag;
706 
707 }
Provides a type-safe way to pass members of the chargedStableSet set.
Definition: Const.h:470
The ParticleType class for identifying different particle types.
Definition: Const.h:289
int getPDGCode() const
PDG code.
Definition: Const.h:354
static const ParticleType Lambda
Lambda particle.
Definition: Const.h:559
static const ChargedStable pion
charged pion particle
Definition: Const.h:542
static const ParticleType antiLambda
Anti-Lambda particle.
Definition: Const.h:560
static const ChargedStable proton
proton particle
Definition: Const.h:544
static const ParticleType invalidParticle
Invalid particle, used internally.
Definition: Const.h:561
static const ParticleType Kshort
K^0_S particle.
Definition: Const.h:557
static const ParticleType photon
photon particle
Definition: Const.h:554
static const ChargedStable electron
electron particle
Definition: Const.h:540
@ c_WriteOut
Object/array should be saved by output modules.
Definition: DataStore.h:70
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:72
Hit pattern of the VXD within a track.
Definition: HitPatternVXD.h:37
unsigned int getInteger() const
Getter for the underlying integer.
Definition: HitPatternVXD.h:58
void setInnermostHitShareStatus(const unsigned short innermostHitShareStatus)
Set the innermost hit share flags for V0 daughters.
bool start()
Start intercepting the output.
Definition: IOIntercept.h:155
Capture stdout and stderr and convert into log messages.
Definition: IOIntercept.h:226
@ c_Debug
Debug: for code development.
Definition: LogConfig.h:26
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
static genfit::Track & getGenfitTrack(RecoTrack &recoTrack)
Give access to the RecoTrack's genfit::Track.
Definition: RecoTrack.cc:396
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:76
bool wasFitSuccessful(const genfit::AbsTrackRep *representation=nullptr) const
Returns true if the last fit with the given representation was successful.
Definition: RecoTrack.cc:333
genfit::AbsTrackRep * getTrackRepresentationForPDG(int pdgCode)
Return an already created track representation of the given reco track for the PDG.
Definition: RecoTrack.cc:460
size_t addHitsFromRecoTrack(const RecoTrack *recoTrack, unsigned int sortingParameterOffset=0, bool reversed=false, boost::optional< double > optionalMinimalWeight=boost::none)
Add all hits from another RecoTrack to this RecoTrack.
Definition: RecoTrack.cc:237
RecoTrack * copyToStoreArray(StoreArray< RecoTrack > &storeArray) const
Append a new RecoTrack to the given store array and copy its general properties, but not the hits the...
Definition: RecoTrack.cc:513
std::vector< RecoHitInformation * > getRecoHitInformations(bool getSorted=false) const
Return a list of all RecoHitInformations associated with the RecoTrack.
Definition: RecoTrack.cc:538
static void registerRequiredRelations(StoreArray< RecoTrack > &recoTracks, std::string const &pxdHitsStoreArrayName="", std::string const &svdHitsStoreArrayName="", std::string const &cdcHitsStoreArrayName="", std::string const &bklmHitsStoreArrayName="", std::string const &eklmHitsStoreArrayName="", std::string const &recoHitInformationStoreArrayName="")
Convenience method which registers all relations required to fully use a RecoTrack.
Definition: RecoTrack.cc:49
const genfit::MeasuredStateOnPlane & getMeasuredStateOnPlaneFromFirstHit(const genfit::AbsTrackRep *representation=nullptr) const
Return genfit's MeasuredStateOnPlane for the first hit in a fit useful for extrapolation of measureme...
Definition: RecoTrack.cc:586
const genfit::MeasuredStateOnPlane & getMeasuredStateOnPlaneFromRecoHit(const RecoHitInformation *recoHitInfo, const genfit::AbsTrackRep *representation=nullptr) const
Return genfit's MeasuredStateOnPlane on plane for associated with one RecoHitInformation.
Definition: RecoTrack.cc:560
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:28
VxdID getSensorID() const
Get the sensor ID.
Definition: SVDCluster.h:101
bool isUCluster() const
Get the direction of strips.
Definition: SVDCluster.h:109
static uint32_t getHitPatternVXDInitializer(const RecoTrack &recoTrack)
Get the HitPattern in the VXD.
static uint64_t getHitPatternCDCInitializer(const RecoTrack &recoTrack)
Get the HitPattern in the CDC.
Values of the result of a track fit with a given particle hypothesis.
Const::ParticleType getParticleType() const
Getter for ParticleType of the mass hypothesis of the track fit.
Algorithm class to handle the fitting of RecoTrack objects.
Definition: TrackFitter.h:114
Class that bundles various TrackFitResults.
Definition: Track.h:25
const TrackFitResult * getTrackFitResultWithClosestMass(const Const::ChargedStable &requestedType) const
Return the track fit for a fit hypothesis with the closest mass.
Definition: Track.cc:68
bool m_useOnlyOneSVDHitPair
false only if the V0Fitter mode is 3
Definition: V0Fitter.h:173
void setFitterMode(int fitterMode)
set V0 fitter mode.
Definition: V0Fitter.cc:75
RecoTrack * copyRecoTrackAndFit(RecoTrack *origRecoTrack, const int trackPDG)
Create a copy of RecoTrack and fit the Track.
Definition: V0Fitter.cc:504
StoreArray< V0ValidationVertex > m_validationV0s
V0ValidationVertex (output, optional).
Definition: V0Fitter.h:163
StoreArray< RecoTrack > m_copiedRecoTracks
RecoTrack used to refit tracks (output)
Definition: V0Fitter.h:164
bool m_forcestore
true only if the V0Fitter mode is 1
Definition: V0Fitter.h:172
void initializeCuts(double beamPipeRadius, double vertexChi2CutOutside, std::tuple< double, double > invMassRangeKshort, std::tuple< double, double > invMassRangeLambda, std::tuple< double, double > invMassRangePhoton)
Initialize the cuts which will be applied during the fit and store process.
Definition: V0Fitter.cc:92
RecoTrack * copyRecoTrack(RecoTrack *origRecoTrack)
Create a copy of RecoTrack.
Definition: V0Fitter.cc:496
bool m_validation
Validation flag.
Definition: V0Fitter.h:158
std::pair< Const::ParticleType, Const::ParticleType > getTrackHypotheses(const Const::ParticleType &v0Hypothesis) const
Get track hypotheses for a given v0 hypothesis.
Definition: V0Fitter.cc:197
StoreArray< V0 > m_v0s
V0 (output).
Definition: V0Fitter.h:162
int checkSharedInnermostCluster(const RecoTrack *recoTrackPlus, const RecoTrack *recoTrackMinus)
Compare innermost hits of daughter pairs to check if they are the same (shared) or not.
Definition: V0Fitter.cc:634
TrackFitResult * buildTrackFitResult(const genfit::Track &track, const RecoTrack *recoTrack, const genfit::MeasuredStateOnPlane &msop, const double Bz, const Const::ParticleType &trackHypothesis, const int sharedInnermostCluster)
Build TrackFitResult of V0 Track and set relation to genfit Track.
Definition: V0Fitter.cc:173
V0Fitter(const std::string &trackFitResultsName="", const std::string &v0sName="", const std::string &v0ValidationVerticesName="", const std::string &recoTracksName="", const std::string &copiedRecoTracksName="CopiedRecoTracks", bool enableValidation=false)
Constructor for the V0Fitter.
Definition: V0Fitter.cc:41
StoreArray< TrackFitResult > m_trackFitResults
TrackFitResult (output).
Definition: V0Fitter.h:161
bool fitAndStore(const Track *trackPlus, const Track *trackMinus, const Const::ParticleType &v0Hypothesis, bool &isForceStored, bool &isHitRemoved)
Fit V0 with given hypothesis and store if fit was successful.
Definition: V0Fitter.cc:213
bool removeInnerHits(RecoTrack *prevRecoTrack, RecoTrack *recoTrack, const int trackPDG, const TVector3 &vertexPosition)
Remove inner hits from RecoTrack at once.
Definition: V0Fitter.cc:527
bool vertexFitWithRecoTracks(const Track *trackPlus, const Track *trackMinus, RecoTrack *recoTrackPlus, RecoTrack *recoTrackMinus, const Const::ParticleType &v0Hypothesis, unsigned int &hasInnerHitStatus, TVector3 &vertexPos, const bool forceStore)
fit V0 vertex using RecoTrack's as inputs.
Definition: V0Fitter.cc:356
double m_beamPipeRadius
Radius where inside/outside beampipe is defined.
Definition: V0Fitter.h:166
std::tuple< double, double > m_invMassRangePhoton
invariant mass cut for Photon.
Definition: V0Fitter.h:170
bool extrapolateToVertex(genfit::MeasuredStateOnPlane &stPlus, genfit::MeasuredStateOnPlane &stMinus, const TVector3 &vertexPosition)
Extrapolate the fit results to the perigee to the vertex.
std::string m_recoTracksName
RecoTrackColName (input).
Definition: V0Fitter.h:159
double m_vertexChi2CutOutside
Chi2 cut outside beampipe.
Definition: V0Fitter.h:167
StoreArray< RecoTrack > m_recoTracks
RecoTrack (input)
Definition: V0Fitter.h:160
double getBzAtVertex(const TVector3 &vertexPosition)
Getter for magnetic field in z direction at the vertex position.
Definition: V0Fitter.cc:163
bool fitGFRaveVertex(genfit::Track &trackPlus, genfit::Track &trackMinus, genfit::GFRaveVertex &vertex)
Fit the V0 vertex.
Definition: V0Fitter.cc:106
int m_v0FitterMode
0: store V0 at the first vertex fit, regardless of inner hits, 1: remove hits inside the V0 vertex po...
Definition: V0Fitter.h:171
std::tuple< double, double > m_invMassRangeKshort
invariant mass cut for Kshort.
Definition: V0Fitter.h:168
std::tuple< double, double > m_invMassRangeLambda
invariant mass cut for Lambda.
Definition: V0Fitter.h:169
Need this container for exception-safe cleanup, GFRave's interface isn't exception-safe as is.
Definition: VertexVector.h:24
std::vector< genfit::GFRaveVertex * > v
Fitted vertices.
Definition: VertexVector.h:42
size_t size() const noexcept
Return size of vertex vector.
Definition: VertexVector.h:36
Abstract base class for a track representation.
Definition: AbsTrackRep.h:66
TVector3 getFieldVal(const TVector3 &position)
This does NOT use the cache!
Definition: FieldManager.h:63
static FieldManager * getInstance()
Get singleton instance.
Definition: FieldManager.h:119
GFRaveTrackParameters class Contains a pointer to the original genfit::Track, the weight of the track...
Vertex factory for producing GFRaveVertex objects from Track objects.
GFRaveVertex class.
Definition: GFRaveVertex.h:48
TVector3 getPos() const
get Position
Definition: GFRaveVertex.h:67
TMatrixDSym getCov() const
get 3x3 covariance (error) of position.
Definition: GFRaveVertex.h:70
#StateOnPlane with additional covariance matrix.
Collection of TrackPoint objects, AbsTrackRep objects and FitStatus objects.
Definition: Track.h:71
const std::vector< genfit::AbsTrackRep * > & getTrackReps() const
Return the track representations as a list of pointers.
Definition: Track.h:132
Abstract base class for different kinds of events.