BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnBeamTracking.cxx
Go to the documentation of this file.
1#include "BmnBeamTracking.h"
2
3#include "BmnKalmanFilter.h"
4#include "BmnMath.h"
5#include "BmnSiBTHit.h"
6#include "FairRunAna.h"
7#include "FairTrackParam.h"
8#include "TFile.h"
9#include "TH1F.h"
10#include "TStyle.h"
11
12#include <TMath.h>
13#include <map>
14#include <vector>
15
16using namespace std;
17using namespace TMath;
18
20 : fSiBTDetector(nullptr)
21 , fSiBTHitsBranchName("BmnSiBTHit")
22 , fBeamTracksBranchName("BmnBeamTrack")
23 , fBeamTracksArray(nullptr)
24 , fSiBTHitsArray(nullptr)
25 , fKalman(nullptr)
26 , fEventNo(0)
27 , fNTrMax(10)
28 , fField(nullptr)
29{}
30
34
36
38{
39 if (fVerbose > 1)
40 cout << "======================== BEAM tracking init started ====================" << endl;
41
43
44 // Get ROOT Manager
45 FairRootManager* ioman = FairRootManager::Instance();
46 if (!ioman)
47 Fatal("Init", "FairRootManager is not instantiated");
48
49 // SILICON
50 fSiBTHitsArray = (TClonesArray*)ioman->GetObject(fSiBTHitsBranchName); // in
51
52 if (!fSiBTHitsArray) {
53 cout << "BmnBeamTracking::Init(): branch " << fSiBTHitsBranchName << " not found! Task will be deactivated"
54 << endl;
55 SetActive(kFALSE);
56 return InitStatus::kERROR;
57 }
58
59 fBeamTracksArray = new TClonesArray("BmnTrack", 100); // out
60 ioman->Register(fBeamTracksBranchName, "BEAM", fBeamTracksArray, kTRUE);
61
62 fField = FairRunAna::Instance()->GetField();
63 if (!fField)
64 Fatal("Init", "No Magnetic Field found");
65
66 TString gPathConfig = gSystem->Getenv("VMCWORKDIR");
67
68 TString gPathGemConfig = gPathConfig + "/parameters/SiBT/XMLConfigs/";
69 TString confSiBT = "SiBTRun8.xml";
70 fSiBTDetector = new BmnSiBTStationSet(gPathGemConfig + confSiBT);
71
72 if (fVerbose > 1)
73 cout << "======================== BEAM tracking init finished ===================" << endl;
74
75 return kSUCCESS;
76}
77
79{
80 TStopwatch sw;
81 sw.Start();
82
83 if (!IsActive())
84 return;
85
86 fEventNo++;
87 if (fVerbose > 1)
88 cout << "\n======================== BEAM tracking exec started ====================" << endl;
89 if (fVerbose > 1)
90 cout << "\n Event number: " << fEventNo << endl;
91
92 fBeamTracksArray->Delete();
93 FindTracks();
94
95 if (fVerbose > 0)
96 cout << "BmnBeamTracking: " << fBeamTracksArray->GetEntriesFast() << " tracks" << endl;
97 if (fVerbose > 1)
98 cout << "\n======================== BEAM tracking exec finished ===================" << endl;
99
100 sw.Stop();
101 fTime += sw.RealTime();
102}
103
105{
106 // Sort hits by stations
107 std::vector<std::vector<BmnSiBTHit*>> sortedHits(fSiBTDetector->GetNStations());
108 SortHits(sortedHits);
109
110 const Double_t Xv = 0.0;
111 const Double_t Yv = 0.0;
112 const Double_t Zv = 0.0;
113
114 // Create and collect all candidates passed CalculateTrackParams method
115 std::vector<BmnTrack> candidates;
116 candidates.reserve(1000);
117
118 for (BmnHit* hit2 : sortedHits[2]) {
119 for (BmnHit* hit1 : sortedHits[1]) {
120 for (BmnHit* hit0 : sortedHits[0]) {
121 BmnTrack cand;
122 cand.AddHit(hit0->GetIndex(), hit0);
123 cand.AddHit(hit1->GetIndex(), hit1);
124 cand.AddHit(hit2->GetIndex(), hit2);
125 cand.SortHits();
126
127 if (CalculateTrackParams(&cand) != kBMNERROR) {
128 candidates.push_back(cand);
129 }
130 }
131 }
132 }
133
134 // sort candidates by linear chi-square
135 std::sort(candidates.begin(), candidates.end(),
136 [](const BmnTrack& a, const BmnTrack& b) { return a.GetChi2() < b.GetChi2(); });
137
138 if ((Int_t)candidates.size() > fNTrMax)
139 candidates.resize(fNTrMax);
140
141 if (fVerbose > 0)
142 cout << "BmnBeamTracking: " << candidates.size() << " tracks after chi2 sort (max " << fNTrMax << ")" << endl;
143
144 // Финальная обработка: Калман + residuals + запись
145 for (auto& tr : candidates) {
147
148 FairTrackParam par = *(tr.GetParamFirst());
149
150 for (Int_t iHit = 0; iHit < tr.GetNHits(); ++iHit) {
151 BmnHit* hit = (BmnHit*)fSiBTHitsArray->At(tr.GetHitIndex(iHit));
152 fKalman->TGeoTrackPropagate(&par, hit->GetZ(), 2212, nullptr, nullptr, 1);
153 hit->SetResXY(par.GetX() - hit->GetX(), par.GetY() - hit->GetY());
154 }
155
156 fKalman->TGeoTrackPropagate(&par, Zv, 2212, nullptr, nullptr, 1);
157 tr.SetB(Sqrt(Sq(par.GetX() - Xv) + Sq(par.GetY() - Yv)));
158 tr.SetParamLast(par);
159
160 new ((*fBeamTracksArray)[fBeamTracksArray->GetEntriesFast()]) BmnTrack(tr);
161 }
162
163 return kBMNSUCCESS;
164}
165
167{
168 printf("Work time of BmnBeamTracking: %4.2f sec.\n", fTime);
169 delete fKalman;
170 delete fSiBTDetector;
171}
172
173BmnStatus BmnBeamTracking::SortHits(std::vector<std::vector<BmnSiBTHit*>>& sortedHits)
174{
175 for (Int_t iHit = 0; iHit < fSiBTHitsArray->GetEntriesFast(); ++iHit) {
176 BmnSiBTHit* hit = (BmnSiBTHit*)fSiBTHitsArray->At(iHit);
177 if (!hit)
178 continue;
180 continue;
181
182 Int_t station = hit->GetStation();
183 if (station < 0 || station >= (Int_t)sortedHits.size())
184 continue;
185
186 sortedHits[station].push_back(hit);
187 }
188
189 return kBMNSUCCESS;
190}
191
193{
194
195 FairTrackParam par = *(cand->GetParamFirst());
196 Double_t chiTot = 0.0;
197 for (Int_t iHit = 0; iHit < cand->GetNHits(); ++iHit) {
198 BmnHit* hit = (BmnHit*)fSiBTHitsArray->At(cand->GetHitIndex(iHit));
199 Double_t chi = 0.0;
200 fKalman->TGeoTrackPropagate(&par, hit->GetZ(), 2212, nullptr, nullptr, 1);
201 fKalman->Update(&par, hit, chi);
202 chiTot += chi;
203 }
204 cand->SetParamLast(par);
205
206 for (Int_t iHit = cand->GetNHits() - 1; iHit >= 0; iHit--) {
207 BmnHit* hit = (BmnHit*)fSiBTHitsArray->At(cand->GetHitIndex(iHit));
208 Double_t chi = 0.0;
209 fKalman->TGeoTrackPropagate(&par, hit->GetZ(), 2212, nullptr, nullptr, 1);
210 fKalman->Update(&par, hit, chi);
211 chiTot += chi;
212 }
213 cand->SetParamFirst(par);
214 cand->SetChi2(chiTot);
215 //---to vertex for online monitoring------
216 // fKalman->TGeoTrackPropagate(&par, 0, 2212, nullptr, nullptr);
217 // cand->SetParamLast(par);
218
219 return kBMNSUCCESS;
220}
221
223{
224 const UInt_t nHits = 3;
225 Double_t chi2circ = 0.0;
226 TVector3 CircParZX = CircleFit(tr, fSiBTHitsArray, chi2circ);
227
228 Double_t Xc = CircParZX.Y(); // x-coordinate of fit-circle center
229 Double_t Zc = CircParZX.X(); // z-coordinate of fit-circle center
230 fField = FairRunAna::Instance()->GetField();
231 const Double_t B = (LineFit(tr, fSiBTHitsArray, "ZY")).X(); // angle coefficient for helicoid
232
233 // Double_t Q = (Xc > 0) ? +1 : -1;
234
235 Double_t sumX(0.0), sumY(0.0), sumTx(0.0), sumTy(0.0), sumQP(0.0);
236 Double_t sumXX(0.0), sumXY(0.0), sumXTx(0.0), sumXTy(0.0), sumXQP(0.0);
237 Double_t sumYY(0.0), sumYTx(0.0), sumYTy(0.0), sumYQP(0.0);
238 Double_t sumTxTx(0.0), sumTxTy(0.0), sumTxQP(0.0);
239 Double_t sumTyTy(0.0), sumTyQP(0.0);
240 Double_t sumQPQP(0.0);
241
242 for (UInt_t i = 0; i < nHits; ++i) {
243 BmnHit* hit = (BmnHit*)fSiBTHitsArray->At(tr->GetHitIndex(i));
244 if (!hit)
245 continue;
246 Double_t Xi = hit->GetX();
247 Double_t Yi = hit->GetY();
248 Double_t Zi = hit->GetZ();
249
250 Double_t Txi = -1.0 * (Zi - Zc) / (Xi - Xc);
251 Double_t Tyi = B;
252 // Double_t Ri = Sqrt(Sq(Xi - Xc) + Sq(Zi - Zc));
253 Double_t QPi = 1.0 / 10.678; // Q / (0.0003 * Abs(fField->GetBy(Xi, Yi, Zi)) * Ri);
254
255 sumX += Xi;
256 sumY += Yi;
257 sumTx += Txi;
258 sumTy += Tyi;
259 sumQP += QPi;
260 sumXX += Xi * Xi;
261 sumXY += Xi * Yi;
262 sumXTx += Xi * Txi;
263 sumXTy += Xi * Tyi;
264 sumXQP += Xi * QPi;
265 sumYY += Yi * Yi;
266 sumYTx += Yi * Txi;
267 sumYTy += Yi * Tyi;
268 sumYQP += Yi * QPi;
269 sumTxTx += Txi * Txi;
270 sumTxTy += Txi * Tyi;
271 sumTxQP += Txi * QPi;
272 sumTyTy += Tyi * Tyi;
273 sumTyQP += Tyi * QPi;
274 sumQPQP += QPi * QPi;
275 }
276
277 Double_t meanX = sumX / nHits;
278 Double_t meanY = sumY / nHits;
279 Double_t meanTx = sumTx / nHits;
280 Double_t meanTy = sumTy / nHits;
281 Double_t meanQP = sumQP / nHits;
282
283 Double_t Cov_X_X = sumXX / nHits - Sq(meanX);
284 Double_t Cov_X_Y = sumXY / nHits - meanX * meanY;
285 Double_t Cov_X_Tx = sumXTx / nHits - meanX * meanTx;
286 Double_t Cov_X_Ty = sumXTy / nHits - meanX * meanTy;
287 Double_t Cov_X_Qp = sumXQP / nHits - meanX * meanQP;
288 Double_t Cov_Y_Y = sumYY / nHits - Sq(meanY);
289 Double_t Cov_Y_Tx = sumYTx / nHits - meanY * meanTx;
290 Double_t Cov_Y_Ty = sumYTy / nHits - meanY * meanTy;
291 Double_t Cov_Y_Qp = sumYQP / nHits - meanY * meanQP;
292 Double_t Cov_Tx_Tx = sumTxTx / nHits - Sq(meanTx);
293 Double_t Cov_Tx_Ty = sumTxTy / nHits - meanTx * meanTy;
294 Double_t Cov_Tx_Qp = sumTxQP / nHits - meanTx * meanQP;
295 Double_t Cov_Ty_Ty = sumTyTy / nHits - Sq(meanTy);
296 Double_t Cov_Ty_Qp = sumTyQP / nHits - meanTy * meanQP;
297 Double_t Cov_Qp_Qp = sumQPQP / nHits - Sq(meanQP);
298
299 FairTrackParam par;
300 par.SetCovariance(0, 0, Cov_X_X);
301 par.SetCovariance(0, 1, Cov_X_Y);
302 par.SetCovariance(0, 2, Cov_X_Tx);
303 par.SetCovariance(0, 3, Cov_X_Ty);
304 par.SetCovariance(0, 4, Cov_X_Qp);
305 par.SetCovariance(1, 1, Cov_Y_Y);
306 par.SetCovariance(1, 2, Cov_Y_Tx);
307 par.SetCovariance(1, 3, Cov_Y_Ty);
308 par.SetCovariance(1, 4, Cov_Y_Qp);
309 par.SetCovariance(2, 2, Cov_Tx_Tx);
310 par.SetCovariance(2, 3, Cov_Tx_Ty);
311 par.SetCovariance(2, 4, Cov_Tx_Qp);
312 par.SetCovariance(3, 3, Cov_Ty_Ty);
313 par.SetCovariance(3, 4, Cov_Ty_Qp);
314 par.SetCovariance(4, 4, Cov_Qp_Qp);
315
316 // если ставить ненулевые ковариации в недиагональных членах, то трек начинает сильно уводить в сторону. Проверить!
317 // par.SetCovariance(0, 0, Cov_X_X);
318 // par.SetCovariance(0, 1, 0.0);
319 // par.SetCovariance(0, 2, 0.0);
320 // par.SetCovariance(0, 3, 0.0);
321 // par.SetCovariance(0, 4, 0.0);
322 // par.SetCovariance(1, 1, Cov_Y_Y);
323 // par.SetCovariance(1, 2, 0.0);
324 // par.SetCovariance(1, 3, 0.0);
325 // par.SetCovariance(1, 4, 0.0);
326 // par.SetCovariance(2, 2, Cov_Tx_Tx);
327 // par.SetCovariance(2, 3, 0.0);
328 // par.SetCovariance(2, 4, 0.0);
329 // par.SetCovariance(3, 3, Cov_Ty_Ty);
330 // par.SetCovariance(3, 4, 0.0);
331 // par.SetCovariance(4, 4, Cov_Qp_Qp);
332
333 tr->SetParamFirst(par);
334 tr->SetParamLast(par);
335
336 return kBMNSUCCESS;
337}
338
340{
341 // Estimation of track parameters for events with magnetic field
342
343 TVector3 lineParZY = LineFit(tr, fSiBTHitsArray, "ZY");
344 const Double_t B = lineParZY.X(); // angle coefficient for helicoid
345
346 Double_t Tx_first =
348 (BmnHit*)fSiBTHitsArray->At(tr->GetHitIndex(2)));
349 Double_t Tx_last =
351 (BmnHit*)fSiBTHitsArray->At(tr->GetHitIndex(0)));
352
353 CalcCovMatrix(tr);
354 TVector3 firstPos;
355 TVector3 lastPos;
356 ((BmnHit*)fSiBTHitsArray->At(tr->GetHitIndex(0)))->Position(firstPos);
357 ((BmnHit*)fSiBTHitsArray->At(tr->GetHitIndex(2)))->Position(lastPos);
358 tr->GetParamFirst()->SetPosition(firstPos);
359 tr->GetParamFirst()->SetTx(Tx_first);
360 tr->GetParamFirst()->SetTy(B);
361 tr->GetParamLast()->SetPosition(lastPos);
362 tr->GetParamLast()->SetTx(Tx_last);
363 tr->GetParamLast()->SetTy(B);
364 Double_t QP = 1.0 / 10.678; // CalcQp(tr); 10.678=4.65*124/54 Xe124
365 tr->GetParamFirst()->SetQp(QP);
366 tr->GetParamLast()->SetQp(QP);
367 tr->SetChi2(lineParZY.Z());
368 return kBMNSUCCESS;
369}
370
372{
373
374 vector<BmnHit*> hits;
375 for (Int_t iHit = 0; iHit < track->GetNHits(); iHit++)
376 hits.push_back((BmnHit*)fSiBTHitsArray->At(track->GetHitIndex(iHit)));
377
378 // Get q/p info from all track segments
379 BmnHit* first = hits[0];
380 BmnHit* second = hits[1];
381 BmnHit* third = hits[2];
382
383 TVector3 CircParZX = CircleBy3Hit(first, second, third);
384 Double_t R = CircParZX.Z();
385 Double_t Xc = CircParZX.Y();
386 Double_t Zc = CircParZX.X();
387
388 Double_t Q = (Xc > 0) ? +1. : -1.;
389 Double_t S = 0.0003
390 * (Abs(fField->GetBy(third->GetX(), third->GetY(), third->GetZ()))
391 + Abs(fField->GetBy(second->GetX(), second->GetY(), second->GetZ()))
392 + Abs(fField->GetBy(first->GetX(), first->GetY(), first->GetZ())))
393 / 3.;
394
395 Double_t Pt = S * R; // actually Pt/Q, but it doesn't matter
396 Double_t fX = first->GetX();
397 Double_t fZ = first->GetZ();
398
399 Double_t h = -1.0;
400
401 Double_t Tx_first = h * (fZ - Zc) / (fX - Xc);
402 TVector3 lineParZY = LineFit(track, fSiBTHitsArray, "ZY");
403 const Double_t B = lineParZY.X(); // angle coefficient for helicoid
404 Double_t Ty_first = B; // / (fX - Xc);
405
406 Double_t Pz = Pt / Sqrt(1 + Sq(Tx_first));
407 Double_t Px = Tx_first * Pz;
408 Double_t Py = Ty_first * Pz;
409 Double_t P = Sqrt(Sq(Px) + Sq(Py) + Sq(Pz));
410 Double_t QP = Q / P;
411
412 return QP;
413}
TVector3 LineFit(BmnTrack *track, const TClonesArray *arr, TString type)
Definition BmnMath.cxx:113
TVector3 CircleBy3Hit(BmnTrack *track, const TClonesArray *arr)
Definition BmnMath.cxx:470
TVector3 CircleFit(BmnTrack *track, const TClonesArray *arr, Double_t &chi2)
Definition BmnMath.cxx:312
Double_t CalcTx(const BmnHit *h0, const BmnHit *h1, const BmnHit *h2)
Definition BmnMath.cxx:422
int i
Definition P4_F32vec4.h:22
int Int_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
void Fatal(const char *location, const char *msgfmt,...)
R__EXTERN TSystem * gSystem
BmnStatus
Define status code.
Definition BmnEnums.h:93
@ kBMNERROR
Error.
Definition BmnEnums.h:95
@ kBMNSUCCESS
Success.
Definition BmnEnums.h:94
virtual void Finish()
Double_t CalcQp(BmnTrack *track)
BmnStatus CalculateTrackParams(BmnTrack *tr)
BmnKalmanFilter * fKalman
BmnSiBTStationSet * fSiBTDetector
virtual ~BmnBeamTracking()
TClonesArray * fSiBTHitsArray
FairField * fField
BmnStatus SortHits(std::vector< std::vector< BmnSiBTHit * > > &sortedHits)
BmnStatus TrackUpdateByKalman(BmnTrack *cand)
virtual InitStatus Init()
BmnStatus CalcCovMatrix(BmnTrack *tr)
virtual void Exec(Option_t *opt)
TClonesArray * fBeamTracksArray
TString fSiBTHitsBranchName
TString fBeamTracksBranchName
void SetResXY(Double_t resX, Double_t resY)
Definition BmnHit.h:57
Short_t GetStation() const
Definition BmnHit.h:35
Double_t GetStripTotalSignalInUpperLayer()
Definition BmnSiBTHit.h:33
Double_t GetStripTotalSignalInLowerLayer()
Definition BmnSiBTHit.h:31
void SetChi2(Double_t chi2)
Definition BmnTrack.h:76
void SetParamLast(FairTrackParam &par)
Definition BmnTrack.h:72
FairTrackParam * GetParamFirst()
Definition BmnTrack.h:63
Int_t GetNHits() const
Accessors.
Definition BmnTrack.h:49
Int_t GetHitIndex(Int_t iHit) const
Definition BmnTrack.h:51
void AddHit(Int_t hitIndex, FairHit *Hit)
Associate a FairHit to the track.
Definition BmnTrack.cxx:28
void SetParamFirst(FairTrackParam &par)
Modifiers.
Definition BmnTrack.h:70
FairTrackParam * GetParamLast()
Definition BmnTrack.h:65
void SortHits()
Public method SortHits Sorts the hits in downstream direction and writes the hit indices into the mem...
Definition BmnTrack.cxx:45
Double_t RealTime()
void Start(Bool_t reset=kTRUE)
void Stop()
Double_t Z() const
Double_t Y() const
Double_t X() const
Double_t Sq(Double_t x)
Double_t Sqrt(Double_t x)
constexpr Double_t R()
Double_t Abs(Double_t d)
Definition json.hpp:4446