CbmRoot
Loading...
Searching...
No Matches
CbmKfFitTracksTask.cxx
Go to the documentation of this file.
1/* Copyright (C) 2023-2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: S.Gorbunov[committer] */
4
9
10
11#include "CbmKfFitTracksTask.h"
12
13#include "CbmGlobalTrack.h"
14#include "CbmKfUtil.h"
15#include "CbmMuchTrack.h"
16#include "CbmMvdHit.h"
17#include "CbmStsHit.h"
18#include "CbmStsSetup.h"
19#include "CbmStsTrack.h"
20#include "CbmTofTrack.h"
21#include "CbmTrdTrack.h"
22#include "FairRootManager.h"
23#include "TClonesArray.h"
24
25#include <cmath>
26#include <iostream>
27#include <thread>
28
29using namespace cbm::algo;
30
31
33 : FairTask("CbmKfFitTracksTask", iVerbose)
34 , fFitMode(mode)
35{
36}
37
39
40
42{
43
44 if (fNthreads < 1) {
45
46 // check if the number of threads is set in the invironment variable
47 const char* env = std::getenv("OMP_NUM_THREADS");
48 if (env) {
49 fNthreads = TString(env).Atoi();
50 LOG(info) << " found environment variable OMP_NUM_THREADS = \"" << env << "\", read as integer: " << fNthreads;
51 }
52
53 // ensure that at least one thread is set
54 if (fNthreads < 1) {
55 fNthreads = 1;
56 }
57 // fNthreads = 1; // enforce n threads to one
58 }
59
60 fFitter.Init();
61
62 //Get ROOT Manager
63 FairRootManager* ioman = FairRootManager::Instance();
64
65 if (!ioman) {
66 LOG(error) << "Init: RootManager not instantiated!";
67 return kERROR;
68 }
69
70 // Get global tracks
71
72 fGlobalTracks = dynamic_cast<TClonesArray*>(ioman->GetObject("GlobalTrack"));
73
74 // Get detector tracks
75 fStsTracks = dynamic_cast<TClonesArray*>(ioman->GetObject("StsTrack"));
76 fMuchTracks = dynamic_cast<TClonesArray*>(ioman->GetObject("MuchTrack"));
77 fTrdTracks = dynamic_cast<TClonesArray*>(ioman->GetObject("TrdTrack"));
78 fTofTracks = dynamic_cast<TClonesArray*>(ioman->GetObject("TofTrack"));
79
81 LOG(error) << "Init: Global track array not found!";
82 return kERROR;
83 }
84
86 LOG(error) << "Init: Sts track array not found!";
87 return kERROR;
88 }
89
90 return kSUCCESS;
91}
92
93void CbmKfFitTracksTask::Exec(Option_t* /*opt*/)
94{
95
96 LOG(info) << "exec event N " << fNeventsProcessed++ << " with " << fNthreads << " threads";
97
98 int statNfittedTracks = 0;
99 int statNtracks = 0;
100
101 fFitter.SetDefaultMomentumForMs(0.1); // 0.1 GeV/c
102 // TODO: automatically fix the momentum for Ms when it is not measured - for mCBM or Trd-only tracks
103
104 // fix the momentum to default for the Multiple Scattering calculation in mCBM
105 fFitter.SetEnforceDefaultMomentumForMs(FitMode::kMcbm == fFitMode);
106
108 statNtracks = fStsTracks->GetEntriesFast();
109 }
111 statNtracks = fGlobalTracks->GetEntriesFast();
112 }
113
114 std::vector<int> statNfittedThreadTracks(fNthreads, 0);
115
116 auto fitThread = [&](int iThread) {
117 CbmKfTrackFitter<> threadFitter(fFitter);
118
119 for (int iTr = iThread; iTr < statNtracks; iTr += fNthreads) {
120
122 if (FitMode::kSts == fFitMode) {
123 if (!threadFitter.CreateFromMvdStsTrack(t, iTr, false)) {
124 LOG(fatal) << "can not create the sts track for the fit! ";
125 return;
126 }
127 }
129 if (!threadFitter.CreateFromGlobalTrack(t, iTr, false)) {
130 LOG(fatal) << "can not create the global track for the fit! ";
131 return;
132 }
133 }
134 else {
135 LOG(fatal) << "unknown fit mode!";
136 return;
137 }
138
139 if (t.GetNofMeasurements() == 0) {
140 LOG(fatal) << "the track has no nodes with measurements!";
141 }
142
143 threadFitter.SetNofIterations(1);
144 // first time, fit with the smoother to get the linearisation at each node
145 if (!threadFitter.FitTrajectory(t)) {
146 continue;
147 }
148 // second time, fit without the smoother to get the final results at the first and at the last nodes
149 // using the linearisation from the previous fit
150
151 kf::TrackParamD parUp, parDn;
152 if (!threadFitter.FitTrajectoryUpstream(t, parUp)) {
153 continue;
154 }
155
156 if (!threadFitter.FitTrajectoryDownstream(t, parDn)) {
157 continue;
158 }
159
160 statNfittedThreadTracks[iThread]++;
161
162 FairTrackParam trackFirst = cbm::kf::ConvertTrackParam(parUp);
163 FairTrackParam trackLast = cbm::kf::ConvertTrackParam(parDn);
164
165 if (FitMode::kSts == fFitMode) {
166 CbmStsTrack* track = dynamic_cast<CbmStsTrack*>(fStsTracks->At(iTr));
167 if (!track) {
168 LOG(fatal) << "null pointer to the sts track!";
169 return;
170 }
171 track->SetParamFirst(&trackFirst);
172 track->SetParamLast(&trackLast);
173 }
175 CbmGlobalTrack* globalTrack = dynamic_cast<CbmGlobalTrack*>(fGlobalTracks->At(iTr));
176 if (!globalTrack) {
177 LOG(fatal) << "null pointer to the global track!";
178 return;
179 }
180 globalTrack->SetParamFirst(&trackFirst);
181 globalTrack->SetParamLast(&trackLast);
182 }
183 } // end of loop over tracks in the thread
184 }; // end of fitThread lambda
185
186 std::vector<std::thread> threads(fNthreads);
187
188 // run n threads
189 for (int i = 0; i < fNthreads; i++) {
190 threads[i] = std::thread(fitThread, i);
191 }
192
193 // wait for the threads to finish
194 for (auto& th : threads) {
195 th.join();
196 }
197
198 // collect statistics
199 for (auto& n : statNfittedThreadTracks) {
200 statNfittedTracks += n;
201 }
202
203 fStatNtracks += statNtracks;
204 fStatNfittedTracks += statNfittedTracks;
205
206 if (statNfittedTracks != statNtracks) {
207 LOG(error) << "can not fit " << 100. * (statNtracks - statNfittedTracks) / statNtracks << "\% of " << statNtracks
208 << " tracks! " << statNtracks - statNfittedTracks << " tracks are not fitted! ";
209 }
210}
211
212
214{
216 LOG(error) << "can not fit " << 100. * (fStatNtracks - fStatNfittedTracks) / fStatNtracks << "\% of "
217 << fStatNtracks << " tracks! " << fStatNtracks - fStatNfittedTracks << " tracks are not fitted! ";
218 }
219 else {
220 LOG(info) << "fitted " << fStatNfittedTracks << " tracks out of " << fStatNtracks
221 << " tracks! All tracks are fitted! ";
222 }
223}
Task class for refitting global or sts tracks.
Data class for a reconstructed hit in the STS.
Data class for STS tracks.
int Int_t
void SetParamLast(const FairTrackParam *parLast)
void SetParamFirst(const FairTrackParam *parFirst)
int fNthreads
number of threads for fitting
TClonesArray * fGlobalTracks
input data arrays
TClonesArray * fTrdTracks
trd tracks
TClonesArray * fMuchTracks
much tracks
CbmKfTrackFitter fFitter
track fitter
void Exec(Option_t *opt) override
Int_t fNeventsProcessed
number of processed events
Int_t fStatNfittedTracks
number of fitted tracks
TClonesArray * fStsTracks
sts tracks
Int_t fStatNtracks
number of tracks
TClonesArray * fTofTracks
tof tracks
InitStatus Init() override
CbmKfFitTracksTask(FitMode mode=FitMode::kSts, Int_t iVerbose=0)
Trajectory with hit information stored in node user references.
bool CreateFromMvdStsTrack(Trajectory &trajectory, int stsTrackIndex, bool addMaterialNodesOutsideHitRange)
bool FitTrajectoryUpstream(const cbm::algo::kf::Trajectory< double > &t, cbm::algo::kf::TrackParamD &parUp)
fit the trajectory upstream and return the track parameters at the first measurement node
bool FitTrajectoryDownstream(const cbm::algo::kf::Trajectory< double > &t, cbm::algo::kf::TrackParamD &parDn)
fit the trajectory downstream and return the track parameters at the last measurement node
bool FitTrajectory(cbm::algo::kf::Trajectory< double > &t)
fit the trajectory
void SetNofIterations(int nofIterations)
set number of iterations for the fit
bool CreateFromGlobalTrack(Trajectory &trajectory, int globalTrackIndex, bool addMaterialNodesOutsideHitRange)
void SetParamFirst(const FairTrackParam *par)
Definition CbmTrack.h:86
void SetParamLast(const FairTrackParam *par)
Definition CbmTrack.h:87
int GetNofMeasurements() const
Get number of nodes with measurements.
TrackParam< double > TrackParamD
cbm::algo::kf::TrackParamD ConvertTrackParam(const FairTrackParam &par)
copy fair track param to Ca track param
Definition CbmKfUtil.cxx:18