Belle II Software  release-08-01-10
BaseRecoFitterModule.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/modules/fitter/BaseRecoFitterModule.h>
9 
10 #include <genfit/KalmanFitStatus.h>
11 #include <genfit/FitStatus.h>
12 #include <genfit/MaterialEffects.h>
13 #include <genfit/FieldManager.h>
14 
15 #include <tracking/trackFitting/fitter/base/TrackFitter.h>
16 
17 #include <simulation/monopoles/MonopoleConstants.h>
18 
19 using namespace Belle2;
20 
22  Module()
23 {
24  setDescription("Fit the given reco tracks with the given fitter parameters.");
26 
27  addParam("recoTracksStoreArrayName", m_param_recoTracksStoreArrayName, "StoreArray name of the input and output reco tracks.",
29 
30  addParam("pxdHitsStoreArrayName", m_param_pxdHitsStoreArrayName, "StoreArray name of the input PXD hits.",
32  addParam("svdHitsStoreArrayName", m_param_svdHitsStoreArrayName, "StoreArray name of the input SVD hits.",
34  addParam("cdcHitsStoreArrayName", m_param_cdcHitsStoreArrayName, "StoreArray name of the input CDC hits.",
36  addParam("bklmHitsStoreArrayName", m_param_bklmHitsStoreArrayName, "StoreArray name of the input BKLM hits.",
38  addParam("eklmHitsStoreArrayName", m_param_eklmHitsStoreArrayName, "StoreArray name of the input EKLM hits.",
40 
41  addParam("pdgCodesToUseForFitting", m_param_pdgCodesToUseForFitting,
42  "Use these particle hypotheses for fitting. Please use positive pdg codes only.",
44 
45  addParam("resortHits", m_param_resortHits, "Resort the hits while fitting.",
47 
48  addParam("initializeCDCTranslators", m_param_initializeCDCTranslators,
49  "Configures whether the CDC Translators should be initialized by the FitterModule",
51  addParam("monopoleMagCharge", Monopoles::monopoleMagCharge,
52  "Sets monopole magnetic charge hypothesis if it is in the pdgCodesToUseForFitting",
53  Monopoles::monopoleMagCharge);
54 
55  addParam("correctSeedCharge", m_correctSeedCharge,
56  "If true changes seed charge of the RecoTrack to the one found by the track fit (if it differs).",
58 }
59 
61 {
63 
64  if (!genfit::MaterialEffects::getInstance()->isInitialized()) {
65  B2FATAL("Material effects not set up. Please use SetupGenfitExtrapolationModule.");
66  }
67 
68  if (!genfit::FieldManager::getInstance()->isInitialized()) {
69  B2FATAL("Magnetic field not set up. Please use SetupGenfitExtrapolationModule.");
70  }
71 
72  genfit::MaterialEffects::getInstance()->setMagCharge(Monopoles::monopoleMagCharge);
73 }
74 
75 
77 {
78  // The used fitting algorithm class.
81 
82  const std::shared_ptr<genfit::AbsFitter>& genfitFitter = createFitter();
83  if (genfitFitter) {
84  fitter.resetFitter(genfitFitter);
85  }
86 
87  B2DEBUG(29, "Number of reco track candidates to process: " << m_recoTracks.getEntries());
88  unsigned int recoTrackCounter = 0;
89 
90  for (RecoTrack& recoTrack : m_recoTracks) {
91 
92  if (recoTrack.getNumberOfTotalHits() < 3) {
93  B2WARNING("Genfit2Module: only " << recoTrack.getNumberOfTotalHits() << " were assigned to the Track! " <<
94  "This Track will not be fitted!");
95  continue;
96  }
97 
98  B2DEBUG(29, "Fitting reco track candidate number " << recoTrackCounter);
99  B2DEBUG(29, "Reco track candidate has start values: ");
100  B2DEBUG(29, "Momentum: " << recoTrack.getMomentumSeed().X() << " " << recoTrack.getMomentumSeed().Y() << " " <<
101  recoTrack.getMomentumSeed().Z());
102  B2DEBUG(29, "Position: " << recoTrack.getPositionSeed().X() << " " << recoTrack.getPositionSeed().Y() << " " <<
103  recoTrack.getPositionSeed().Z());
104  B2DEBUG(29, "Charge: " << recoTrack.getChargeSeed());
105  B2DEBUG(29, "Total number of hits assigned to the track: " << recoTrack.getNumberOfTotalHits());
106 
107 
108 
109  bool flippedCharge = false;
110  for (const unsigned int pdgCodeToUseForFitting : m_param_pdgCodesToUseForFitting) {
111  bool wasFitSuccessful;
112 
113  if (pdgCodeToUseForFitting != Monopoles::c_monopolePDGCode) {
114  Const::ChargedStable particleUsedForFitting(pdgCodeToUseForFitting);
115  B2DEBUG(29, "PDG: " << pdgCodeToUseForFitting);
116  wasFitSuccessful = fitter.fit(recoTrack, particleUsedForFitting);
117 
118  // only flip if the current fit was the cardinal rep. and seed charge differs from fitted charge
119  if (m_correctSeedCharge && wasFitSuccessful
120  && recoTrack.getCardinalRepresentation() == recoTrack.getTrackRepresentationForPDG(pdgCodeToUseForFitting)) { // charge flipping
121  // If the charge after the fit (cardinal rep) is different from the seed charge,
122  // we change the charge seed and refit the track
123  flippedCharge |= recoTrack.getChargeSeed() != recoTrack.getMeasuredStateOnPlaneFromFirstHit().getCharge();
124 
125  // debug
126  if (flippedCharge) {
127  B2DEBUG(29, "Refitting with opposite charge PDG: " << pdgCodeToUseForFitting);
128  }
129 
130  } // end of charge flipping
131 
132  } else {
133  // Different call signature for monopoles in order not to change Const::ChargedStable types
134  wasFitSuccessful = fitter.fit(recoTrack, pdgCodeToUseForFitting);
135  }
136  const genfit::AbsTrackRep* trackRep = recoTrack.getTrackRepresentationForPDG(pdgCodeToUseForFitting);
137 
138  if (!trackRep) {
139  B2FATAL("TrackRepresentation for PDG id " << pdgCodeToUseForFitting << " not present in RecoTrack although it " <<
140  "should have been created.");
141  }
142 
143  B2DEBUG(28, "-----> Fit results:");
144  if (wasFitSuccessful) {
145  const genfit::FitStatus* fs = recoTrack.getTrackFitStatus(trackRep);
146  const genfit::KalmanFitStatus* kfs = dynamic_cast<const genfit::KalmanFitStatus*>(fs);
147  B2DEBUG(28, " Chi2 of the fit: " << kfs->getChi2());
148  B2DEBUG(28, " NDF of the fit: " << kfs->getBackwardNdf());
149  //Calculate probability
150  double pValue = recoTrack.getTrackFitStatus(trackRep)->getPVal();
151  B2DEBUG(28, " pValue of the fit: " << pValue);
152  const genfit::MeasuredStateOnPlane& mSoP = recoTrack.getMeasuredStateOnPlaneFromFirstHit(trackRep);
153  B2DEBUG(28, "Charge after fit " << mSoP.getCharge());
154  B2DEBUG(28, "Position after fit " << mSoP.getPos().X() << " " << mSoP.getPos().Y() << " " << mSoP.getPos().Z());
155  B2DEBUG(28, "Momentum after fit " << mSoP.getMom().X() << " " << mSoP.getMom().Y() << " " << mSoP.getMom().Z());
156  } else {
157  B2DEBUG(28, " fit failed!");
158  }
159  } // loop over hypothesis
160 
161  // if charge has been flipped reset seed charge and refit all track representations
162  if (flippedCharge) {
163  recoTrack.setChargeSeed(-recoTrack.getChargeSeed());
164  // refit all present track representations
165  for (const auto trackRep : recoTrack.getRepresentations()) {
166  Const::ChargedStable particleUsedForFitting(abs(trackRep->getPDG()));
167  fitter.fit(recoTrack, particleUsedForFitting);
168  }
169  }
170  recoTrackCounter += 1;
171  } // loop tracks
172 }
std::string m_param_bklmHitsStoreArrayName
StoreArray name of the BKLM hits.
bool m_param_resortHits
Resort the hits while fitting.
std::vector< unsigned int > m_param_pdgCodesToUseForFitting
Use these particle hypotheses for fitting.
std::string m_param_pxdHitsStoreArrayName
StoreArray name of the PXD hits.
void initialize() override
Initialize the store ararys and check for the material effects.
void event() override
Do the fitting using the created fitter.
std::string m_param_eklmHitsStoreArrayName
StoreArray name of the EKLM hits.
bool m_correctSeedCharge
if true resets the charge seed of the RecoTrack if track fit prefers the other charge
std::string m_param_recoTracksStoreArrayName
StoreArray name of the input and output reco tracks.
std::string m_param_svdHitsStoreArrayName
StoreArray name of the SVD hits.
std::string m_param_cdcHitsStoreArrayName
StoreArray name of the CDC hits.
StoreArray< RecoTrack > m_recoTracks
RecoTracks StoreArray.
virtual std::shared_ptr< genfit::AbsFitter > createFitter() const =0
Method to create the used filter.
bool m_param_initializeCDCTranslators
Configures whether the CDC Translators should be initialized by the FitterModule especially useful fo...
Provides a type-safe way to pass members of the chargedStableSet set.
Definition: Const.h:580
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:79
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
Algorithm class to handle the fitting of RecoTrack objects.
Definition: TrackFitter.h:116
Abstract base class for a track representation.
Definition: AbsTrackRep.h:66
static FieldManager * getInstance()
Get singleton instance.
Definition: FieldManager.h:119
Class where important numbers and properties of a fit can be stored.
Definition: FitStatus.h:80
double getChi2() const
Get chi^2 of the fit.
Definition: FitStatus.h:120
FitStatus for use with AbsKalmanFitter implementations.
#StateOnPlane with additional covariance matrix.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
Abstract base class for different kinds of events.