Belle II Software development
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
19using 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 B2DEBUG(29, "resortHits: " << m_param_resortHits);
117
118 wasFitSuccessful = fitter.fit(recoTrack, particleUsedForFitting, m_param_resortHits);
119
120 // only flip if the current fit was the cardinal rep. and seed charge differs from fitted charge
121 if (m_correctSeedCharge && wasFitSuccessful
122 && recoTrack.getCardinalRepresentation() == recoTrack.getTrackRepresentationForPDG(pdgCodeToUseForFitting)) { // charge flipping
123 // If the charge after the fit (cardinal rep) is different from the seed charge,
124 // we change the charge seed and refit the track
125 flippedCharge |= recoTrack.getChargeSeed() != recoTrack.getMeasuredStateOnPlaneFromFirstHit().getCharge();
126
127 // debug
128 if (flippedCharge) {
129 B2DEBUG(29, "Refitting with opposite charge PDG: " << pdgCodeToUseForFitting);
130 }
131
132 } // end of charge flipping
133 } else {
134 // Different call signature for monopoles in order not to change Const::ChargedStable types
135 wasFitSuccessful = fitter.fit(recoTrack, pdgCodeToUseForFitting, m_param_resortHits);
136 }
137 const genfit::AbsTrackRep* trackRep = recoTrack.getTrackRepresentationForPDG(pdgCodeToUseForFitting);
138
139 if (!trackRep) {
140 B2FATAL("TrackRepresentation for PDG id " << pdgCodeToUseForFitting << " not present in RecoTrack although it " <<
141 "should have been created.");
142 }
143
144 B2DEBUG(28, "-----> Fit results:");
145 if (wasFitSuccessful) {
146 const genfit::FitStatus* fs = recoTrack.getTrackFitStatus(trackRep);
147 const genfit::KalmanFitStatus* kfs = dynamic_cast<const genfit::KalmanFitStatus*>(fs);
148 B2DEBUG(28, " Chi2 of the fit: " << kfs->getChi2());
149 B2DEBUG(28, " NDF of the fit: " << kfs->getBackwardNdf());
150 //Calculate probability
151 double pValue = recoTrack.getTrackFitStatus(trackRep)->getPVal();
152 B2DEBUG(28, " pValue of the fit: " << pValue);
153 const genfit::MeasuredStateOnPlane& mSoP = recoTrack.getMeasuredStateOnPlaneFromFirstHit(trackRep);
154 B2DEBUG(28, "Charge after fit " << mSoP.getCharge());
155 B2DEBUG(28, "Position after fit " << mSoP.getPos().X() << " " << mSoP.getPos().Y() << " " << mSoP.getPos().Z());
156 B2DEBUG(28, "Momentum after fit " << mSoP.getMom().X() << " " << mSoP.getMom().Y() << " " << mSoP.getMom().Z());
157 } else {
158 B2DEBUG(28, " fit failed!");
159 }
160 } // loop over hypothesis
161
162 // if charge has been flipped reset seed charge and refit all track representations
163 if (flippedCharge) {
164 recoTrack.setChargeSeed(-recoTrack.getChargeSeed());
165 // refit all present track representations
166 for (const auto trackRep : recoTrack.getRepresentations()) {
167 Const::ChargedStable particleUsedForFitting(abs(trackRep->getPDG()));
168 fitter.fit(recoTrack, particleUsedForFitting);
169 }
170 }
171 recoTrackCounter += 1;
172 } // loop tracks
173}
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.
virtual std::shared_ptr< genfit::AbsFitter > createFitter() const =0
Method to create the used filter.
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.
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:589
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:121
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.