BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnStsVectorFinderV9.cxx
Go to the documentation of this file.
1// -------------------------------------------------------------------------
2// ----- BmnStsVectorFinder source file -----
3// ----- Created 3/12/21 by A.Zinchenko, D.Zinchenko, R.Zinchenko -----
4// -------------------------------------------------------------------------
6
7#include "BmnStsMatchTracks.h"
8#include "CbmKF.h"
9#include "CbmKFTrack.h"
10#include "CbmStsCluster.h"
11#include "CbmStsDigiMatch.h"
12#include "CbmStsDigiScheme.h"
13#include "CbmStsHit.h"
14#include "CbmStsPoint.h"
15#include "CbmStsSector.h"
16#include "CbmStsStation.h"
17#include "CbmStsTrack.h"
18#include "FairRootManager.h"
19#include "FairRunAna.h"
20#include "TMVA/Tools.h"
21
22#include <TClonesArray.h>
23#include <TF1.h>
24#include <TGraph.h>
25#include <TMath.h>
26#include <TObjString.h>
27#include <iomanip>
28#include <iostream>
29#include <map>
30#include <set>
31#include <vector>
32
33using std::cout;
34using std::endl;
35using std::map;
36using std::multimap;
37using std::pair;
38using std::set;
39using std::vector;
40
41#include <TStopwatch.h>
42
43// std::ofstream outf("log.txt");
44
45static Double_t workTime = 0.0;
46
47// ----- Default constructor -------------------------------------------
49 : FairTask("STS Vector Finder V9")
50 , fHitArray(NULL)
51 , fTrackArray(NULL)
52 , fEvent(0)
53 , fPass(0)
54 , fNsta(0)
55 ,
56 // fNbranches(5), // AZ-021125 - for tracking in windows
57 fNbranches(7)
58 , // AZ-230625
59 // fNbranches(10), // AZ-270625
60 fExact(0)
61 , fExactSel(-9)
62 , discarded(0)
63 , fOut(0) // 0,2,3,6
64 // AZ-240626 fNhitsMin(nullptr)
66 , fUseTMVA(0)
67 , // 0,2,3 //AZ-300922
69 , // AZ-040525 - discriminate good from fake tracks
70 fNSi(4)
71 , // AZ-051022
72 fGemConfigFile("GemRun8.xml")
73 , fSilConfigFile("SiliconRun8.xml")
74 , fOutBranch("StsVector")
75 , fKillHitsTxP(0)
76 , fTracksToKill(nullptr)
77 , fHitConverter(nullptr)
78{
79 for (int j = 0; j < 4; ++j)
80 fClusArray[j] = nullptr;
81 // fOutf = new ofstream("log.txt"); // AZ-290525 - for auxiliary output
82}
83// -------------------------------------------------------------------------
84
85// ----- Destructor ----------------------------------------------------
87// -------------------------------------------------------------------------
88
89// ----- Public method Init --------------------------------------------
91{
92
93 // Get RootManager
94 FairRootManager* ioman = FairRootManager::Instance();
95 if (!ioman) {
96 cout << "-E- BmnStsVectorFinderV9::Init: " << "RootManager not instantiated!" << endl;
97 return kFATAL;
98 }
99
100 // Get input arrays
101 fClusArray[0] = (TClonesArray*)ioman->GetObject("StsCluster");
102 if (!fClusArray[0]) {
103 // cout << "-W- BmnStsVectorFinderV9::Init: "
104 // << "No StsCluster array!" << endl;
105 // return kERROR;
106 fClusArray[0] = (TClonesArray*)ioman->GetObject("BmnSiliconUpperCluster");
107 fClusArray[1] = (TClonesArray*)ioman->GetObject("BmnSiliconLowerCluster");
108 fClusArray[2] = (TClonesArray*)ioman->GetObject("BmnGemUpperCluster");
109 fClusArray[3] = (TClonesArray*)ioman->GetObject("BmnGemLowerCluster");
110 for (int j = 0; j < 4; ++j) {
111 // AZ-241222 if ( ! fClusArray[j] ) {
112 if (!fClusArray[0] && !fClusArray[2]) { // AZ-241222
113 cout << "-W- BmnStsVectorFinderV9::Init: " << "No BmnCluster array!" << j << endl;
114 return kERROR;
115 }
116 }
117 }
118
119 fHitArray = (TClonesArray*)ioman->GetObject("StsHit");
120 if (!fHitArray) {
121 // cout << "-W- BmnStsVectorFinderV9::Init: "
122 // << "No StsHit array!" << endl;
123 return kERROR;
124 }
125
126 fTrackArray = (TClonesArray*)ioman->GetObject("StsTrack");
127 if (!fTrackArray) {
128 // cout << "-W- BmnStsVectorFinderV9::Init: "
129 // << "No StsTrack array!" << endl;
130 // AZ-100722 return kERROR;
131 }
132
133 fDigiMatches = (TClonesArray*)ioman->GetObject("StsDigiMatch");
134 if (!fDigiMatches) {
135 // cout << "-W- BmnStsVectorFinderV9::Init: "
136 // << "No StsDigiMatch array!" << endl;
137 // return kERROR;
138 }
139
140 fStsPoints = (TClonesArray*)ioman->GetObject("StsPoint");
141 if (!fStsPoints) {
142 // cout << "-W- BmnStsVectorFinderV9::Init: "
143 // << "No StsPoint array!" << endl;
144 // AZ-181222 return kERROR;
145 }
146
147 fSilPoints = (TClonesArray*)ioman->GetObject("SiliconPoint");
148 if (!fSilPoints) {
149 // cout << "-E- BmnStsVectorFinderV9::Init: No SiliconPoint array!" << endl;
150 }
151
152 fVspPoints = (TClonesArray*)ioman->GetObject("VSPPoint");
153 if (!fVspPoints) {
154 // cout << "-E- BmnStsVectorFinder::Init: No SiliconPoint array!" << endl;
155 }
156
157 // Create and register output array
158 fVectorArray = new TClonesArray("CbmStsTrack");
159 // AZ-041125 ioman->Register("StsVector", "STS", fVectorArray, kTRUE);
160 ioman->Register(fOutBranch, "STS", fVectorArray, kTRUE); // AZ-041125
161
162 if (fOut / 3 > 0) { // AZ-260922
163 // Store triplets
164 // AZ-240623 fMap3OutPtr = &fMap3Out;
165 // AZ-240623 ioman->RegisterAny("Triplets", fMap3OutPtr, kTRUE);
166 fStream3out.open("triplets.txt", std::ofstream::out);
167 }
168 if (fOut && fOut % 2 == 0) { // AZ-260922
169 // Store doublets
170 // AZ-240623 fMap2OutPtr = &fMap2Out;
171 // AZ-240623 ioman->RegisterAny("Doublets", fMap2OutPtr, kTRUE);
172 fStream2out.open("doublets.txt", std::ofstream::out);
173 }
174
175 fXyzv[0] = 0.4;
176 fXyzv[1] = 0.1;
177 fXyzv[2] = 0.0;
178
179 fitter.Init();
180
181 // Define logic
182 vector<int> nHitsMin = {7, 5, 4, 4}; // min number of hits per track vs iteration - Run 7
183 // static Int_t nHitsMin[20] = {7, 5, 4, 3}; // min number of hits per track vs iteration - Run 7
184 // static Double_t dTanX[20] = {0.001, 0.003, 0.002, 0.008}; // window size in TanX vs iteration
185 vector<Double_t> dTanX = {0.002, 0.003, 0.002, 0.008}; // window size in TanX vs iteration
186 vector<Double_t> dTanXTMVA = {0.003, 0.0045, 0.003, 0.012}; // window size in TanX vs iteration - for TMVA
187 vector<Double_t> dTanXB0 = {0.001, 0.002, 0.002, 0.002}; // window size in TanX vs iteration - for zero field
188 // static Double_t dTanY[20] = {0.01, 0.02, 0.01, 0.02}; // window size in TanY vs iteration
189 // AZ-230623 static Double_t dTanY[20] = {0.01, 0.02, 0.02, 0.03}; // window size in TanY vs iteration
190 vector<Double_t> dTanY = {0.02, 0.02, 0.02, 0.03}; // window size in TanY vs iteration
191 // static Double_t dTanY[20] = {0.05, 0.05, 0.05, 0.1}; // window size in TanY vs iteration - 221225 - test
192 vector<Double_t> dTanYTMVA = {0.015, 0.03, 0.03, 0.045}; // window size in TanY vs iteration - for TMVA
193 vector<Double_t> dTanYB0 = {0.01, 0.02, 0.02, 0.02}; // window size in TanY vs iteration - for zero field
194 // AZ-220623 static Double_t dTanY3[20] = {0.01, 0.02, 0.02, 0.03}; // window size in TanY vs iteration
195 vector<Double_t> dTanY3 = {0.03, 0.02, 0.015, 0.015}; // AZ-220623 window size in TanY vs iteration
196 vector<Double_t> dTanY3TMVA = {0.015, 0.03, 0.03, 0.045}; // window size in TanY vs iteration - for TMVA
197 vector<Double_t> dTanY3B0 = {0.01, 0.02, 0.02, 0.02}; // window size in TanY vs iteration - for zero field
198 vector<Double_t> dTanXzero = {0.01, 0.02, 0.02, 0.02}; // window size in TanX vs iteration - for zero field
199 // static Double_t dVarX[20] = {0.004, 0.01, 0.006, 0.02}; // window size in VarX vs iteration - coherent with
200 // ptCut AZ-120623 static Double_t ptCut[20] = {1.0, 0.3, 0.7, 0.1}; // min pxz
201 vector<Double_t> ptCut = {1.0, 0.7, 0.3, 0.1}; // min pxz - 120623
202 vector<Double_t> ptCutB0 = {1., 1., 1., 1.}; // AZ-010123: min pxz - zero field
203 // static Double_t ptCutB0[20] = {0.5, 0.5, 0.5, 0.5 }; //AZ-010123: min pxz - zero field
204 vector<Double_t> curvSta = {
205 12.0, 12.0, 12.0, 7.5, 5.5, 4.5,
206 3.6, 3.0, 3.0, 3.0, 3.0}; // AZ-310722 - max curvature in stations (for tracks starting in Si)
207 vector<Double_t> curvSta41 = {
208 12.0, 12.0, 12.0, 12.0, 7.5, 5.5, 4.5,
209 3.6, 3.0, 3.0, 3.0, 3.0}; // AZ-190625 - max curvature in stations (for tracks starting in Si) 4Si+VSP
210 // static Double_t curvSta4[20] = {12.0, 12.0, 12.0, 10.0, 7.5, 5.5, 4.5, 3.6, 3.0, 3.0, 3.0}; //AZ-051022 -
211 // max curvature in stations (for tracks starting in Si) - 4 Si stations
212 vector<Double_t> phiXZ = {0.76, 0.69, 0.69, 0.95, 0.74, 0.60, 0.51, 0.44, 0.39, 0.35}; // Max phi_XZ in stations
213 // static Double_t phiXZ4[20] = {0.76, 0.69, 0.69, 0.66, 0.95, 0.74, 0.60, 0.51, 0.44, 0.39, 0.35}; //Max
214 // phi_XZ in stations - 4 Si
215 vector<Double_t> phiXZ4 = {0.60, 0.63, 0.61, 0.62, 0.95, 0.74,
216 0.60, 0.51, 0.44, 0.39, 0.35}; // AZ-051122 - 4 Si 6_10_14_18
217 vector<Double_t> phiXZ41 = {1.00, 0.60, 0.63, 0.61, 0.62, 0.95,
218 0.74, 0.60, 0.51, 0.44, 0.39, 0.35}; // AZ-190625 - 4 Si 6_10_14_18 + VSP
219 vector<Double_t> tanXmax = {0.95, 0.83, 0.83, 1.40, 0.91, 0.68, 0.56, 0.47, 0.41, 0.37}; // Max tan_X in stations
220 // static Double_t tanXmax4[20] = {0.95, 0.83, 0.83, 0.77, 1.40, 0.91, 0.68, 0.56, 0.47, 0.41, 0.37}; //Max
221 // tan_X in stations - 4 Si
222 vector<Double_t> tanXmax4 = {0.68, 0.73, 0.69, 0.71, 1.40, 0.91,
223 0.68, 0.56, 0.47, 0.41, 0.37}; // AZ-051122 - 4 Si 6_10_14_18
224 vector<Double_t> tanXmax41 = {1.50, 0.68, 0.73, 0.69, 0.71, 1.40,
225 0.91, 0.68, 0.56, 0.47, 0.41, 0.37}; // AZ-190625 - 4 Si 6_10_14_18 + VSP
226 vector<Double_t> zMean = {18.5, 27.2, 35.8, 60.9, 91.7, 123.4, 154.0, 185.8, 216.5, 248.0}; // Mean Z of stations
227 // static Double_t zMean4[20] = {18.5, 27.2, 35.8, 44.4, 60.9, 91.7, 123.4, 154.0, 185.8, 216.5, 248.0}; //Mean Z
228 // of stations - 4 Si AZ-301222 static Double_t zMean4[20] = {14.9, 23.5, 32.1, 40.8, 60.9, 91.7, 123.4, 154.0,
229 // 185.8, 216.5, 248.0}; //AZ-051122 - 4Si 6_10_14_18
230 vector<Double_t> zMean4 = {17.6, 26.4, 35.1, 43.7, 63.6, 94.2,
231 126.5, 156.8, 189.0, 219.2, 251.4}; // AZ-301222 - 4Si 6_10_14_18 - beam data
232 vector<Double_t> zMean41 = {7.6, 17.6, 26.4, 35.1, 43.7, 63.6,
233 94.2, 126.5, 156.8, 189.0, 219.2, 251.4}; // AZ-190625 - 4Si 6_10_14_18 + VSP
234 //*/
235
236 FairField* magField = FairRunAna::Instance()->GetField();
237 fBy = TMath::Abs(magField->GetBy(0.0, 0.0, 135.0)) / 10; // max. field in Tesla
238
239 fNhitsMin = nHitsMin;
240 fdTanX = (fUseTMVA) ? dTanXTMVA : dTanX;
241 fdTanY = (fUseTMVA) ? dTanYTMVA : dTanY;
242 fdTanY3 = (fUseTMVA) ? dTanY3TMVA : dTanY3;
243 fPTcut = ptCut;
244 // AZ-311222
245 if (fBy < 0.2) {
246 fdTanX = dTanXB0;
247 fdTanY = dTanYB0;
248 fdTanY3 = dTanY3B0;
249 fPTcut = ptCutB0;
250 } // AZ-311222
251 fdTanXB0 = dTanXzero; // AZ-010123
252 fPhiXZ = (fNSi == 4) ? phiXZ4 : phiXZ;
253 if (fNSi == 5)
254 fPhiXZ = phiXZ41; // AZ-190625 - 4Si+VSP
255 fTanXmax = (fNSi == 4) ? tanXmax4 : tanXmax;
256 if (fNSi == 5)
257 fTanXmax = tanXmax41; // AZ-190625 - 4Si+VSP
258 fZmean = (fNSi == 4) ? zMean4 : zMean;
259 if (fNSi == 5)
260 fZmean = zMean41; // AZ-190625 - 4Si+VSP
261 // fVarx = dVarX;
262 fCurvSta = curvSta;
263 if (fNSi == 5)
264 fCurvSta = curvSta41;
265
266 // AZ-240626 for (int j = 0; j < 20; ++j)
267 for (int j = 0; j < (int)fPTcut.size(); ++j)
268 if (fPTcut[j] > 0.001)
269 fPTcut[j] = 1 / fPTcut[j]; // AZ-170722 - curvature
270
271 // fExact = 1; // for debug // removed DZ 13.10.2021
272 // fExactSel = 13; // for debug
273
274 if (fExact) {
275 // if (1) {
276 // Open windows
277 // Double_t scale = 3;
278 Double_t scale = 1;
279 // AZ-240626 for (Int_t j = 0; j < 20; ++j) {
280 for (Int_t j = 0; j < (int)dTanX.size(); ++j) {
281 dTanX[j] *= scale;
282 dTanY[j] *= scale;
283 // dX[j] *= scale;
284 }
285 }
286
287 // AZ-271222 for (int j = 0; j < 20; ++j) fCurvSta[j] *= (0.8 / fBy); //AZ-290822 - max curvature vs field
288 if (fBy > 0.1)
289 // AZ-240626 for (int j = 0; j < 20; ++j)
290 for (int j = 0; j < (int)fCurvSta.size(); ++j)
291 fCurvSta[j] *= (0.8 / fBy);
292 // AZ-311222 else fBy = 0.1; // zero mag. field
293
294 // Read system info
295 fTxBinw = 0.01;
296 TString fileGraphs = gSystem->ExpandPathName("$VMCWORKDIR");
297 fileGraphs += "/parameters/reco/";
298 if (fNSi == 4)
299 fileGraphs += "fitGraphs_8kG.txt"; // Run 8
300 else
301 fileGraphs += "fitGraphs_8kG_vsp.txt"; // AZ-220625 - Run 9
302 ReadTxInfo(fileGraphs);
303
304 if (fMatBudgetFileName != "")
305 fitter.ReadMatBudget(fMatBudgetFileName);
306
307 if (fUseTMVA == 2)
308 InitTMVA2(); // AZ-221022 - for doublets
309 if (fUseTMVA)
310 InitTMVA3(); // AZ-300922 - for triplets
311 if (fTMVAtracks)
312 InitTMVAtracks(); // AZ-040525 - for tracks
313
314 // Create tracking detector setups------------------------------------------------------
315 TString pathConfig = gSystem->Getenv("VMCWORKDIR");
316 fGemStationSet = new BmnGemStripStationSet(pathConfig + "/parameters/gem/XMLConfigs/" + fGemConfigFile);
317 fSilStationSet = new BmnSiliconStationSet(pathConfig + "/parameters/silicon/XMLConfigs/" + fSilConfigFile);
318
319 cout << "-I- BmnStsVectorFinderV9: Intialisation successfull" << endl;
320
321 return kSUCCESS;
322}
323// -------------------------------------------------------------------------
324
326{
327 // Read information about Tx windows
328
329 ifstream fin;
330 fin.open(fileName);
331 if (fin.fail()) {
332 cout << " !!! Error opening Tx file " << fileName << endl;
333 exit(1);
334 }
335 TString chline;
336 TObjArray* tokens = NULL;
337 int ista0 = -1, ista2;
338 vector<Float_t> params(10);
339
340 while (1) {
341 chline.ReadLine(fin);
342 if (fin.eof())
343 break;
344 // cout << chline << endl;
345 tokens = chline.Tokenize(" ");
346 int ntok = tokens->GetEntriesFast();
347 // if (chline.Contains("Station")) {
348 if (ntok == 4) {
349 // Station info
350 int j = 1;
351 ista0 = ((TObjString*)tokens->UncheckedAt(j++))->String().Atoi();
352 int ista1 = ((TObjString*)tokens->UncheckedAt(j++))->String().Atoi();
353 ista2 = 100 * ista0 + ista1;
354 if (fStatData.find(ista2) != fStatData.end())
355 continue;
356 // Float_t txmax = TMath::Abs (((TObjString*)tokens->UncheckedAt(j++))->String().Atof());
357 fTxStep = ((TObjString*)tokens->UncheckedAt(j))->String().Atof();
358 unordered_map<int, vector<Float_t>> mstat;
359 fStatData[ista2] = mstat;
360 // fTanXmax[ista0] = TMath::Abs(txmax); // average max Tx (for upper and lower parts)
361 fTanXmax[ista0] = -9;
362 } else {
363 // int ibin = ((TObjString*)tokens->UncheckedAt(0))->String().Atoi();
364 Float_t binc = ((TObjString*)tokens->UncheckedAt(0))->String().Atof();
365 int ilr = ((TObjString*)tokens->UncheckedAt(1))->String().Atoi();
366 Float_t binc1 = binc;
367 if (binc1 > 90.0)
368 binc1 -= 100.0;
369 if (fTanXmax[ista0] < -8) {
370 fTanXmax[ista0] = TMath::Abs(binc1 - fTxStep / 2);
371 // cout << ista0 << " " << fTanXmax[ista0] << endl;
372 }
373 int ibin = FindBin(ista0, fTxStep, binc1);
374 if (binc > 90.0)
375 ibin += 1000;
376 for (int j = 0; j < 5; ++j)
377 params[ilr * 5 + j] = ((TObjString*)tokens->UncheckedAt(j + 2))->String().Atof();
378 // if (ilr > 0) fStatData[ista2].insert(pair<int,vector<Float_t> >(ibin,params));
379 if (ilr > 0)
380 fStatData[ista2][ibin] = params;
381 }
382 if (tokens) {
383 tokens->Delete();
384 delete tokens;
385 tokens = NULL;
386 }
387 }
388 fin.close();
389 cout << "-I- BmnStsVectorFinderV9: Station info has been read from " << fileName << endl;
390}
391
392// ----- Public method Exec --------------------------------------------
394{
395
396 TStopwatch sw;
397 sw.Start();
398
399 //*
400 // Reset output array
401 if (!fHitArray)
402 Fatal("Exec", "No StsHit array");
403
404 // AZ-230626
405 if (fKillHitsTxP) {
406 // Kill hits in momentum space in MC
407 KillHitsTxP();
408 }
409
410 fVectorArray->Delete();
411 fMap2Out.clear(); // AZ-210922
412 fMap3Out.clear(); // AZ-260922
413
414 for (Int_t j = 0; j < 19; ++j) {
415 fCandSet[j].clear();
416 // fTripleCodes[j].clear();
417 fCandCodes[j].clear();
418 }
419
420 // AZ-100722 Int_t nTracks = fTrackArray->GetEntriesFast();
421 // AZ-100722 if (nTracks == 0) return;
422 Int_t nTracks = 0;
423 if (fTrackArray) {
424 nTracks = fTrackArray->GetEntriesFast();
425 if (nTracks == 0)
426 return;
427 }
428
429 const Int_t nPass = 4; // 4; //5; //8;
431 for (Int_t j = 0; j < nPass; ++j)
432 fNskips[j] = nsta - fNhitsMin[j];
433
434 Int_t nHits0 = fHitArray->GetEntriesFast(), idmaxP = 0;
435 // cout << " !!! nHits0 " << nHits0 << endl; // AZ-230626
436
437 // Fill cluster-to-hit maps
438 fHit2id.clear();
439 fClusMaps[0].clear();
440 fClusMaps[1].clear();
441 fmapHits.clear();
442
443 for (Int_t ihit = 0; ihit < nHits0; ++ihit) {
444 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(ihit);
445 if (hit->GetUniqueID() != 999)
446 hit->SetUniqueID(0); // AZ-021125 - reset hit status
447 if (hit->GetZ() > 400.0)
448 continue; // AZ-290323 - exclude small GEM downstream
449 Int_t iclusF = hit->GetDigi(0);
450 Int_t iclusB = hit->GetDigi(1);
451 fClusMaps[0].insert(pair<Int_t, Int_t>(iclusF, ihit));
452 fClusMaps[1].insert(pair<Int_t, Int_t>(iclusB, ihit));
453 Int_t ista = hit->GetStationNr() - 0;
454 fNsta = TMath::Max(fNsta, ista);
455 // Code below for debugging
456 if (fVerbose > 0) {
457 set<Int_t> idset = GetHitId(hit, idmaxP);
458 for (set<Int_t>::iterator sit = idset.begin(); sit != idset.end(); ++sit)
459 fHit2id.insert(pair<Int_t, Int_t>(ihit, *sit));
460 }
461 }
462
463 Int_t nHitsOut = 0;
464 discarded = 0;
465 // AZ-080623 BuildTrackCand();
466 FillHitInfo(); // AZ-080623
467
468 for (Int_t ipass = 0; ipass < nPass; ++ipass) {
469 // for (Int_t ipass = nPass-1; ipass < nPass; ++ipass) {
470 fPass = ipass;
471 // Int_t minHits = 5; //4; // minimum number of hits on tracks to accept
472 // Int_t minHits = (ipass == 0) ? 15 : 5; // minimum number of hits on tracks to accept
473 Int_t minHits = (ipass == 0) ? 15 : -fNhitsMin[ipass - 1]; // minimum number of hits on tracks to accept
474 TClonesArray* trArray = (ipass == 0) ? fTrackArray : fVectorArray;
475 nHitsOut += ExcludeHits(minHits, trArray);
476
477 if (fVerbose > 0) {
478 cout << "-I- BmnStsVectorFinderV9: start - " << nHits0 << ", end - " << nHits0 - nHitsOut << endl;
479 }
480
481 Int_t ntr0 = fVectorArray->GetEntriesFast();
482 // BuildTrackCand();
483 /*
484 //ExtendTracks(fNsta-1);
485 FitTracks();
486 RemoveFakes();
487 RemoveDoubles();
488 cout << "\n ***** Pass " << ipass << ": Number of found tracks = "
489 << fVectorArray->GetEntriesFast() - ntr0 << " " << fVectorArray->GetEntriesFast() << "\n" << endl;
490 //if (fNhitsMin[ipass] <= 4) RemoveFakes();
491 */
494 fTracks.clear(); //
495 BuildTracks();
496 FitTracks();
498 if (fVerbose > 0) {
499 // if (1) {
500 cout << "\n ***** Pass " << ipass << ": Number of found tracks = " << fVectorArray->GetEntriesFast() - ntr0
501 << " " << fVectorArray->GetEntriesFast() << "\n"
502 << endl;
503 }
504 // GoToTarget(); //AZ-240625
505 }
506
507 if (fVerbose > 0)
508 cout << "discarded " << discarded << " track candidates" << endl;
509
510 // Post-processing - try to exclude fake tracks (with too many shared clusters)
511 ExcludeFakes();
512 if (fTMVAtracks)
513 TMVAOutputTra(); // AZ-040525
514
515 // AZ-230626
516 // cout << " BBBBB hits " << fHitArray->GetEntriesFast() << " " << fVectorArray->GetEntriesFast() << endl;
517
518 sw.Stop();
519 workTime += sw.RealTime();
520}
521
522// -------------------------------------------------------------------------
523
525{
526 // Exclude hits used for tracking
527
528 // AZ-100722 Int_t nTracks = trArray->GetEntriesFast();
529 Int_t nTracks = 0; // AZ-100722
530 if (trArray)
531 nTracks = trArray->GetEntriesFast(); // AZ-100722
532
533 if (nTracks == 0)
534 return 0;
535 Int_t nHitsOut = 0;
536 // AZ-130722 multimap<Int_t,Int_t>::iterator mit;
537 // AZ-130722 pair<multimap<Int_t,Int_t>::iterator,multimap<Int_t,Int_t>::iterator> ret;
538 unordered_multimap<Int_t, Int_t>::iterator mit;
539 pair<unordered_multimap<Int_t, Int_t>::iterator, unordered_multimap<Int_t, Int_t>::iterator> ret; // AZ-130722
540
541 for (Int_t itra = 0; itra < nTracks; ++itra) {
542 CbmStsTrack* track = (CbmStsTrack*)trArray->UncheckedAt(itra);
543 if (track->GetNStsHits() < minHits) {
544 trArray->Remove(track);
545 continue;
546 }
547
548 Int_t nHitsTr = track->GetNStsHits();
549
550 for (Int_t ihit = 0; ihit < nHitsTr; ++ihit) {
551 int indx = track->GetStsHitIndex(ihit); // AZ-130722
552 // AZ-130722 CbmStsHit *hit = (CbmStsHit*) fHitArray->UncheckedAt(track->GetStsHitIndex(ihit));
553 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(indx); // AZ-130722
554 if (!hit)
555 continue;
556
557 if (fNhitsMin[fPass] < -5) {
558 // if (fNhitsMin[fPass] > 6) { //AZ-180722
559 // Exclude all hits created from given clusters
560 Int_t iclusF = hit->GetDigi(0);
561 ret = fClusMaps[0].equal_range(iclusF);
562 for (mit = ret.first; mit != ret.second; ++mit) {
563 CbmStsHit* hit1 = (CbmStsHit*)fHitArray->UncheckedAt(mit->second);
564 if (hit1->GetUniqueID() == 0)
565 ++nHitsOut; // excluded hit - used in track
566 hit1->SetUniqueID(1); // exclude hit - used in track
567 // AZ-130722 fmapHits[ihit].used = 1;
568 fmapHits[mit->second].used = 1; // AZ-130722
569 }
570 Int_t iclusB = hit->GetDigi(1);
571 ret = fClusMaps[1].equal_range(iclusB);
572 for (mit = ret.first; mit != ret.second; ++mit) {
573 CbmStsHit* hit1 = (CbmStsHit*)fHitArray->UncheckedAt(mit->second);
574 if (hit1->GetUniqueID() == 0)
575 ++nHitsOut; // excluded hit - used in track
576 hit1->SetUniqueID(1); // exclude hit - used in track
577 // AZ-130722 fmapHits[ihit].used = 1;
578 fmapHits[mit->second].used = 1; // AZ-130722
579 }
580 }
581 if (hit->GetUniqueID() == 0)
582 ++nHitsOut;
583 hit->SetUniqueID(1);
584 // AZ-130722 fmapHits[ihit].used = 1;
585 fmapHits[indx].used = 1; // AZ-130722
586
587 // AZ-130722 Remove used doublets
588 //*
589 int ista = hit->GetStationNr() - 1;
590 ret = fMap2[ista].equal_range(indx);
591 fMap2[ista].erase(ret.first, ret.second);
592 // AZ-140722 Remove used triplets
593 ret = fMap3[ista].equal_range(indx);
594 for (mit = ret.first; mit != ret.second; ++mit) {
595 candvec cand = fCandVec3[ista][mit->second];
596 string code = MakeCode(cand);
597 fMapCode3[ista].erase(code);
598 }
599 fMap3[ista].erase(ret.first, ret.second);
600 //*/
601 }
602 }
603
604 trArray->Compress();
605 return nHitsOut;
606}
607
608// -------------------------------------------------------------------------
609
611{
612 // Get IDs contributing to given hit (for debugging purposes)
613
614 // AZ-241222 if (fClusArray[1]) return GetHitIdBmn (hit, idmaxP); // BmnRoot data structures
615 if (1)
616 return GetHitIdBmn(hit, idmaxP); // BmnRoot data structures - AZ-241222
617
618 set<Int_t> ids;
619 // return ids; // FIXME
620
621 Int_t iclusF = hit->GetDigi(0);
622 Int_t iclusB = hit->GetDigi(1);
623 CbmStsCluster* clusF = (CbmStsCluster*)fClusArray[0]->UncheckedAt(iclusF);
624 CbmStsCluster* clusB = (CbmStsCluster*)fClusArray[0]->UncheckedAt(iclusB);
625
626 map<Int_t, Double_t> indF, indB;
627 // set<Int_t> ids;
628 Int_t nDigis = clusF->GetNDigis();
629 Double_t pmax = 0.0;
630 TVector3 mom3;
631
632 for (Int_t j = 0; j < nDigis; ++j) {
633 CbmStsDigiMatch* digiMatch = (CbmStsDigiMatch*)fDigiMatches->UncheckedAt(clusF->GetDigi(j));
634 for (Int_t j1 = 0; j1 < 3; ++j1) {
635 Int_t ip = digiMatch->GetRefIndex(j1);
636 if (ip < 0)
637 break;
638 CbmStsPoint* p = (CbmStsPoint*)fStsPoints->UncheckedAt(ip);
639 p->Momentum(mom3);
640 indF[p->GetTrackID()] = mom3.Mag();
641 }
642 }
643
644 nDigis = clusB->GetNDigis();
645
646 for (Int_t j = 0; j < nDigis; ++j) {
647 CbmStsDigiMatch* digiMatch = (CbmStsDigiMatch*)fDigiMatches->UncheckedAt(clusB->GetDigi(j));
648 for (Int_t j1 = 0; j1 < 3; ++j1) {
649 Int_t ip = digiMatch->GetRefIndex(j1);
650 if (ip < 0)
651 break;
652 CbmStsPoint* p = (CbmStsPoint*)fStsPoints->UncheckedAt(ip);
653 // Not needed p->Momentum(mom3);
654 indB[p->GetTrackID()] = 1.0; // mom3.Mag();
655 }
656 }
657
658 idmaxP = -1;
659
660 for (map<Int_t, Double_t>::iterator mit = indF.begin(); mit != indF.end(); ++mit) {
661 Int_t id = (indB.count(mit->first) == 0) ? -mit->first : mit->first;
662 ids.insert(id); // negative ID for ghost crossings
663 if (id >= 0 && mit->second > pmax) {
664 pmax = mit->second;
665 idmaxP = id;
666 }
667 }
668 // This is to be consistent with CBM hit matching procedure
669 // (hit is matched with the closest point)
670 if (hit->GetRefIndex() >= 0) {
671 CbmStsPoint* p = (CbmStsPoint*)fStsPoints->UncheckedAt(hit->GetRefIndex());
672 idmaxP = p->GetTrackID();
673 } else
674 idmaxP = -1;
675
676 for (map<Int_t, Double_t>::iterator mit = indB.begin(); mit != indB.end(); ++mit) {
677 if (ids.count(mit->first) > 0)
678 continue;
679 ids.insert(-mit->first); // negative ID for ghost crossings
680 }
681
682 return ids;
683}
684
685// -------------------------------------------------------------------------
686
688{
689 // Get IDs contributing to given hit (for debugging purposes) - for BmnRoot data structures
690
691 set<Int_t> ids;
692 // int ind = 0; // Si hit
693 // if (hit->GetSystemId() == kGEM) ind = 2; // GEM hit
694
695 if (hit->GetRefIndex() == -1 || fStsPoints == nullptr || fSilPoints == nullptr)
696 ids.insert(-1); // fake hit
697 else {
698 // AZ-150722 CbmStsPoint *p = (CbmStsPoint*) fStsPoints->UncheckedAt(hit->GetRefIndex());
699 FairMCPoint* p = nullptr;
700 if (hit->GetSystemId() == kGEM)
701 p = (FairMCPoint*)fStsPoints->UncheckedAt(hit->GetRefIndex());
702 else if (hit->GetSystemId() == kVSP)
703 p = (FairMCPoint*)fVspPoints->UncheckedAt(hit->GetRefIndex());
704 else
705 p = (FairMCPoint*)fSilPoints->UncheckedAt(hit->GetRefIndex());
706 ids.insert(p->GetTrackID());
707 }
708 idmaxP = *ids.begin(); // AZ-290922
709 return ids;
710}
711
712// -------------------------------------------------------------------------
713
714// AZ-080623 void BmnStsVectorFinder::BuildTrackCand()
716{
717 // Fill hit information
718
719 for (Int_t ist = 0; ist < fNsta; ++ist) {
720 // AZ-080623 fmapPhx[ist].clear();
721 fmapTx[ist].clear();
722 fmapTy[ist].clear();
723 fmapX[ist].clear();
724 fmapY[ist].clear();
725 fSeedVec[ist].clear();
726 fCandVec[ist].clear();
727 // fCandMap2[ist].clear();
728 // fCandMap3[ist].clear();
729 fCandVec2[ist].clear();
730 fMap2[ist].clear();
731 fCandVec3[ist].clear();
732 fMap3[ist].clear();
733 fMapCode3[ist].clear();
734 fTxBins[ist].clear();
735 }
736 // fmapHits.clear();
737
738 // AZ-220725 fTxBinw = 0.01; // bin width for hits
739 Int_t nHits = fHitArray->GetEntriesFast(), idmaxP = 0;
740 if (fVerbose > 0)
741 cout << "nHits " << nHits << endl;
742 TVector3 pos;
743
744 for (Int_t ih = 0; ih < nHits; ++ih) {
745 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(ih);
746 if (hit->GetUniqueID())
747 continue; // used hit
748 if (hit->GetZ() > 400.0)
749 continue; // AZ-290323 - exclude small GEM downstream
750 // if (hit->GetSystemId() == kGEM) continue; //!!!AZ-100123 - exclude GEMs
751 // if (hit->GetSystemId() != kGEM) continue; //!!!AZ-100123 - exclude Si
752 // else if (hit->GetSystemId() != kGEM && hit->GetStationNr() == 1) continue; //!!!AZ-110123 - exclude station 1
753 // else if (hit->GetSystemId() != kGEM && hit->GetStationNr() == 4) continue; //!!!AZ-110123 - exclude station 1
754 // if (hit->GetSystemId() == kGEM && hit->GetStationNr() > 7 && TMath::Abs(hit->GetX()) < 10.0 &&
755 // TMath::Abs(hit->GetY()) < 15.0) continue; //!!!AZ-130123 - exclude beam region
756 /*if (hit->GetSystemId() == kGEM && hit->GetSectorNr() > 4) continue; //300123 - exclude lower GEMs
757 else if (hit->GetSystemId() != kGEM) {
758 //AZ-300123 - exclude lower Si
759 if (hit->GetStationNr() == 1 && hit->GetSectorNr() > 3) continue;
760 if (hit->GetStationNr() == 2 && hit->GetSectorNr() > 5) continue;
761 if (hit->GetStationNr() == 3 && hit->GetSectorNr() > 7) continue;
762 if (hit->GetStationNr() == 4 && hit->GetSectorNr() > 9) continue;
763 }*/
764 // AZ-260423 - apply cluster charge correlation cut
765 // if (hit->GetSystemId() == kGEM && TMath::Abs(hit->GetSignalDiv()+0.08) > 0.5) continue;
766 // else if (hit->GetSystemId() != kGEM && TMath::Abs(hit->GetSignalDiv()-0.11) > 0.5) continue;
767 if (fExactSel >= 0) {
768 // Accept only hits with given ID - for debug
769 set<Int_t> ids = GetHitId(hit, idmaxP);
770 if (ids.count(fExactSel) == 0)
771 continue;
772 }
773 if (fExact) {
774 // Accept only true hits
775 set<Int_t> ids = GetHitId(hit, idmaxP);
776 if (idmaxP < 0)
777 continue;
778 }
779 Int_t ista = hit->GetStationNr() - 1;
780 //!!! For debug
781 // if (ista > 2) continue;
782 // if (ista >= 4) continue; //AZ-201222 - Si only
783 //!!!
784 hit->Position(pos);
785 Double_t dx = hit->GetX() - fXyzv[0];
786 Double_t dy = hit->GetY() - fXyzv[1];
787 Double_t dz = hit->GetZ() - fXyzv[2];
788 Double_t by = (fBy < 0.2) ? 0.8 : fBy; // AZ-271222
789 // AZ-250822 if (fPass >= 0) fmapHits[ih] = hitinfo(pos,dx/dz,dy/dz);
790 // 271222 if (fPass >= 0) fmapHits[ih] = hitinfo (pos, TMath::ATan2(dx,dz)/fPhiXZ[ista]/fZmean[ista]/fBy,
791 // dy/dz/fTanXmax[ista]); //AZ-280822 AZ-010123 if (fPass >= 0) fmapHits[ih] = hitinfo (pos,
792 // TMath::ATan2(dx,dz)/fPhiXZ[ista]/fZmean[ista]/by, dy/dz/fTanXmax[ista]); //AZ-271222
793 Double_t tanx = dx / dz;
794 // Double_t tanx = dx / (fZmean[ista] - fXyzv[2]); //AZ-090623 - w.r.t. nominal vertex (mean station Z!!!)
795 if (fPass >= 0)
796 fmapHits[ih] = hitinfo(pos, TMath::ATan2(dx, dz) / fPhiXZ[ista] / fZmean[ista] / by,
797 // AZ-070623 dx/dz/fTanXmax[ista], dy/dz/fTanXmax[ista]); //AZ-010123
798 // tanx/fTanXmax[ista], dy/dz/fTanXmax[ista]); //AZ-070623
799 // AZ-230623 tanx, dy/dz/fTanXmax[ista]); //AZ-080623
800 tanx, dy / dz); // AZ-230623
801 fmapX[ista].insert(pair<Double_t, Int_t>(pos[0], ih));
802 fmapY[ista].insert(pair<Double_t, Int_t>(pos[1], ih));
803 // AZ-080623 fmapPhx[ista].insert(pair<Double_t,Int_t>(fmapHits[ih].phx,ih));
804 fmapTx[ista].insert(pair<Double_t, Int_t>(fmapHits[ih].tx, ih));
805 fmapTy[ista].insert(pair<Double_t, Int_t>(fmapHits[ih].ty, ih));
806 // AZ-070623 - hit binning in Tx
807 int ista2 = ista * 100 + ista + 1;
808 int bin = FindBin(ista, fTxBinw, fmapHits[ih].tx);
809 if (bin < 0)
810 continue; // AZ-270623
811 int binStat = FindBin(ista, fTxStep, BinCenterTx(ista, bin, fTxBinw));
812 if (dy > 0)
813 binStat += 1000; // AZ-270623
814 if (fStatData[ista2].find(binStat) == fStatData[ista2].end())
815 continue;
816 // int bin = (tanx + fTanXmax[ista]) / fTxBinw;
817 if (dy > 0)
818 bin += 1000;
819 // int bin = (tanxMean + fTanXmax[ista]) / fTxBinw;
820 fTxBins[ista].insert(pair<int, int>(bin, ih));
821 } // for (Int_t ih = 0;
822 /*
823 //const Int_t stastop[9] = { fNsta-1, fNsta-2, fNsta-4}; // stop station vs iteration
824 //const Int_t stastop[9] = { fNsta-3, fNsta-2, fNsta-3}; // stop station vs iteration
825 Int_t stastop = fNsta - 1 - fNskips[fPass];
826 stastop = 0;
827
828 if (fVerbose > 0) cout << "fNskips fPass " << fNskips[fPass] << " " << fPass << " stastop " << stastop << " fNsta-1
829 " << fNsta-1 << endl;
830
831 for (Int_t ista = fNsta-1; ista >= stastop; --ista) {
832 if (fVerbose > 0) cout << "xmapsize " << fmapX[ista].size() << endl;
833 for (multimap<Double_t,Int_t>::iterator mit = fmapX[ista].begin(); mit != fmapX[ista].end(); ++mit) {
834 candvec aaa;
835 //AZ-280323 aaa.nskips = fNsta - 1 - ista;
836 aaa.nskips = 0; //AZ-280323
837 aaa.momxz = 0.0;
838 aaa.stahit[ista] = mit->second;
839 aaa.code = "-" + to_string(aaa.stahit[ista]) + "-"; // hit index coded
840 //if (fExact) {
841
842 set<Int_t> ids = GetHitId(mit->second, idmaxP);
843 aaa.idmaxP = idmaxP;
844 //}
845 //cout << "aaa.z " <<((CbmStsHit*) fHitArray->UncheckedAt(aaa.stahit[ista]))->GetZ() << " ";
846 fSeedVec[ista].push_back(aaa);
847 } //for (multimap<Double_t,Int_t>::iterator mit
848
849 if (fVerbose > 0) {
850 Int_t ncand = fSeedVec[ista].size();
851 cout << " Vector stat: " << ista << " " << ncand;// << endl;
852 //AZ-130722 pair<multimap<Int_t, Int_t>::iterator, multimap<Int_t, Int_t>::iterator> ret;
853 pair<unordered_multimap<Int_t, Int_t>::iterator, unordered_multimap<Int_t, Int_t>::iterator> ret; //AZ-130722
854
855 for (Int_t j = 0; j < ncand; ++j) {
856 Int_t ih = fSeedVec[ista][j].stahit[ista];
857 ret = fHit2id.equal_range(ih);
858 cout << " (" << ih << "*";
859 //AZ-130722 for (multimap<Int_t, Int_t>::iterator mit = ret.first; mit != ret.second; ++mit) {
860 for (unordered_multimap<Int_t, Int_t>::iterator mit = ret.first; mit != ret.second; ++mit) { //AZ-130722
861 if (mit != ret.first) cout << ":";
862 cout << mit->second;
863 }
864 cout << ")";
865 }
866 cout << "\n";
867 }
868 } // for (Int_t ista = fNsta-1;
869 */
870}
871
872// -------------------------------------------------------------------------
873
875{
876 // Build doublets
877
878 int rebuild2 = 1; // AZ-140722
879
880 // Run8
881 const unordered_map<string, float> scaleMap4 = {
882 {"01", 1.9}, {"02", 2.8}, {"12", 1.0}, {"13", 1.5}, {"23", 0.65}, {"24", 1.4}, {"34", 0.95},
883 {"35", 1.5}, {"45", 1.0}, {"46", 1.5}, {"56", 0.7}, {"57", 1.0}, {"67", 0.6}, {"68", 0.7},
884 {"78", 0.35}, {"79", 0.5}, {"89", 0.3}, {"810", 0.35}, {"910", 0.25}};
885 // Run 9
886 const unordered_map<string, float> scaleMap5 = {
887 {"01", 11.5}, {"02", 15.0}, {"12", 1.9}, {"13", 2.8}, {"23", 1.0}, {"24", 1.5}, {"34", 0.65},
888 {"35", 1.4}, {"45", 0.95}, {"46", 1.5}, {"56", 1.0}, {"57", 1.5}, {"67", 0.7}, {"68", 1.0},
889 {"78", 0.6}, {"79", 0.7}, {"89", 0.35}, {"810", 0.5}, {"910", 0.3}, {"911", 0.35}, {"1011", 0.25}};
890
891 for (Int_t ist = 0; ist < fNsta; ++ist) {
892 fCandVec[ist].clear();
893 fCandVec2[ist].clear();
894 fMap2[ist].clear();
895 fCandVec3[ist].clear();
896 fMap3[ist].clear();
897 fMapCode3[ist].clear();
898 // AZ-140722 - Does not seem to speed up
899 /*
900 if ( (fPass == 0) || (TMath::Abs(fdTanX[fPass]-fdTanX[fPass-1]) > 0.001) || //AZ-140722
901 (TMath::Abs(fdTanY[fPass]-fdTanY[fPass-1]) > 0.001) ) {
902 fCandVec2[ist].clear();
903 fMap2[ist].clear();
904 rebuild2 = 1;
905 }
906 */
907 }
908 if (rebuild2 == 0)
909 return; // AZ-140722 - do not rebuild doublets
910 const unordered_map<string, float>& scaleMap = (fNSi == 4) ? scaleMap4 : scaleMap5;
911
912 Int_t idmaxP = 0;
913
914 for (Int_t ista = 0; ista < fNsta - 1; ++ista) {
915 int nHits = fTxBins[ista].size();
916 // cout << " nHits: " << ista << " " << nHits << endl;
917 if (nHits == 0)
918 continue;
919 string ssta0 = to_string(ista);
920
921 for (int istanext = ista + 1; istanext < ista + 3; ++istanext) {
922 // for (int istanext = ista + 1; istanext < ista + 2; ++istanext) { // no jumps over station
923 if (istanext > fNsta - 1)
924 continue;
925 if (fmapX[istanext].size() == 0)
926 continue;
927 Double_t dty = fdTanY[fPass]; //, dphx = fdTanX[fPass];
928 // dty *= 5; //AZ-040822
929 // dtx *= 2; //AZ-040822
930 int nskips = istanext - (ista + 1);
931 int ibin0 = -99, ista2 = ista * 100 + istanext;
932 set<Int_t> setTx;
933 Float_t tx = 0;
934 string ssta2 = ssta0 + to_string(istanext);
935 dty *= (scaleMap.find(ssta2)->second);
936
937 for (unordered_multimap<int, int>::iterator mit = fTxBins[ista].begin(); mit != fTxBins[ista].end(); ++mit)
938 {
939 // AZ-070623 - Loop over binned hits
940 int ih = mit->second;
941 if (fmapHits[ih].used)
942 continue; // used hit
943 candvec aaa;
944 aaa.nskips = 0;
945 aaa.momxz = 0.0;
946 aaa.stahit[ista] = mit->second;
947 aaa.code = "-" + to_string(aaa.stahit[ista]) + "-"; // hit index coded
948 set<Int_t> ids = GetHitId(mit->second, idmaxP);
949 aaa.idmaxP = idmaxP;
950
951 int ibin = mit->first;
952 if (ibin != ibin0) {
953 // Compute dTx constraints for this bin
954 ibin0 = ibin;
955 setTx.clear();
956 tx = BinCenterTx(ista, ibin, fTxBinw);
957 Float_t dtx[2] = {0};
958 DTxWindow(ista2, tx, ibin / 1000, fPTcut[fPass], dtx);
959 // dtx[0] *= 2; dtx[1] *= 2; //
960 if (istanext < fNSi) {
961 dtx[0] *= 2;
962 dtx[1] *= 2;
963 } // AZ-120623
964 // else { dtx[0] *= 1.5; dtx[1] *= 1.5; }
965 // else { dtx[0] *= 1.5; dtx[1] *= 1.5; } // AZ-260625
966 // Get hits on the downstream station
967 // multimap<Double_t,Int_t>::iterator mitxb = fmapPhx[istanext].lower_bound(phx-dphx);
968 // multimap<Double_t,Int_t>::iterator mitxe = fmapPhx[istanext].upper_bound(phx+dphx);
969 multimap<Double_t, Int_t>::iterator mitxb = fmapTx[istanext].lower_bound(tx + dtx[0]);
970 multimap<Double_t, Int_t>::iterator mitxe = fmapTx[istanext].upper_bound(tx + dtx[1]);
971 for (multimap<Double_t, Int_t>::iterator mit1 = mitxb; mit1 != mitxe; ++mit1)
972 if (fmapHits[mit1->second].used == 0)
973 setTx.insert(mit1->second);
974 }
975
976 Double_t ty = fmapHits[ih].ty;
977 // AZ-230623 ty *= (fTanXmax[ista] / fTanXmax[istanext]); //AZ-280822
978 // Double_t tx = fmapHits[ih].tx;
979 // tx *= (fTanXmax[ista] / fTanXmax[istanext]); //AZ-010123
980 multimap<Double_t, candvec> mapDoublets; // AZ-251022 TMVA output -> doublets
981
982 // Get hits on the downstream station
983 multimap<Double_t, Int_t>::iterator mityb = fmapTy[istanext].lower_bound(ty - dty);
984 multimap<Double_t, Int_t>::iterator mitye = fmapTy[istanext].upper_bound(ty + dty);
985 // Get hits from the acceptance window
986 set<Int_t> setTy, intersect;
987 for (multimap<Double_t, Int_t>::iterator mit1 = mityb; mit1 != mitye; ++mit1)
988 if (fmapHits[mit1->second].used == 0)
989 setTy.insert(mit1->second);
990 set_intersection(setTx.begin(), setTx.end(), setTy.begin(), setTy.end(),
991 std::inserter(intersect, intersect.begin()));
992 // if (fVerbose > 0) cout << " Intersect: " << ista << " " << ibin << " " << setTx.size() << " "
993 // << setTy.size() << " " << intersect.size() << " " << endl;
994 Double_t xp = fmapHits[ih].xyz[0]; // AZ-280722
995 Double_t zp = fmapHits[ih].xyz[2]; // AZ-280722
996 // int n0 = fMap2[ista].size(); //AZ-241022 - for debug
997
998 for (set<Int_t>::iterator sit = intersect.begin(); sit != intersect.end(); ++sit) {
999 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(*sit);
1000 if (hit->GetUniqueID())
1001 continue; // used hit
1002 if (fmapHits[*sit].used)
1003 continue;
1004 if (fBy < 0.2 && TMath::Abs(tx - fmapHits[*sit].tx) > fdTanXB0[fPass])
1005 continue; // AZ-010123 - zero mag. field
1006 if (fExact) {
1007 // Exact track ID match
1008 set<Int_t> ids1 = GetHitId(*sit, idmaxP);
1009 // if (ids.count(aaa.idmaxP) == 0) continue;
1010 if (idmaxP != aaa.idmaxP)
1011 continue;
1012 }
1013 candvec aaa1 = aaa;
1014 aaa1.stahit[istanext] = *sit; // second hit of the doublet
1015 Double_t dx = xp - fmapHits[*sit].xyz[0]; // AZ-280722
1016 Double_t dz = zp - fmapHits[*sit].xyz[2]; // AZ-280722
1017 aaa1.lengxz = TMath::Sqrt(dx * dx + dz * dz); // AZ-280722 - doublet length in XZ-plane
1018 aaa1.momxz =
1019 Curv3(aaa1, aaa1, aaa1, 0); // AZ-310722 - pxz-estimate with the origin at the primary vertex
1020 if (fBy > 0.2
1021 && (TMath::Abs(aaa1.momxz) > fPTcut[fPass] || TMath::Abs(aaa1.momxz) > fCurvSta[ista]))
1022 continue; // AZ-010123
1023 else if (fBy < 0.2 && TMath::Abs(aaa1.momxz) / fZmean[1] * fZmean[istanext] > fPTcut[fPass])
1024 continue; // AZ-010123 - zero mag. field
1025 // AZ-300922 aaa1.ty = fmapHits[*sit].ty; //AZ-290822
1026 // AZ-220623 aaa1.ty = ty - fmapHits[*sit].ty; //AZ-300922
1027 aaa1.ty = (fmapHits[ih].xyz[1] - fmapHits[*sit].xyz[1]) / aaa1.lengxz; // AZ-220623
1028 aaa1.tx = tx - fmapHits[*sit].tx; // AZ-010123 - for zero mag. field
1029 // AZ-250822 aaa1.varx = varx;
1030 // cout << " Doublet: " << aaa1.idmaxP << " " << aaa1.stahit.begin()->first << endl; // debug output
1031
1032 if (fOut && fOut % 2 == 0) { // AZ-210922 for writing out
1033 string code = to_string(ih) + "-" + to_string(*sit);
1034 if (fMap2Out.find(code) == fMap2Out.end())
1035 fMap2Out[code] = fPass;
1036 }
1037
1038 // AZ-221022
1039 Double_t tmvaOut = 9.9;
1040 if (fUseTMVA == 2)
1041 tmvaOut = TMVAOutput2(aaa1);
1042 // if (fUseTMVA) outf << tmvaOut << " " << fPass << endl;
1043 // if (tmvaOut < 0.02) continue;
1044 if (tmvaOut < 0.01)
1045 continue;
1046 aaa1.nskips = nskips;
1047
1048 mapDoublets.insert(pair<Double_t, candvec>(-tmvaOut, aaa1)); // AZ-251022
1049 } // for (set<Int_t>::iterator sit = intersect.begin();
1050
1051 // AZ-251022
1052 int n2tot = 0, n2max = (fUseTMVA == 2) ? fNbranches * 2 : 999;
1053
1054 for (auto ait = mapDoublets.begin(); ait != mapDoublets.end(); ++ait) {
1055 fCandVec2[ista].push_back(ait->second);
1056 fMap2[ista].insert(pair<int, int>(ih, fCandVec2[ista].size() - 1));
1057 ++n2tot;
1058 if (n2tot >= n2max)
1059 break;
1060 }
1061 // cout << " *** Doublets : " << ista << " " << ih << " " << fMap2[ista].size()-n0 << endl;
1062 } // for (unordered_multimap<int,int>::iterator mit = fTxBins[ista].begin();
1063 } // for (int istanext = ista + 1;
1064
1065 Int_t ncand = fCandVec2[ista].size();
1066 if (fVerbose >= 1) {
1067 cout << " Doublet stat: " << ista << " " << ncand << endl;
1068 for (int i2 = 0; i2 < ncand; ++i2)
1069 PrintHits(fCandVec2[ista][i2]);
1070 }
1071 } // for (Int_t ista = 0;
1072}
1073
1074// -------------------------------------------------------------------------
1075
1077{
1078 // Find bin number
1079
1080 return (tx + fTanXmax[ista]) / binw;
1081}
1082
1083// -------------------------------------------------------------------------
1084
1086{
1087 // Get Tx bin center
1088
1089 return -fTanXmax[ista] + binw * (ibin % 1000 + 0.5);
1090}
1091
1092// -------------------------------------------------------------------------
1093
1094void BmnStsVectorFinderV9::DTxWindow(int ista2, Float_t tx, int idu, Float_t curvCut, Float_t* dtx)
1095{
1096 // Compute dTx window
1097
1098 // void DTxWindow(Double_t curv)
1099 // Float_t params[2][4] = { {-0.00995846, -81.1826, -181.066, -94.9851},
1100 // {0.0032616, 79.4583, 163.907, -415.319} };
1101 // Float_t tMinMax[2] = {-0.21, 0.1};
1102 TF1 ff("ff", "pol3", -1, 1);
1103 TVector3 xyz[3];
1104
1105 int bintx = FindBin(ista2 / 100, fTxStep, tx) + 1000 * idu;
1106 // if (fStatData[ista2].find(bintx) == fStatData[ista2].end()) {cout << ista2 << " " << tx << " " << bintx << " " <<
1107 // fStatData[ista2].size() << " " << endl; exit(0);}
1108 vector<Float_t>& params = fStatData[ista2][bintx];
1109 Float_t tMinMax[2] = {params[4], params[9]};
1110
1111 for (int ilr = 0; ilr < 2; ++ilr) {
1112 int ip = ilr * 5;
1113 ff.SetParameters(params[ip], params[ip + 1], params[ip + 2], params[ip + 3]);
1114 Float_t cmax = ff.Eval(tMinMax[ilr]);
1115 // if (cmax <= curv) { cout << tMinMax[ilr] << endl; continue; }
1116 if (cmax <= curvCut) {
1117 dtx[ilr] = tMinMax[ilr];
1118 continue;
1119 }
1120 xyz[1][0] = tMinMax[ilr] * curvCut / cmax;
1121 xyz[1][1] = ff.Eval(xyz[1][0]);
1122 Float_t dx = tMinMax[ilr] / 10;
1123 for (int j = -1; j < 2; j += 2) {
1124 xyz[j + 1][0] = xyz[1][0] + j * dx;
1125 xyz[j + 1][1] = ff.Eval(xyz[j + 1][0]);
1126 }
1127 // xyz[0].Print();
1128 // xyz[1].Print();
1129 // xyz[2].Print();
1130 // Local parabolic approximation
1131 TVector3 cba = Parabola(xyz[0], xyz[1], xyz[2]);
1132 // cba.Print();
1133 Float_t d = cba[1] * cba[1] - 4 * cba[2] * (cba[0] - curvCut);
1134 // cout << d << endl;
1135 Float_t x1 = (-cba[1] + TMath::Sqrt(d)) / 2 / cba[2];
1136 Float_t x2 = (-cba[1] - TMath::Sqrt(d)) / 2 / cba[2];
1137 Float_t dthx = x1;
1138 if (x1 * x2 < 0) {
1139 if ((ilr == 0 && dthx > 0) || (ilr == 1 && dthx < 0))
1140 dthx = x2;
1141 } else
1142 dthx = TMath::Sign(TMath::Min(TMath::Abs(x1), TMath::Abs(x2)), x1);
1143 dtx[ilr] = dthx;
1144 if (ilr == 0)
1145 dtx[ilr] = TMath::Min(dtx[ilr], -0.01f);
1146 else
1147 dtx[ilr] = TMath::Max(dtx[ilr], 0.01f);
1148 // cout << x1 << " " << x2 << " " << dthx << endl;
1149 }
1150}
1151
1152// -------------------------------------------------------------------------
1153
1155{
1156 // AZ-310722 - Check Varx
1157
1158 varx = (dx / dz - tx) / distxz;
1159 // AZ-250822 if (TMath::Abs(varx) > fVarx[fPass]) return kFALSE;
1160 return kTRUE;
1161}
1162
1163// -------------------------------------------------------------------------
1164
1166{
1167 // Build triplets
1168
1169 // Int_t idmaxP = 0;
1170
1171 // AZ-130722 pair<multimap<Int_t,int>::iterator,multimap<Int_t,int>::iterator> ret;
1172 // AZ-130722 multimap<Int_t,int>::iterator mit, mit1;
1173 pair<unordered_multimap<Int_t, int>::iterator, unordered_multimap<Int_t, int>::iterator> ret; // AZ-130722
1174 unordered_multimap<Int_t, int>::iterator mit, mit1; // AZ-130722
1175 // AZ-140725 Double_t pxzCut = (fUseTMVA) ? 0.3 : 0.2; //AZ-041022 - pxz difference cut
1176 // pxzCut = 0.3; // AZ-220625
1177 // if (fBy < 0.2) pxzCut = 1.0; //AZ-261222 - zero magnetic field
1178 const Float_t pxzScale4[19] = {5.0, 3.8, 3.0, 2.0, 1.2, 1.0, 0.9, 1.1, 1.0}; // AZ-260623 - Run 8
1179 const Float_t pxzScale5[19] = {7.0, 7.0, 3.8, 3.0, 2.0, 1.2, 1.0, 0.9, 1.1, 1.0}; // AZ-220625 - Run 9
1180 // const Float_t dtymax9[19] = {0.014, 0.019, 0.020, 0.016, 0.009, 0.007, 0.007, 0.006, 0.006, 0.006, 0.006, 0.006};
1181 // // AZ-260625 - sigma
1182 const Float_t dtymax9[19] = {0.070, 0.095, 0.100, 0.080, 0.045, 0.035,
1183 0.035, 0.030, 0.030, 0.030, 0.03, 0.03}; // AZ-260625 - 5*sigma
1184 // const Float_t beamWidth9[19] = {0.19, 0.12, 0.10, 0.10, 0.11, 0.12, 0.14, 0.17, 0.19, 0.22}; // AZ-260624 - sigma
1185 // const Float_t beamWidth9[19] = {0.95, 0.60, 0.50, 0.50, 0.55, 0.60, 0.70, 0.85, 0.95, 1.10, 1.1, 1.1}; //
1186 // AZ-260624 - 5*sigma const Float_t beamWidth9[19] = {0.19, 0.12, 0.10, 0.09, 0.10, 0.10, 0.11, 0.13, 0.15, 0.19};
1187 // // AZ-260624 - sigma, fit with "w"
1188 const Float_t beamWidth9[19] = {0.95, 0.60, 0.50, 0.45, 0.50, 0.50,
1189 0.55, 0.65, 0.75, 0.95, 1.0, 1.0}; // AZ-260624 - 5*sigma
1190
1191 // const Float_t *pxzScale = (fNSi == 4) ? pxzScale4 : pxzScale5; // AZ-230625
1192 const Float_t *pxzScale = pxzScale5, *dtymax = dtymax9, *beamWidth = beamWidth9; // AZ-270625
1193 if (fNSi == 4) { // AZ-270625
1194 pxzScale = pxzScale4;
1195 dtymax = &dtymax9[1];
1196 beamWidth = &beamWidth9[1];
1197 }
1198
1199 for (Int_t ista = 0; ista < fNsta - 2; ++ista) {
1200 discarded = 0;
1201 Int_t nTra = fCandVec2[ista].size();
1202 // AZ-280323 Int_t istanext = ista + 1;
1203 // AZ-280323 if (nTra == 0 || fCandVec2[istanext].size() == 0) continue;
1204 if (nTra == 0)
1205 continue;
1206
1207 for (mit = fMap2[ista].begin(); mit != fMap2[ista].end(); ++mit) {
1208 candvec& aaa = fCandVec2[ista][mit->second]; // first doublet
1209 Int_t istanext = ista + 1 + aaa.nskips; // AZ-280323
1210 if (fCandVec2[istanext].size() == 0)
1211 continue; // AZ-280323
1212 // AZ-300922 Double_t tany = fmapHits[aaa.stahit.begin()->second].ty; //AZ-2908822
1213 // AZ-300922 tany *= (fTanXmax[ista] / fTanXmax[istanext+1]); //AZ-290822
1214 // Double_t tany = aaa.ty; //AZ-300922
1215 Double_t tanx = aaa.tx; // AZ-010123
1216
1217 ret = fMap2[istanext].equal_range(aaa.stahit.rbegin()->second);
1218 multimap<Double_t, candvec> mapDoublets; // AZ-110722 second doublets, attached to one first doublet
1219 int nbr = 0, newtr = 0, newtr3 = 0; //, mult2 = 0;
1220 // Double_t c2max = 999.0;
1221
1222 // AZ-090525 - for TMVA
1223 /*
1224 if (fUseTMVA && fBy > 0.2) {
1225 for (mit1 = ret.first; mit1 != ret.second; ++mit1) {
1226 candvec &aaa2 = fCandVec2[istanext][mit1->second]; // second doublet
1227 if (TMath::Abs(tany - aaa2.ty) > fdTanY3[fPass]) continue;
1228 ++mult2; // doublet multiplicity in triplets
1229 }
1230 }
1231 */
1232
1233 for (mit1 = ret.first; mit1 != ret.second; ++mit1) {
1234 candvec aaa1;
1235 // AZ-150722 Int_t newtr = (mit1 == ret.first) ? 1 : 0;
1236
1237 // Int_t nhits = 3;
1238 aaa1 = aaa;
1239 candvec& aaa2 = fCandVec2[istanext][mit1->second]; // second doublet
1240 if (fExact) {
1241 // Exact track ID match
1242 if (aaa.idmaxP != aaa2.idmaxP)
1243 continue;
1244 }
1245 // AZ-310722 - Check doublet matching criteria
1246 // if (TMath::Abs(aaa.varx - aaa2.varx) > 0.002) continue; //AZ-050822
1247 // AZ-070822 if (TMath::Abs(aaa.ty - aaa2.ty) > 0.01) continue; //AZ-040822
1248 // if (TMath::Abs(aaa.ty - aaa2.ty) > fdTanY3[fPass]) continue; //AZ-250822
1249 // cout << TMath::Abs(tany - aaa2.ty) << " " << fdTanY3[fPass] << " "
1250 // << TMath::Abs(tanx - aaa2.tx) << " " << fdTanXB0[fPass] << endl;
1251 // AZ-230623 if (TMath::Abs(tany - aaa2.ty) > fdTanY3[fPass]) continue; //AZ-290822
1252 if (fBy < 0.2 && TMath::Abs(tanx - aaa2.tx) > fdTanXB0[fPass])
1253 continue; // AZ-010123 - for zero mag. field
1254 /* AZ-090525
1255 if (fOut / 3 > 0) { // AZ-260922 for writing out
1256 string code = to_string(aaa.stahit.begin()->second) + "-" +
1257 to_string(aaa.stahit.rbegin()->second)
1258 + "-" + to_string(aaa2.stahit.rbegin()->second);
1259 if (fMap3Out.find(code) == fMap3Out.end())
1260 fMap3Out[code] = fPass;
1261 }
1262 */
1263
1264 /* AZ-260625 - reldiff is not a good criterion for first stations and high momenta for a wide beam
1265 Float_t reldiff = TMath::Abs(aaa.momxz-aaa2.momxz) / (TMath::Abs(aaa.momxz)+TMath::Abs(aaa2.momxz));
1266 if (fBy > 0.2 && reldiff > 0.9) continue; //AZ-260623
1267 if (fBy > 0.2 && reldiff / pxzScale[ista] > pxzCut) continue; //AZ-260623
1268 //if (fBy < 0.2 && TMath::Abs(aaa.momxz-aaa2.momxz) / TMath::Sqrt(fZmean[ista]) > pxzCut) continue;
1269 //AZ-311222
1270 */
1271 // AZ-280625 if (TMath::Abs (aaa.ty - aaa2.ty) > dtymax[ista]) continue; // AZ-260625
1272 Double_t dtym = dtymax[ista]; // AZ-280625
1273 int dsta = aaa2.stahit.rbegin()->first - ista; // AZ-280625
1274 if (dsta > 2)
1275 dtym *= (2.0 / dsta); // AZ-280625
1276 if (TMath::Abs(aaa.ty - aaa2.ty) > dtym)
1277 continue; // AZ-260625
1278
1279 // AZ-260625 Use parabolic approximation to find X-position of triplet at Ztarg
1280 map<int, int>::iterator mitt = aaa.stahit.begin();
1281 TVector3 points[3];
1282 points[0] = fmapHits[mitt->second].xyz;
1283 ++mitt;
1284 points[1] = fmapHits[mitt->second].xyz;
1285 points[2] = fmapHits[aaa2.stahit.rbegin()->second].xyz;
1286 for (int j3 = 0; j3 < 3; ++j3)
1287 points[j3] -= fXyzv;
1288 TVector3 cba = Parabola(points[0], points[1], points[2], 2);
1289 Double_t dist = TMath::Abs(cba[0]) / TMath::Sqrt(points[0].Z());
1290 // cout << " ddd " << ista << " " << points[0].Z() << " " << points[1].Z() << " " << points[2].Z() << "
1291 // " << dist << endl;
1292 Double_t beamW = beamWidth[ista] * 2; // AZ-290625
1293 if (dsta > 2)
1294 beamW *= (2.0 / dsta); // AZ-290625
1295 if (dist > beamW)
1296 continue;
1297
1298 aaa1.stahit[aaa2.stahit.rbegin()->first] = aaa2.stahit.rbegin()->second; // third hit of the triplet
1299
1300 Double_t tmvaOut = 9.9; // AZ-300922
1301 /* AZ-200525
1302 if (fUseTMVA)
1303 tmvaOut = TMVAOutput3(aaa1, aaa2); // AZ-300922
1304 // if (fUseTMVA) outf << tmvaOut << " " << fPass << endl; //AZ-300922
1305 if (tmvaOut < 0.02)
1306 continue; // AZ-300922 - use TMVA MLPBNN method
1307 */
1308
1309 map<Int_t, Int_t>& hitMap = aaa1.stahit;
1310
1311 CbmStsHit* hit = nullptr;
1312 CbmStsTrack track;
1313 TArrayI& hits = *track.GetStsHits();
1314 hits.Set(3);
1315 Int_t indx = 0; //, iok = 1;
1316
1317 /// hitMap ---- aaa1.stahit
1318 for (map<Int_t, Int_t>::iterator mit2 = hitMap.begin(); mit2 != hitMap.end(); ++mit2) {
1319 hits[indx++] = mit2->second;
1320 hit = (CbmStsHit*)fHitArray->UncheckedAt(mit2->second);
1321 // cout << " hit: " << mit2->first << " " << mit2->second << endl;
1322 // hit->SetDx(0.08/TMath::Sqrt(12.0));
1323 hit->SetDx(0.08 / TMath::Sqrt(12.0) * 1.2); // AZ-210125 - as in vers.1
1324 /// hit->SetDx(0.05); //AZ-110123 - early estimate
1325 // hit->SetDx(0.015);
1326 hit->SetDy(0.1234); // AZ-210125 - as in vers.1
1327 // AZ-030123 if (hit->GetStationNr() <= 3) hit->SetDx(0.02/TMath::Sqrt(12.0));
1328 if (hit->GetStationNr() <= fNSi)
1329 hit->SetDx(0.02 / TMath::Sqrt(12.0)); // AZ-210125 - as in vers.1
1330 // if (hit->GetStationNr() <= fNSi) hit->SetDx(0.01); //AZ-040123 - early estimate
1331 /// if (hit->GetStationNr() <= fNSi) hit->SetDx(0.02); //AZ-040123 - early estimate
1332 // if (hit->GetStationNr() % 2 != 0) hit->SetCovXY(1.968e-3); // this is for 2-D hits
1333 // else hit->SetCovXY(-1.968e-3);
1334 // hit->SetDy(0.03); // for test
1335 if (indx == 3)
1336 break;
1337 }
1338
1339 // fitter.DoFit(&track);
1340 // float chi2 = track.GetChi2();
1341 // AZ-310722 Double_t ty = 0.0;
1342 Double_t ty = aaa.ty; // AZ-310722
1343 // AZ-280722 float chi2 = LinearFit (&track, newtr, ty) / hit->GetDy() / hit->GetDy();
1344 float chi2 = LinearFit(aaa, aaa2, &track, newtr, ty) / hit->GetDy() / hit->GetDy(); // AZ-280722
1345 ++newtr; // AZ-150722
1346 // float chi2 = LinearFit (&track, newtr, ty) / 0.09 / 0.09;
1347 // cout << "3hit track Chi2 " << track.GetChi2() << " " << nhits << endl;
1348 // if Chi2 > 10.0 exclude track cand
1349 // TODO DZ add index so I know how many candidates were discarded
1350 // if (aaa1.idmaxP == 78 || aaa1.idmaxP == 222 || aaa1.idmaxP == 127)
1351 // cout << " Triplet: " << aaa1.idmaxP << " " << aaa1.stahit.begin()->first << " " << chi2 << endl; //
1352 // debug output
1353
1354 if (chi2 > 10.0) {
1355 // if (chi2 > 20.0) { //AZ-010123
1356 discarded++;
1357 continue;
1358 }
1359 // Triplet curvature
1360 aaa1.momxz = Curv3(aaa, aaa2, aaa1, newtr3);
1361 newtr3 = 1;
1362 // AZ-150722 if (TMath::Abs(aaa1.momxz) < 0.2) {
1363 // Double_t ptcut = (fPass < 2) ? 0.3 : 0.2; //AZ-150722
1364 // if (TMath::Abs(aaa1.momxz) < ptcut) { //AZ-150722
1365 if (TMath::Abs(aaa1.momxz) > fPTcut[fPass]) { // AZ-170722 - curvature
1366 // if (TMath::Abs(aaa1.momxz) > fPTcut[fPass] || TMath::Abs(aaa1.momxz) > fCurvSta[ista]) {
1367 // //AZ-310722 - curvature
1368 discarded++;
1369 continue;
1370 }
1371
1372 if (fOut / 3 > 0) { // AZ-090525 for writing out
1373 string code = to_string(aaa.stahit.begin()->second) + "-" + to_string(aaa.stahit.rbegin()->second)
1374 + "-" + to_string(aaa2.stahit.rbegin()->second);
1375 if (fMap3Out.find(code) == fMap3Out.end())
1376 fMap3Out[code] = fPass;
1377 }
1378
1379 aaa1.ty = ty;
1380 /*AZ-110722
1381 fCandVec3[ista].push_back(aaa1);
1382 fMap3[ista].insert(pair<Int_t,int>(mit->first,fCandVec3[ista].size()-1));
1383 string code = "-";
1384 for (map<Int_t,Int_t>::iterator mitr = hitMap.begin(); mitr != hitMap.end(); ++mitr)
1385 code += (to_string(mitr->second) + "-");
1386 fMapCode3[ista][code] = fCandVec3[ista].size() - 1;
1387 */
1388 /*AZ-200525
1389 if (fUseTMVA) {
1390 // AZ-300922 Keep fNbranches with the highest NN response
1391 if (-tmvaOut > c2max && nbr >= fNbranches)
1392 continue;
1393 } else if (chi2 > c2max && nbr >= fNbranches)
1394 continue;
1395 */
1396 aaa1.chi2 = chi2; // AZ-140722
1397 Double_t qual = (fUseTMVA) ? -tmvaOut : chi2; // AZ-300922
1398 aaa1.nskips = aaa.nskips + aaa2.nskips; // AZ-280323
1399 // AZ-300922 mapDoublets.insert(pair<Double_t,candvec>(chi2,aaa1)); //AZ-110722
1400 mapDoublets.insert(pair<Double_t, candvec>(qual, aaa1)); // AZ-300922
1401 // mapDoublets.insert(pair<Double_t,candvec>(TMath::Abs(aaa1.momxz),aaa1)); //AZ-280722
1402 nbr = mapDoublets.size();
1403 // AZ-310722 if (nbr > fNbranches) mapDoublets.erase(mapDoublets.rbegin()->first);
1404 /*AZ-200525
1405 if (nbr > fNbranches) {
1406 multimap<Double_t, candvec>::iterator mit0 = mapDoublets.end();
1407 --mit0;
1408 mapDoublets.erase(mit0);
1409 }
1410 c2max = mapDoublets.rbegin()->first;
1411 */
1412 } // for (mit1 = ret.first;
1413
1414 // AZ-200525
1415 if (fUseTMVA && nbr > fNbranches) {
1416 multimap<Double_t, candvec> mapTmp;
1417 for (multimap<Double_t, candvec>::iterator it = mapDoublets.begin(); it != mapDoublets.end(); ++it) {
1418 auto aaa1 = it->second;
1419 // Double_t tmvaOut = TMVAOutput3 (aaa1, aaa2, mult2); // AZ-090525
1420 // AZ-280525 Double_t tmvaOut = TMVAOutput3 (aaa1, aaa, mult2); // AZ-090525
1421 Double_t tmvaOut = TMVAOutput3(aaa1, aaa, nbr); // AZ-280525
1422 if (tmvaOut < -0.2) {
1423 ++discarded;
1424 continue;
1425 } // AZ-090525 - use TMVA BDTD method
1426 mapTmp.insert(pair<Double_t, candvec>(-tmvaOut, aaa1));
1427 }
1428 mapDoublets.clear();
1429 mapDoublets = mapTmp;
1430 }
1431 //
1432
1433 // Take only first fNbranches with lowest chi2
1434 int nok = 0;
1435 for (multimap<Double_t, candvec>::iterator it = mapDoublets.begin(); it != mapDoublets.end(); ++it) {
1436 if (nok >= fNbranches)
1437 break;
1438 ++nok;
1439 fCandVec3[ista].push_back(it->second);
1440 fMap3[ista].insert(pair<Int_t, int>(mit->first, fCandVec3[ista].size() - 1));
1441 map<Int_t, Int_t>& hitMap = it->second.stahit;
1442 string code = "-";
1443 for (map<Int_t, Int_t>::iterator mitr = hitMap.begin(); mitr != hitMap.end(); ++mitr)
1444 code += (to_string(mitr->second) + "-");
1445 fMapCode3[ista][code] = fCandVec3[ista].size() - 1;
1446 // cout << ista << " " << code << endl;
1447 }
1448 } // for (mit = fCandMap2[ista].begin();
1449
1450 Int_t ncand = fCandVec3[ista].size();
1451 if (fVerbose > 0)
1452 cout << " Triplet stat: " << ista << " " << ncand << " " << discarded << " " << fPass << endl;
1453 } // for (Int_t ista = fNsta-1;
1454}
1455
1456// -------------------------------------------------------------------------
1457
1459{
1460 // Build tracks starting from triplets
1461
1462 int istaEnd = fNsta - fNhitsMin[fPass] + 1;
1463 istaEnd = TMath::Min(istaEnd, fNsta - 3); // do not allow simple triplets on last 3 stations
1464 // std::multimap<Int_t,int> &candMap = fMap3[ista];
1465 // vector<candvec> &candVec = fCandVec3[ista];
1466 // std::multimap<Int_t,int> *candMap = &fMap2[ista];
1467 // vector<candvec> *candVec = &fCandVec2[ista];
1468
1469 for (Int_t ista = 0; ista < istaEnd; ++ista) {
1470 // std::multimap<Int_t,int> *candMap = &fMap2[ista];
1471 // vector<candvec> *candVec = &fCandVec2[ista];
1472 // AZ-130722 std::multimap<Int_t,int> *candMap = &fMap3[ista];
1473 std::unordered_multimap<Int_t, int>* candMap = &fMap3[ista]; // AZ-130722
1474 vector<candvec>* candVec = &fCandVec3[ista];
1475 Int_t nTra = candMap->size();
1476 // cout << " BuildTracks: " << ista << " " << nTra << " " << istaEnd << " " << fNsta << endl;
1477 if (nTra == 0)
1478 continue;
1479 // Int_t istaup = ista - 2;
1480
1481 // AZ-130722 for (multimap<Int_t,int>::iterator mit = candMap->begin(); mit != candMap->end(); ++mit) {
1482 for (unordered_multimap<Int_t, int>::iterator mit = candMap->begin(); mit != candMap->end(); ++mit) {
1483 candvec& cand = (*candVec)[mit->second];
1484 if (fPass == 0 && cand.nskips > 0)
1485 continue; //!!! AZ-280323 - no jumps over stations at 1'st pass !!!
1486 map<int, int>::iterator it = cand.stahit.begin();
1487 int ista0 = it->first;
1488 ++it;
1489 int ista1 = it->first;
1490 if (ista1 - ista0 > 1)
1491 continue; // AZ-250423 - isolated first hit is not allowed
1492 ExtendTrack(cand);
1493 }
1494 }
1495}
1496
1497// -------------------------------------------------------------------------
1498
1500{
1501 // Extend the track by triplets or doublets
1502
1503 const Double_t c2ndfMax = 30.0; // cut on chi2/NDF
1504 Double_t pxzCut = 0.3; // AZ-261222 - pxz difference cut
1505 // if (fBy < 0.2) pxzCut = 1.0; //AZ-261222 - zero magnetic field
1506 // const Float_t pxzCuts9pos[19] = {0.043, 0.046, 0.049, 0.060, 0.053, 0.047, 0.050, 0.055, 0.064}; // AZ-290625 -
1507 // sigma
1508 const Float_t pxzCuts9pos[19] = {0.215, 0.230, 0.245, 0.300, 0.265,
1509 0.235, 0.250, 0.275, 0.320}; // AZ-270625 - 5*sigma
1510 // const Float_t pxzCuts9neg[19] = {0.047, 0.043, 0.037, 0.034, 0.032, 0.027, 0.025, 0.024, 0.029}; // AZ-290625 -
1511 // sigma
1512 const Float_t pxzCuts9neg[19] = {0.235, 0.215, 0.185, 0.170, 0.160,
1513 0.135, 0.125, 0.120, 0.145}; // AZ-290625 - 5*sigma
1514 const Float_t* pxzCutsPos = (fNSi == 5) ? pxzCuts9pos : &pxzCuts9pos[1]; // AZ-290625
1515 const Float_t* pxzCutsNeg = (fNSi == 5) ? pxzCuts9neg : &pxzCuts9neg[1]; // AZ-290625
1516
1517 Int_t nTra = 0, ista = cand.stahit.rbegin()->first;
1518 // cout << ista << " " << cand.stahit.size() << endl;
1519 /*
1520 //!!! Check - step back
1521 if (ista == fNsta-2) {
1522 cand.stahit.erase(cand.stahit.rbegin()->first);
1523 ista = cand.stahit.rbegin()->first;
1524 }
1525 */
1526 // std::multimap<Int_t,int> &candMap = (ista == fNsta-2) ? fMap2[ista] : fMap3[ista]; // doublets or triplets
1527 // vector<candvec> &candVec = (ista == fNsta-2) ? fCandVec2[ista] : fCandVec3[ista]; // doublets or triplets
1528 // std::multimap<Int_t,int> *pCandMap = (ista == fNsta-2) ? &fMap2[ista] : &fMap2[ista]; // doublets or triplets
1529 // vector<candvec> *pCandVec = (ista == fNsta-2) ? &fCandVec2[ista] : &fCandVec2[ista]; // doublets or triplets
1530 // AZ-130722 std::multimap<Int_t,int> *pCandMap = (ista == fNsta-2) ? &fMap2[ista] : &fMap2[ista]; // doublets or
1531 // triplets
1532 std::unordered_multimap<Int_t, int>* pCandMap =
1533 (ista == fNsta - 2) ? &fMap2[ista] : &fMap2[ista]; // AZ-130722 doublets or triplets
1534 vector<candvec>* pCandVec = (ista == fNsta - 2) ? &fCandVec2[ista] : &fCandVec2[ista]; // doublets or triplets
1535 // AZ-130722 multimap<Int_t,int> &candMap = *pCandMap;
1536 unordered_multimap<Int_t, int>& candMap = *pCandMap; // AZ-130722
1537 vector<candvec>& candVec = *pCandVec;
1538
1539 if (ista < fNsta - 1) {
1540 /*
1541 if (ista == fNsta-2) {
1542 // Doublets
1543 candMap = fMap2[ista];
1544 candVec = fCandVec2[ista];
1545 }
1546 */
1547 nTra = candMap.count(cand.stahit.rbegin()->second);
1548 }
1549
1550 // cout << " ExtendTrack " << ista << " " << nTra << endl;
1551 if (nTra == 0) {
1552 // No extension found
1553 if (int(cand.stahit.size()) < fNhitsMin[fPass])
1554 return; // too short track
1555 // cout << " ExtendTrack - store " << cand.stahit.size() << " " << cand.idmaxP << endl;
1556 // FitTrack(cand);
1557 string code("-");
1558 for (map<int, int>::iterator it = cand.stahit.begin(); it != cand.stahit.end(); ++it)
1559 code += (to_string(it->second) + "-");
1560 // cout << cand.stahit.rbegin()->first << " " << ista << endl;
1561 if (fCandCodes[cand.stahit.size()].find(code) == fCandCodes[cand.stahit.size()].end()) {
1562 fCandCodes[cand.stahit.size()].insert(code);
1563 // cout << " 1 " << endl;
1564 // AZ-170122 if (cand.stahit.size() >= 4 && FitTrack(cand) > c2ndfMax) return;
1565 // AZ-110123 if (cand.stahit.size() >= 4 && cand.stahit.rbegin()->first != ista && FitTrack(cand) >
1566 // c2ndfMax) return;
1567 if (int(cand.stahit.size()) >= fNhitsMin[fPass] && cand.stahit.rbegin()->first != ista
1568 && FitTrack(cand) > c2ndfMax)
1569 return; // AZ-110123
1570 // cout << " ExtendTrack - store " << cand.stahit.size() << " " << cand.idmaxP << endl;
1571 fCandVec[cand.stahit.begin()->first].push_back(cand);
1572 }
1573 return;
1574 }
1575
1576 // AZ-130722 multimap<Int_t,int>::iterator mit;
1577 // AZ-130722 pair<multimap<Int_t,int>::iterator,multimap<Int_t,int>::iterator> ret;
1578 unordered_multimap<Int_t, int>::iterator mit; // AZ-130722
1579 pair<unordered_multimap<Int_t, int>::iterator, unordered_multimap<Int_t, int>::iterator> ret; // AZ-130722
1580 ret = candMap.equal_range(cand.stahit.rbegin()->second);
1581 string code = "-";
1582 int istaMid = 0;
1583
1584 // Use Kalman track constraints around extrapolated position
1585 /*
1586 set<int> kalmWind;
1587 if (nTra > 5)
1588 if (cand.stahit.size() >= 4) kalmWind = KalmanWindow(cand, candVec[ret.first->second].stahit.begin()->second);
1589 */
1590
1591 for (mit = ret.first; mit != ret.second; ++mit) {
1592 // candvec &aaa = candVec[mit->second];
1593 candvec aaa = candVec[mit->second];
1594 if (fExact && aaa.idmaxP != cand.idmaxP)
1595 continue;
1596 if (fPass == 0 && aaa.nskips > 0)
1597 continue; //!!!AZ-289323 - no jumps over station at 1'st pass
1598
1599 // if (nTra > 5 && cand.stahit.size() >= 4 &&
1600 // kalmWind.find(aaa.stahit.begin()->second) == kalmWind.end()) continue; // outside Kalman window
1601
1602 // Check if there is a triplet started from the last but one point of the current one (cand)
1603 map<Int_t, Int_t>::iterator mitr = aaa.stahit.begin();
1604 ++mitr;
1605 if (code.size() == 1) {
1606 map<Int_t, Int_t>::reverse_iterator mit1 = cand.stahit.rbegin();
1607 ++mit1;
1608 istaMid = mit1->first;
1609 code += (to_string(mit1->second) + "-");
1610 --mit1;
1611 code += (to_string(mit1->second) + "-");
1612 code += (to_string(mitr->second) + "-");
1613 } else {
1614 // Replace last index
1615 int pos = code.rfind("-", code.size() - 2);
1616 code.erase(code.begin() + pos + 1, code.end());
1617 code += (to_string(mitr->second) + "-");
1618 }
1619 // cout << " Check code: " << code << " " << istaMid << endl;
1620 // Check extension possibility
1621 int ok = 1;
1622 if (fMapCode3[istaMid].find(code) == fMapCode3[istaMid].end())
1623 ok = 0; // no triplet found
1624 //!!! Check triplet slopes and curvatures
1625 //*
1626 candvec* bbb = nullptr;
1627 if (ok) {
1628 bbb = &fCandVec3[istaMid][fMapCode3[istaMid][code]];
1629 // Double_t dty = TMath::Abs (cand.ty - bbb.ty);
1630 // if (dty * 2 / (TMath::Abs(cand.ty) + TMath::Abs(bbb.ty)) > 0.1) continue; // different slopes
1631 // if (dty > 0.005) continue; // different slopes
1632 // Curvatures
1633 // cout << cand.momxz << " " << bbb.momxz << endl;
1634 if ((fPass == 0 && bbb->nskips > 0) || (cand.nskips + bbb->nskips > 2))
1635 ok = 0; //!!!AZ-280323 - jumps over stations
1636 if (ok && cand.stahit.size() > 2) {
1637 Double_t dp = TMath::Abs(cand.momxz - bbb->momxz);
1638 // if (dp * 2 / (TMath::Abs (cand.momxz) + TMath::Abs(bbb->momxz)) > 0.3) {
1639 // AZ-060822 if (dp * 2 / (TMath::Abs (cand.momxz) + TMath::Abs(bbb->momxz)) > 0.2) {
1640 // AZ-261222 if (dp / (TMath::Abs (cand.momxz) + TMath::Abs(bbb->momxz)) > 0.3) { //AZ-060822
1641 // AZ-270625 if (TMath::Abs(fBy) > 0.2 && dp / (TMath::Abs (cand.momxz) + TMath::Abs(bbb->momxz)) >
1642 // pxzCut) { //AZ-311222
1643 int istabeg = cand.stahit.begin()->first; // AZ-290625
1644 pxzCut = (cand.momxz > 0) ? pxzCutsPos[istabeg] : pxzCutsNeg[istabeg]; // AZ-290625
1645 int dsta = bbb->stahit.rbegin()->first - istabeg; // AZ-290625
1646 if (dsta > 3)
1647 pxzCut *= (3.0 / dsta); // AZ-290625
1648 if (TMath::Abs(fBy) > 0.2
1649 && dp / (TMath::Abs(cand.momxz) + TMath::Abs(bbb->momxz)) / TMath::Sqrt(TMath::Abs(1 / cand.momxz))
1650 > pxzCut)
1651 { // AZ-270625
1652 // Different curvatures
1653 ok = 0;
1654 }
1655 }
1656 }
1657 if (ok) {
1658 if ((fPass == 0 && aaa.nskips > 0) || (cand.nskips + aaa.nskips > 2))
1659 ok = 0; //!!!AZ-280323 - jumps over stations
1660 if (aaa.stahit.size() == 3) {
1661 // Extension by a triplet
1662 if (ok) {
1663 Double_t dp = TMath::Abs(cand.momxz - aaa.momxz);
1664 // if (dp * 2 / (TMath::Abs (cand.momxz) + TMath::Abs(aaa.momxz)) > 0.3) {
1665 // AZ-070822 if (dp * 2 / (TMath::Abs (cand.momxz) + TMath::Abs(aaa.momxz)) > 0.2) {
1666 // AZ-261222 if (dp / (TMath::Abs (cand.momxz) + TMath::Abs(aaa.momxz)) > 0.3) { //AZ-070822
1667 // AZ-270625 if (TMath::Abs(fBy) > 0.2 && dp / (TMath::Abs (cand.momxz) + TMath::Abs(aaa.momxz)) >
1668 // pxzCut) { //AZ-020123
1669 int istabeg = cand.stahit.begin()->first; // AZ-290625
1670 pxzCut = (cand.momxz > 0) ? pxzCutsPos[istabeg] : pxzCutsNeg[istabeg]; // AZ-290625
1671 int dsta = aaa.stahit.rbegin()->first - istabeg; // AZ-290625
1672 if (dsta > 3)
1673 pxzCut *= (3.0 / dsta); // AZ-290625
1674 if (TMath::Abs(fBy) > 0.2
1675 && dp / (TMath::Abs(cand.momxz) + TMath::Abs(aaa.momxz))
1676 / TMath::Sqrt(TMath::Abs(1 / cand.momxz))
1677 > pxzCut)
1678 { // AZ-270625
1679 // different curvatures
1680 ok = 0;
1681 }
1682 }
1683 }
1684 }
1685 if (!ok) {
1686 // No extension found
1687 if (int(cand.stahit.size()) < fNhitsMin[fPass])
1688 continue; // too short track
1689 // cout << " ExtendTrack - store " << cand.stahit.size() << " " << cand.idmaxP << endl;
1690 string codeVec("-");
1691 for (map<int, int>::iterator it = cand.stahit.begin(); it != cand.stahit.end(); ++it)
1692 codeVec += (to_string(it->second) + "-");
1693 if (fCandCodes[cand.stahit.size()].find(codeVec) == fCandCodes[cand.stahit.size()].end()) {
1694 fCandCodes[cand.stahit.size()].insert(codeVec);
1695 if (cand.stahit.size() >= 4) {
1696 // cout << " 2 " << endl;
1697 if (cand.stahit.rbegin()->first == ista)
1698 continue; // AZ-171121
1699 Double_t chi2 = FitTrack(cand);
1700 // cout << " --- Chi2: " << chi2 << endl;
1701 if (chi2 > c2ndfMax)
1702 continue;
1703 }
1704 // cout << " ExtendTrack - store " << cand.stahit.size() << " " << cand.idmaxP << endl;
1705 fCandVec[cand.stahit.begin()->first].push_back(cand);
1706 }
1707 continue; // AZ-280323
1708 }
1709 //*/
1710 //!!! Extension found
1711 candvec candext = cand;
1712 if (cand.stahit.size() < 3)
1713 candext.momxz = bbb->momxz; // update momentum
1714 // candext.ty = bbb.ty;
1715 // Add triplet (or doublet)
1716 for (mitr = aaa.stahit.begin(); mitr != aaa.stahit.end(); ++mitr)
1717 candext.stahit[mitr->first] = mitr->second;
1718 candext.nskips += aaa.nskips; //!!!AZ-280323 - update number of jumps
1719 // cout << " ids: " << aaa.idmaxP << " " << cand.idmaxP << " " << candext.stahit.size() << " " << candext.nskips
1720 // << " " << fPass << endl; if (candext.nskips > 2) exit(0); AZ-120722 if (aaa.idmaxP != cand.idmaxP)
1721 // cand.idmaxP = -1;
1722 if (aaa.idmaxP != cand.idmaxP)
1723 candext.idmaxP = -1; // AZ-120722
1724 // Fit track to fight with combinatorics
1725 if (candext.stahit.size() >= 4) {
1726 Double_t chi2ndf = FitTrack(candext);
1727 // cout << " -3- " << chi2ndf << endl;
1728 if (chi2ndf > c2ndfMax)
1729 continue;
1730 /* This slows down
1731 if (chi2ndf > c2ndfMax) {
1732 string codext = MakeCode(candext);
1733 fCandCodes[candext.stahit.size()].insert(codext);
1734 continue;
1735 }
1736 */
1737 }
1738 ExtendTrack(candext);
1739 } // for (mit = ret.first;
1740}
1741
1742// -------------------------------------------------------------------------
1743
1745{
1746 // Fit track candidate
1747
1748 const Int_t gkChi2Cut = 5.0; // 10.0;
1749 // Int_t gkChi2Cut = 10.0; //AZ-010123
1750
1751 CbmStsTrack track;
1752 string hitcode;
1753
1754 MakeStsTrack(cand, hitcode, track);
1755 int nhits = track.GetNStsHits();
1756 if (fCandSet[nhits].find(hitcode) != fCandSet[nhits].end())
1757 return 0.0; // track has been saved already
1758
1759 // AZ-160122 fitter.DoFit(&track);
1760 if (nhits <= 4)
1761 fitter.DoFit(&track);
1762 else
1763 FilterHit(cand, track);
1764 /*
1765 else {
1766 // Debug
1767 CbmStsTrack track1(track);
1768 FilterHit (cand, track);
1769 fitter.DoFit(&track1);
1770 cout << " debug " << track.GetChi2() << " " << track1.GetChi2() << endl;
1771 }
1772 */
1773 // track.GetParamFirst()->Print();
1774 // cout << " aaaaaa " << track.GetChi2() << " " << track.GetNStsHits() << endl;
1775 int ndf = TMath::Max(track.GetNDF(), 1);
1776 Double_t chi2ndf = track.GetChi2() / ndf;
1777 cand.param = *(track.GetParamLast());
1778 cand.chi2 = track.GetChi2();
1779 if (chi2ndf < gkChi2Cut && nhits >= fNhitsMin[fPass]) {
1780 // Refit with material budget
1781 // fitter.DoFit(&track);
1782 fitter.Fit(&track); // AZ
1783 if (track.GetChi2() / ndf > gkChi2Cut) {
1784 // cout << " yyyyyy " << " " << track.GetChi2() / ndf << endl;
1785 // fitter.Fit(&track); //AZ - for debugging
1786 return chi2ndf;
1787 }
1788 // Save good tracks
1789 Double_t qual = nhits;
1790 qual += (100.0 - TMath::Min(TMath::Abs(track.GetChi2()), 100.0)) / 101.0;
1791 fTracks.insert(pair<Double_t, CbmStsTrack>(-qual, track));
1792 fCandSet[nhits].insert(hitcode);
1793 if (fVerbose > 0) {
1794 cout << " FitTrack: " << track.GetChi2() << " ";
1795 PrintHits(cand);
1796 }
1797 }
1798 // fCandSet[nhits].insert(hitcode); - don't use this !!!
1799 return chi2ndf;
1800}
1801
1802// -------------------------------------------------------------------------
1803//*
1805{
1806 // Filter last hit on track candidate
1807
1808 // const Int_t gkChi2Cut = 10.0;
1809 // AZ const Int_t gkChi2Cut = 20.0; //AZ-010123
1810 /*
1811 CbmStsTrack track;
1812 string hitcode;
1813
1814 MakeStsTrack(cand, hitcode, track);
1815 */
1816 Int_t nhits = cand.stahit.size();
1817 // CbmStsHit *hit = (CbmStsHit*) fHitArray->UncheckedAt(track.GetStsHitIndex(nhits-1));
1818 /*cout << " !!! parameters: " << cand.stahit.size() << " " << cand.param.GetX() << " " << cand.param.GetY()
1819 << " " << cand.param.GetZ() << " "
1820 << hit->GetZ() << " " << cand.chi2 << " " << cand.code << endl;*/
1821 // AZ-050222 fitter.Extrapolate(&track,hit->GetZ(),track.GetParamLast());
1822 // cout << hit->GetZ() << " " << track.GetParamLast()->GetZ() << endl;
1823
1824 CbmKFTrack kftr;
1825 kftr.SetStsTrack(track, kFALSE); // last parameter
1826 fitter.SetKFHits(kftr, &track);
1827 Bool_t downstream = kTRUE;
1828 // Double_t qp0 = 0.0;
1829 Double_t qp0 = track.GetParamLast()->GetQp();
1830 // Double_t *cov = kftr.GetCovMatrix();
1831 // for (Int_t j = 0; j < 15; ++j) cov[j] = 0.0;
1832 // cov[0] = cov[2] = cov[5] = cov[9] = cov[14] = 10000.0;
1833 // kftr.GetRefChi2() = 0.0;
1834 // Double_t chi20 = 0.0, dchi2 = 0.0;
1835 // Double_t chi20 = kftr.GetRefChi2();
1836
1837 /*CbmKF *KF =*/CbmKF::Instance();
1838 CbmKFHit* h = NULL;
1839 // Int_t istold = 0, imax = 0;
1840 Bool_t err = kFALSE;
1841
1842 // for (Int_t i = 0; i < nhits; i++) {
1843 h = kftr.GetHit(nhits - 1);
1844 err = err || h->Filter(kftr, downstream, qp0);
1845 // Double_t dchi2 = kftr.GetRefChi2() - chi20;
1846 // cout << err << " " << dchi2 << " " << kftr.GetRefChi2() << " " << cand.chi2+dchi2 << endl;
1847 kftr.GetTrackParam(*track.GetParamLast());
1848 track.SetChi2(kftr.GetRefChi2() + err * 1000);
1849 track.SetNDF(2 * nhits - 5);
1850 /*
1851 if (fCandSet[track.GetNStsHits()].find(hitcode) != fCandSet[track.GetNStsHits()].end()) return 0.0; // track has
1852 been saved already
1853
1854 fitter.DoFit(&track);
1855 //track.GetParamFirst()->Print();
1856 //cout << " aaaaaa " << track.GetChi2() << " " << track.GetNStsHits() << endl;
1857 int ndf = TMath::Max (track.GetNDF(), 1);
1858 Double_t chi2ndf = track.GetChi2() / ndf;
1859 if (chi2ndf < gkChi2Cut && track.GetNStsHits() >= fNhitsMin[fPass]) {
1860 // Save good tracks
1861 Double_t qual = track.GetNStsHits();
1862 qual += (100.0 - TMath::Min(TMath::Abs(track.GetChi2()),100.0)) / 101.0;
1863 fTracks.insert(pair<Double_t,CbmStsTrack>(-qual,track));
1864 fCandSet[track.GetNStsHits()].insert(hitcode);
1865 //cout << " FitTrack: " << hitcode << " " << track.GetChi2() << endl;
1866 }
1867 return chi2ndf;
1868 */
1869 return 0.0;
1870}
1871//*/
1872// -------------------------------------------------------------------------
1873
1874void BmnStsVectorFinderV9::MakeStsTrack(candvec& cand, string& hitcode, CbmStsTrack& track)
1875{
1876 // Fill STS track information
1877
1878 map<Int_t, Int_t>& hitMap = cand.stahit;
1879 CbmStsHit* hit = nullptr;
1880 TArrayI& hits = *track.GetStsHits();
1881 hits.Set(hitMap.size());
1882 Int_t indx = 0; //, iok = 1;
1883 hitcode = "-";
1884
1885 /// hitMap ---- cand.stahit
1886 for (map<Int_t, Int_t>::iterator mit2 = hitMap.begin(); mit2 != hitMap.end(); ++mit2) {
1887 hits[indx++] = mit2->second;
1888 hit = (CbmStsHit*)fHitArray->UncheckedAt(mit2->second);
1889 // cout << " hit: " << mit2->first << " " << mit2->second << endl;
1890 hit->SetDx(0.08 / TMath::Sqrt(12.0)); // AZ-210125 - as in vers.1
1891 /// hit->SetDx(0.05); //AZ-110123 - early estimate
1892 // hit->SetDx(0.015);
1893 hit->SetDy(0.1234); // AZ-210125 - as in vers.1
1894 // AZ-030123 if (hit->GetStationNr() <= 3) hit->SetDx(0.02/TMath::Sqrt(12.0));
1895 if (hit->GetStationNr() <= fNSi)
1896 hit->SetDx(0.02 / TMath::Sqrt(12.0)); // AZ-210125 - as in vers.1
1897 // if (hit->GetStationNr() % 2 != 0) hit->SetCovXY(1.968e-3); // this is for 2-D hits
1898 // else hit->SetCovXY(-1.968e-3);
1899 // hit->SetDy(0.03); // for test
1901 Double_t dx = stat->GetSector(0)->GetDx();
1902 // if (dx < 0.02) dx *= 2; // scale up for Si
1903 // AZ-120722 if (dx > 0.01) dx *= 1.2; // for GEMs
1904 if (dx > 0.02)
1905 dx *= 1.2; // AZ-120722 for GEMs
1906 hit->SetDx(dx / TMath::Sqrt(12.0)); // AZ-210125 - as in vers.1
1907 // if (dx < 0.02) hit->SetDx(0.01); //AZ-040123 - early estimate for Si
1908 /// if (dx < 0.02) hit->SetDx(0.02); //AZ-040123 - early estimate for Si
1909 hitcode += (to_string(mit2->second) + "-");
1910 }
1911 track.SetParamFirst(cand.param);
1912 track.SetParamLast(cand.param);
1913 track.SetChi2(cand.chi2);
1914 cand.code = hitcode;
1915}
1916
1917// -------------------------------------------------------------------------
1918
1920{
1921 // Extend tracks by going upstream
1922
1923 // const Double_t zsta[19] = {1.132, 32.750, 64.150, 96.750, 129.300, 160.800, 192.100}; // average hit Z-position -
1924 // Run 6 !!! const Double_t zsta[19] = {16.21, 22.79, 29.22, 42.56, 67.63, 116.10, 137.80, 164.10, 186.20}; //
1925 // average hit Z-position - Run 7 !!!
1926 /*
1927 const Double_t zsta[19] = {18.55, 27.16, 35.78, 61.05, 91.50, 123.50, 153.90, 185.90, 216.40, 248.20}; // average
1928 hit Z-position - Run 8 !!! const Double_t pars[19][4] = { {1.30358, 20.8953, 0.857369, 0.56339}, {1.64202, 7.18813,
1929 0.596002, 0.694601}, {3.10765, 3.21564, 0.291252, 1.08062}, {2.25484, 3.81810, 0.430724, 0.840519},
1930 {3.38309, 4.33504, 0.349704, 1.07882}, {3.99252, 3.35587, 0.302402, 1.65050},
1931 {10.3321, 4.24742, 0.168995, 1.71113} };
1932 */
1933}
1934
1935// -------------------------------------------------------------------------
1936
1938{
1939 // Finish event
1940 /*
1941 FairRootManager* ioman = FairRootManager::Instance();
1942 */
1943 if (fStream2out.is_open()) {
1944 fStream2out << " Event: " << fEvent << " " << fMap2Out.size() << endl;
1945 for (unordered_map<string, int>::iterator it = fMap2Out.begin(); it != fMap2Out.end(); ++it)
1946 fStream2out << it->first << " " << it->second << "\n";
1947 }
1948 if (fStream3out.is_open()) {
1949 fStream3out << " Event: " << fEvent << " " << fMap3Out.size() << endl;
1950 for (unordered_map<string, int>::iterator it = fMap3Out.begin(); it != fMap3Out.end(); ++it)
1951 fStream3out << it->first << " " << it->second << "\n";
1952 }
1953 ++fEvent;
1954}
1955
1956// -------------------------------------------------------------------------
1957
1959{
1960 printf("Work time of BmnStsVectorFinderV9: %4.2f sec.\n", workTime);
1961 if (fStream2out.is_open())
1962 fStream2out.close();
1963 if (fStream3out.is_open())
1964 fStream3out.close();
1965}
1966
1967//__________________________________________________________________________
1968
1969// AZ-270625 TVector3 BmnStsVectorFinderV9::Parabola(TVector3& pos0, TVector3& pos1, TVector3& pos2)
1970TVector3 BmnStsVectorFinderV9::Parabola(TVector3& pos0, TVector3& pos1, TVector3& pos2, int ix) // AZ-270625
1971{
1972 // Get parabolic track approximation from 3 points (X vs Z for ix = 2 or Y vs X for ix = 0)
1973 // y = a*x^2 + bx + c
1974
1975 Double_t x2[3] = {pos0[2] - fXyzv[2], pos1[2] - fXyzv[2], pos2[2] - fXyzv[2]};
1976 Double_t y2[3] = {pos0[0] - fXyzv[0], pos1[0] - fXyzv[0], pos2[0] - fXyzv[0]};
1977 Double_t x0[3] = {pos0[0], pos1[0], pos2[0]};
1978 Double_t y0[3] = {pos0[1], pos1[1], pos2[1]};
1979 Double_t *x = x0, *y = y0;
1980 if (ix == 2) {
1981 x = x2;
1982 y = y2;
1983 }
1984
1985 Double_t denom = (x[0] - x[1]) * (x[0] - x[2]) * (x[1] - x[2]);
1986 Double_t dy10 = y[1] - y[0];
1987 Double_t dy02 = y[0] - y[2];
1988 Double_t dy21 = y[2] - y[1];
1989 // Double_t a = x[2] * (y[1] - y[0]) + x[1] * (y[0] - y[2]) + x[0] * (y[2] - y[1]);
1990 Double_t a = x[2] * dy10 + x[1] * dy02 + x[0] * dy21;
1991 a /= denom;
1992 // Double_t b = x[0]*x[0] * (y[1] - y[2]) + x[2]*x[2] * (y[0] - y[1]) +
1993 // x[1]*x[1] * (y[2] - y[0]);
1994 Double_t b = -x[0] * x[0] * dy21 - x[2] * x[2] * dy10 - x[1] * x[1] * dy02;
1995 b /= denom;
1996 Double_t c = x[1] * x[1] * (x[2] * y[0] - x[0] * y[2]) + x[1] * (x[0] * x[0] * y[2] - x[2] * x[2] * y[0])
1997 + x[0] * x[2] * (x[2] - x[0]) * y[1];
1998 c /= denom;
1999 return TVector3(c, b, a);
2000 // 𝐴=𝑥3(𝑦2−𝑦1)+𝑥2(𝑦1−𝑦3)+𝑥1(𝑦3−𝑦2) / (𝑥1−𝑥2)(𝑥1−𝑥3)(𝑥2−𝑥3)
2001 // 𝐵=𝑥21(𝑦2−𝑦3)+𝑥23(𝑦1−𝑦2)+𝑥22(𝑦3−𝑦1) / (𝑥1−𝑥2)(𝑥1−𝑥3)(𝑥2−𝑥3)
2002 // 𝐶=𝑥22(𝑥3𝑦1−𝑥1𝑦3)+𝑥2(𝑥21𝑦3−𝑥23𝑦1)+𝑥1𝑥3(𝑥3−𝑥1)𝑦2 / (𝑥1−𝑥2)(𝑥1−𝑥3)(𝑥2−𝑥3)
2003}
2004
2005// -------------------------------------------------------------------------
2006
2008{
2009 // Fit tracks
2010
2011 const Double_t gkChi2Cut = 5.0; // 10.0;
2012 // const Double_t gkChi2Cut = 10.0; //AZ-010123
2013 // fTracks.clear();
2014
2015 // for (Int_t ista = 0; ista < fNsta-3; ++ista) {
2016 for (Int_t ista = 0; ista < fNsta; ++ista) {
2017 Int_t ntra = fCandVec[ista].size();
2018 if (fVerbose > 0)
2019 cout << " FitTracks: " << ista << " " << ntra << endl;
2020
2021 for (Int_t itra = 0; itra < ntra; ++itra) {
2022 candvec& cand = fCandVec[ista][itra];
2023 // if (cand.nextind >= 0) continue; // track has an extension already processed
2024
2025 map<Int_t, Int_t>& hitMap = cand.stahit;
2026 Int_t nhits = hitMap.size();
2027 // if (nhits < 3) continue; // too short track
2028 if (nhits < fNhitsMin[fPass])
2029 continue; // too short track
2030 CbmStsTrack track;
2031 TArrayI& hits = *track.GetStsHits();
2032 hits.Set(nhits);
2033 Int_t indx = 0, iok = 1;
2034
2035 // Check if the track candidate has been checked already
2036 string hitcode("-");
2037 for (map<Int_t, Int_t>::iterator mit = hitMap.begin(); mit != hitMap.end(); ++mit)
2038 hitcode += (to_string(mit->second) + "-");
2039 // cout << itra << " " << hitcode << endl;
2040
2041 /* AZ-140725
2042 Int_t same = 0; //, sta0 = hitMap.begin()->first;
2043
2044 //same = fCandSet[sta0].count(hitcode);
2045 same = fCandSet[nhits].count(hitcode);
2046 //if (same) cout << " same: " << sta0 << " " << same << " " << endl;
2047 */
2048
2049 /////AZ if (same) continue; // used combination - skip it ???
2050 // fCandSet[sta0].insert(hitcode);
2051 fCandSet[nhits].insert(hitcode);
2052
2053 for (map<Int_t, Int_t>::iterator mit = hitMap.begin(); mit != hitMap.end(); ++mit) {
2054 hits[indx++] = mit->second;
2055 // Debug
2056 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(mit->second);
2057 // cout << " hit: " << mit->first << " " << hit->GetX() << " " << hit->GetY() << " " << hit->GetZ() << "
2058 // "
2059 // << hit->GetDx() << " " << hit->GetDy() << endl;
2060 // cout << " hit: " << mit->first << " " << mit->second << endl;
2061 // hit->SetDx(0.08/TMath::Sqrt(12.0));
2062 /// hit->SetDx(0.05); //AZ-110123 - early estimate
2063 // hit->SetDx(0.015);
2064 /// hit->SetDy(0.1234);
2065 // AZ-030123 if (hit->GetStationNr() <= 3) hit->SetDx(0.02/TMath::Sqrt(12.0));
2066 // if (hit->GetStationNr() <= fNSi) hit->SetDx(0.02/TMath::Sqrt(12.0)); //AZ-030123
2067 // if (hit->GetStationNr() <= 3) hit->SetDx(0.0025);
2068 // if (hit->GetStationNr() % 2 != 0) hit->SetCovXY(1.968e-3); // this is for 2-D hits (CbmFitter)
2069 // else hit->SetCovXY(-1.968e-3);
2070 // hit->SetDy(0.03); // for test
2072 Double_t dx = stat->GetSector(0)->GetDx();
2073 // if (dx < 0.02) dx *= 2; // scale up for Si
2074 // AZ-120722 if (dx > 0.01) dx *= 1.2; // scale up for GEMs
2075 if (dx > 0.02)
2076 dx *= 1.2; // AZ-120722 scale up for GEMs
2077 hit->SetDx(dx / TMath::Sqrt(12.0)); // AZ-210125 - as in vers.1
2078 // if (dx < 0.02) hit->SetDx(0.01); //AZ-040123 - early estimate for Si
2079 /// if (dx < 0.02) hit->SetDx(0.02); //AZ-040123 - early estimate for Si
2080 /*
2081 if (fMatBudgetFileName != "" && hit->GetDz() < 1.e-7) {
2082 // Store material budget for the hit (along the beam)
2083 Double_t zshift = (dx < 0.02) ? 0.5 : 1.5; // Si or GEM
2084 TProfile2D *prof = fMatHistos.lower_bound(hit->GetZ()-zshift)->second;
2085 int ix = prof->FindBin(hit->GetX());
2086 int iy = prof->FindBin(hit->GetY());
2087 Double_t radThick = prof->GetBinContent(ix,iy);
2088 hit->SetDz(radThick/100);
2089 }
2090 */
2091 }
2092
2093 // cout << " before " << track.GetParamFirst()->GetZ() << endl;
2094 // fitter.DoFit(&track);
2095 fitter.Fit(&track); // AZ
2096 // cout << " after " << track.GetParamFirst()->GetZ() << " " << track.GetNStsHits() << " " <<
2097 // track.GetChi2() << endl;
2098 /*
2099 CbmKFTrack kftr = CbmKFTrack(track);
2100 fitter.SetKFHits(kftr, &track);
2101 kftr.Fit(kTRUE); // downstream
2102 kftr.Fit(kFALSE); // upstream
2103 */
2104 if (fVerbose > 0) {
2105 cout << " aaaaaaa " << endl;
2106 // track.GetParamFirst()->Print();
2107 cout << track.GetChi2() << " " << nhits << " " << endl;
2108 }
2109 // AZ-111221 if (track.GetChi2() / track.GetNDF() > gkChi2Cut) {
2110 if (track.GetChi2() / track.GetNDF() > gkChi2Cut && track.GetNStsHits() > 3) {
2111 /*
2112 // Too high chi2/NDF - try to remove one outlier with the largest dChi2
2113 // Based on the code from CbmKFTrackInterface::Fit()
2114 CbmKFTrack kftr;
2115 //kftr.SetStsTrack(track, kFALSE); // last parameter
2116 //Bool_t downstream = kFALSE;
2117 kftr.SetStsTrack(track, kTRUE); // first parameter
2118 fitter.SetKFHits(kftr,&track);
2119 Bool_t downstream = kTRUE;
2120 Double_t qp0 = 0.0;
2121 Double_t *cov = kftr.GetCovMatrix();
2122 for (Int_t j = 0; j < 15; ++j) cov[j] = 0.0;
2123 cov[0] = cov[2] = cov[5] = cov[9] = cov[14] = 10000.0;
2124 kftr.GetRefChi2() = 0.0;
2125 Double_t chi20 = 0.0, dchi2 = 0.0, dchi2max = 0.0;
2126
2127 CbmKF *KF = CbmKF::Instance();
2128 CbmKFHit *h = NULL;
2129 Int_t istold = 0, imax = 0;
2130 Bool_t err = kFALSE;
2131 set<Int_t> indok;
2132
2133 //for (Int_t i = nhits - 1; i >= 0; i--) {
2134 // h = kftr.GetHit( i );
2135 // Int_t ist = h->MaterialIndex;
2136 // if (i < nhits - 1) {
2137 // for (Int_t j = istold - 1; j > ist; j--)
2138 // err = err || KF->vMaterial[j]->Pass( kftr, downstream, qp0 );
2139 // }
2140
2141 for (Int_t i = 0; i < nhits; i++) {
2142 h = kftr.GetHit( i );
2143 Int_t ist = h->MaterialIndex;
2144 if (i > 0) {
2145 for (Int_t j = istold + 1; j < ist; j++)
2146 err = err || KF->vMaterial[j]->Pass( kftr, downstream, qp0 );
2147 }
2148 err = err || h->Filter( kftr, downstream, qp0 );
2149 dchi2 = kftr.GetRefChi2() - chi20;
2150 cout << dchi2 << " " << kftr.GetRefChi2() << endl;
2151 //if (dchi2 <= gkChi2Cut) indok.insert(i);
2152 //if (dchi2 <= 2*gkChi2Cut) indok.insert(i);
2153 indok.insert(i);
2154 if (dchi2 > dchi2max) {
2155 dchi2max = dchi2;
2156 imax = i;
2157 }
2158 chi20 = kftr.GetRefChi2();
2159 istold = ist;
2160 }
2161 */
2162 // Remove last hit and refit
2163 set<Int_t> indok;
2164 for (Int_t i = 0; i < nhits; i++)
2165 indok.insert(i);
2166 int imax = nhits - 1;
2167
2168 if (indok.size() > 3) {
2169 // if (indok.size() >= fNhitsMin[fPass]) {
2170 // if (indok.size()-1 >= fNhitsMin[fPass]) {
2171 indok.erase(imax);
2172 // Good short track - refit
2173 indx = 0;
2174 hitcode = "-";
2175 for (set<Int_t>::iterator sit = indok.begin(); sit != indok.end(); ++sit) {
2176 hits[indx++] = hits[*sit];
2177 // hitcode += hits[*sit];
2178 hitcode += (to_string(hits[*sit]) + "-");
2179 }
2180 // if (fCandSet[sta0].count(hitcode)) continue;
2181 // fCandSet[sta0].insert(hitcode);
2182 // cout << " failed " << hitcode << endl;
2183 if (fCandSet[indok.size()].find(hitcode) != fCandSet[indok.size()].end())
2184 continue;
2185 fCandSet[indok.size()].insert(hitcode);
2186
2187 hits.Set(indok.size());
2188 // fitter.DoFit(&track);
2189 fitter.Fit(&track); // AZ
2190 int ndf = (track.GetFlag() == 0) ? track.GetNDF() : 1;
2191 // cout << " bbbbbb " << endl;
2192 // track.GetParamFirst()->Print();
2193 if (fVerbose > 0)
2194 cout << " bbbbbb " << track.GetChi2() << " " << hits.GetSize() << " " << track.GetChi2() / ndf
2195 << endl;
2196 if (track.GetChi2() / track.GetNDF() > gkChi2Cut)
2197 iok = 0;
2198 } else
2199 iok = 0;
2200
2201 } // if (track.GetChi2() / track.GetNDF() > gkChi2Cut)
2202
2203 // Good track - extra printout
2204 if (iok) {
2205 Double_t qual = track.GetNStsHits();
2206 // qual += (100.0 - TMath::Min(TMath::Abs(track.GetChi2()),100.0)) / 101.0;
2207 // if (track.GetNStsHits() <= 4) qual += TMath::Min(1/TMath::Abs(track.GetParamFirst()->GetQp()),10.0)
2208 // / 11.0;
2209 if (track.GetNStsHits() < 4) {
2210 // Vertex constraint
2211 /*
2212 TVector3 mom3, pos3;
2213 track.GetParamFirst()->Momentum(mom3);
2214 track.GetParamFirst()->Position(pos3);
2215 //Double_t ang = mom3.Angle(pos3);
2216 Double_t phi1 = TMath::ATan2 (track.GetParamFirst()->GetY(), track.GetParamFirst()->GetX());
2217 Double_t phi2 = TMath::ATan2 (track.GetParamFirst()->GetTy(), track.GetParamFirst()->GetTx());
2218 Double_t dphi = phi1 - Proxim(phi1,phi2);
2219 //qual += (2.1 - TMath::Min(TMath::Abs(dphi),2.1)) / 2.2;
2220 //Double_t www = TMath::Exp(-TMath::Abs(dphi)/2.1);
2221 Double_t www = TMath::Min (TMath::Exp(-TMath::Abs(dphi)/0.2), 0.999); // 0.2 - rms
2222 if (TMath::Abs(dphi) > 2.1) www = 0.0;
2223 */
2224 // Linear extrapolation to Zvert
2225 Double_t xextr; // = pos3.X() - pos3.Z() * track.GetParamFirst()->GetTx() + 0.04;
2226 Double_t yextr; // = pos3.Y() - pos3.Z() * track.GetParamFirst()->GetTy();
2227 // Extrapolation to Zvert
2228 FairTrackParam param = *track.GetParamFirst();
2229 fitter.Extrapolate(&param, fXyzv[2], &param);
2230 xextr = param.GetX() - fXyzv[0];
2231 yextr = param.GetY() - fXyzv[1];
2232 Double_t rad =
2233 TMath::Sqrt(xextr * xextr / 0.035 / 0.035 + yextr * yextr / 0.2 / 0.2); // 0.035, 0.2 - sigmas
2234 Double_t www = TMath::Min(TMath::Exp(-rad), 0.999);
2235 qual += TMath::Exp(-TMath::Abs(track.GetChi2())) * www;
2236 } else
2237 qual += (100.0 - TMath::Min(TMath::Abs(track.GetChi2()), 100.0)) / 101.0;
2238 fTracks.insert(pair<Double_t, CbmStsTrack>(-qual, track));
2239 // AZ-130722 pair<multimap<Int_t,Int_t>::iterator,multimap<Int_t,Int_t>::iterator> ret;
2240 pair<unordered_multimap<Int_t, Int_t>::iterator, unordered_multimap<Int_t, Int_t>::iterator>
2241 ret; // AZ-130722
2242 nhits = hits.GetSize();
2243 if (fVerbose > 0) {
2244 cout << " Good track: " << endl;
2245 // track.GetParamFirst()->Print();
2246 cout << track.GetChi2() << " " << nhits << " " << track.GetParamFirst()->GetZ() << endl;
2247
2248 for (Int_t j = nhits - 1; j >= 0; --j) {
2249 ret = fHit2id.equal_range(hits[j]);
2250 cout << " (";
2251 // AZ-130722 for (multimap<Int_t,Int_t>::iterator mit = ret.first; mit != ret.second; ++mit) {
2252 for (unordered_multimap<Int_t, Int_t>::iterator mit = ret.first; mit != ret.second; ++mit) {
2253 if (mit == ret.first)
2254 cout << mit->first << "*";
2255 else
2256 cout << ":";
2257 cout << mit->second;
2258 }
2259 cout << ")";
2260 }
2261 cout << "\n";
2262 }
2263 }
2264
2265 } // for (Int_t itra = 0;
2266 }
2267}
2268
2269// -------------------------------------------------------------------------
2270
2272{
2273 // Remove double tracks (keep the ones with better quality)
2274
2275 multimap<Double_t, CbmStsTrack>::iterator mit = fTracks.begin(), mit1;
2276 Int_t nOK = fTracks.size(), nOut = fVectorArray->GetEntriesFast();
2277
2278 for (; mit != fTracks.end(); ++mit) {
2279 if (mit->second.GetFlag())
2280 continue; // discarded track
2281 mit1 = mit;
2282 ++mit1;
2283
2284 for (; mit1 != fTracks.end(); ++mit1) {
2285 if (mit1->second.GetFlag())
2286 continue; // discarded track
2287 if (!AreTracksDoubles(mit1->second, mit->second))
2288 continue;
2289 mit1->second.SetFlag(1); // double - discard it
2290 --nOK;
2291 /*
2292 // Debug printout
2293 TArrayI &hits = *mit1->second.GetStsHits();
2294 Int_t nhits = mit1->second.GetNStsHits();
2295 pair<multimap<Int_t,Int_t>::iterator,multimap<Int_t,Int_t>::iterator> ret;
2296 cout << " Double: " << mit->first << " " << mit1->first << endl;
2297 for (Int_t j = nhits-1; j >= 0; --j) {
2298 ret = fHit2id.equal_range(hits[j]);
2299 cout << " (";
2300 for (multimap<Int_t,Int_t>::iterator mit2 = ret.first; mit2 != ret.second; ++mit2) {
2301 if (mit2 == ret.first) cout << mit2->first << "*";
2302 else cout << ":";
2303 cout << mit2->second;
2304 }
2305 cout << ")";
2306 }
2307 cout << "\n";
2308 */
2309 }
2310
2311 new ((*fVectorArray)[nOut++]) CbmStsTrack(mit->second);
2312 // cout << " yyyyy " << mit->second.GetParamFirst()->GetZ() << " " << mit->second.GetNStsHits() << endl;
2313 }
2314 if (fVerbose > 0)
2315 cout << " RemoveDoubles: " << fTracks.size() << " " << nOK << endl;
2316}
2317
2318// -------------------------------------------------------------------------
2319
2321{
2322 /// Searching common hits in 2 tracks to determine doubles
2323 /// tr1 contains fewer hits than tr2
2324
2325 Int_t limCommonPoint = (tr1.GetNStsHits() + 1) / 2; // at least so many common hits should be found
2326 // limCommonPoint = TMath::Min (limCommonPoint, 2); // 2 common hits at max
2327 limCommonPoint = TMath::Min(limCommonPoint, 1); // 1 common hit at max
2328 TArrayI &hits1 = *tr1.GetStsHits(), &hits2 = *tr2.GetStsHits();
2329 Int_t nh1 = hits1.GetSize(), nh2 = hits2.GetSize(), nHitsCommon = 0, j = nh2 - 1;
2330 if (nh1 == 3)
2331 limCommonPoint = 0;
2332
2333 for (Int_t i = nh1 - 1; i >= 0; i--) {
2334 // for (Int_t i = 0; i <= nh1 - 1; ++i){
2335 CbmStsHit* hit1 = (CbmStsHit*)fHitArray->UncheckedAt(tr1.GetStsHitIndex(i));
2336
2337 for (; j >= 0; j--) {
2338 // for ( ; j <= nh2 - 1; ++j){
2339 CbmStsHit* hit2 = (CbmStsHit*)fHitArray->UncheckedAt(tr2.GetStsHitIndex(j));
2340
2341 // Is the hit common for two tracks?
2342 if (hit1 == hit2) {
2343 nHitsCommon++;
2344 // AZ-281121 if (nHitsCommon == limCommonPoint) return kTRUE; // already enough common hits
2345 if (nHitsCommon > limCommonPoint)
2346 return kTRUE; // already enough common hits
2347 break;
2348 }
2349
2350 if (hit2->GetStationNr() < hit1->GetStationNr())
2351 break; // already closer to target
2352 }
2353
2354 // AZ-281121 if ((nh1 - i - 1) + limCommonPoint - nHitsCommon > nh1) return kFALSE; // there'll be not enough
2355 // common hits already
2356 if (i + nHitsCommon <= limCommonPoint)
2357 return kFALSE; // there'll be not enough common hits already
2358 }
2359
2360 // AZ-281121 if (nHitsCommon < limCommonPoint) return kFALSE; // not too many common hits
2361 if (nHitsCommon <= limCommonPoint)
2362 return kFALSE; // not too many common hits
2363
2364 return kTRUE;
2365}
2366
2367// -------------------------------------------------------------------------
2368/*
2369void BmnStsVectorFinderV9::RemoveFakes()
2370{
2371 // Remove fake tracks (according to some empirical rules)
2372
2373 Int_t ncand = fVectorArray->GetEntriesFast();
2374
2375 for (Int_t j = 0; j < ncand; ++j) {
2376 CbmStsTrack *tr = (CbmStsTrack*) fVectorArray->UncheckedAt(j);
2377 Int_t nhits = tr->GetNStsHits();
2378 if (1/TMath::Abs(tr->GetParamFirst()->GetQp()) < 0.2) { fVectorArray->Remove(tr); continue; }
2379 if (nhits < 4) {
2380 CbmStsHit *hit = (CbmStsHit*) fHitArray->UncheckedAt(tr->GetStsHitIndex(0));
2381 if (hit->GetStationNr() <= 3) continue;
2382 fVectorArray->Remove(tr); // short track starts in GEM
2383 }
2384 }
2385 fVectorArray->Compress();
2386
2387 cout << " Remove fakes: " << ncand << " " << fVectorArray->GetEntriesFast() << endl;
2388}
2389*/
2390// -------------------------------------------------------------------------
2392{
2393 // Remove fake tracks (according to some empirical rules)
2394
2395 multimap<Double_t, CbmStsTrack>::iterator mit = fTracks.begin();
2396 Int_t nOK = fTracks.size(), nOut = nOK;
2397
2398 for (; mit != fTracks.end(); ++mit) {
2399 if (mit->second.GetFlag())
2400 continue; // discarded track
2401 CbmStsTrack* tr = &mit->second;
2402 Int_t nhits = tr->GetNStsHits();
2403 if (1 / TMath::Abs(tr->GetParamFirst()->GetQp()) < 0.2) {
2404 tr->SetFlag(1);
2405 --nOut;
2406 continue;
2407 }
2408 if (nhits < 4) {
2409 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(tr->GetStsHitIndex(0));
2410 if (hit->GetStationNr() <= 3)
2411 continue;
2412 tr->SetFlag(1); // short track starts in GEM
2413 --nOut;
2414 }
2415 }
2416
2417 if (fVerbose > 0)
2418 cout << " Remove fakes: " << nOK << " " << nOut << endl;
2419}
2420
2421// -------------------------------------------------------------------------
2422
2424{
2425 // Exclude fake tracks (with too many shared clusters)
2426
2427 Int_t ncand = fVectorArray->GetEntriesFast();
2428
2429 map<Int_t, set<Int_t>> mClusTr;
2430 map<Int_t, Double_t> mWeight;
2431
2432 for (Int_t j = 0; j < ncand; ++j) {
2433 CbmStsTrack* tr = (CbmStsTrack*)fVectorArray->UncheckedAt(j);
2434 Int_t nhits = tr->GetNStsHits();
2435
2436 for (Int_t jh = 0; jh < nhits; ++jh) {
2437 Int_t indx = tr->GetStsHitIndex(jh);
2438 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(indx);
2439
2440 for (Int_t side = 0; side < 2; ++side) {
2441 Int_t iclus = hit->GetDigi(side);
2442 if (mClusTr.count(iclus) == 0) {
2443 set<Int_t> aaa;
2444 mClusTr[iclus] = aaa;
2445 }
2446 mClusTr[iclus].insert(j);
2447 }
2448 }
2449
2450 Double_t www = TMath::Exp(-tr->GetChi2() / tr->GetNDF());
2451 // Extrapolation to Zvert
2452 if (nhits == 3) {
2453 FairTrackParam param = *tr->GetParamFirst();
2454 fitter.Extrapolate(&param, fXyzv[2], &param);
2455 Double_t xextr = param.GetX() - fXyzv[0];
2456 Double_t yextr = param.GetY() - fXyzv[1];
2457 Double_t rad =
2458 TMath::Sqrt(xextr * xextr / 0.035 / 0.035 + yextr * yextr / 0.2 / 0.2); // 0.035, 0.2 - sigmas
2459 www *= TMath::Exp(-rad);
2460 }
2461 mWeight[j] = www;
2462 }
2463
2464 while (1) {
2465 multimap<Double_t, pair<Int_t, Int_t>> mapQual;
2466 set<Int_t> set2kill, set2kill1;
2467
2468 for (Int_t j = 0; j < ncand; ++j) {
2469 CbmStsTrack* tr = (CbmStsTrack*)fVectorArray->UncheckedAt(j);
2470 if (tr == NULL)
2471 continue; // removed track
2472 Int_t nhits = tr->GetNStsHits();
2473 Int_t nover = 0;
2474
2475 for (Int_t jh = 0; jh < nhits; ++jh) {
2476 Int_t indx = tr->GetStsHitIndex(jh);
2477 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(indx);
2478 // if (mClusTr[hit->GetDigi(0)].size() > 1 || mClusTr[hit->GetDigi(1)].size() > 1) ++nover;
2479
2480 for (Int_t side = 0; side < 2; ++side) {
2481 Int_t iclus = hit->GetDigi(side);
2482 if (mClusTr[iclus].size() > 1)
2483 ++nover;
2484 }
2485 }
2486 // Double_t quality = nhits * 1000 + (1 - Double_t(nover) / nhits) * 100
2487 //+ (1 - TMath::Min(tr->GetChi2(),100.0) / 100);
2488 Double_t quality = nhits * 1000;
2489 Double_t www = TMath::Exp(-Double_t(nover) / nhits / 2) * mWeight[j];
2490 mapQual.insert(pair<Double_t, pair<Int_t, Int_t>>(quality + www, pair<Int_t, Int_t>(j, nover)));
2491 // if ((nover == nhits) || (nhits == 3 && nover == 2)) set2kill.insert(j);
2492 // if ((nhits <= 4 && nover == nhits) || (nhits == 3 && nover == 2)) set2kill.insert(j);
2493 // if (nhits <= 4 && Double_t(nover)/nhits/2 > 0.81) set2kill.insert(j);
2494 if (nhits <= 5 && Double_t(nover) / nhits / 2 > 0.6)
2495 set2kill.insert(j);
2496 else if (!fExact && nhits <= 3 && www < 1.e-8)
2497 set2kill1.insert(j); // 1e-8 - empirical value
2498 }
2499
2500 if (set2kill.size())
2501 set2kill1.clear(); // first kill in set2kill
2502 if (set2kill.size() || set2kill1.size()) {
2503 // Remove track and update cluster-to-track info
2504
2505 for (multimap<Double_t, pair<Int_t, Int_t>>::iterator mit = mapQual.begin(); mit != mapQual.end(); ++mit) {
2506 Int_t itr = mit->second.first;
2507 CbmStsTrack* tr = (CbmStsTrack*)fVectorArray->UncheckedAt(itr);
2508 Int_t nhits = tr->GetNStsHits(); //, nover = mit->second.second;
2509 if (set2kill.count(itr) == 0 && set2kill1.count(itr) == 0)
2510 continue;
2511
2512 for (Int_t jh = 0; jh < nhits; ++jh) {
2513 Int_t indx = tr->GetStsHitIndex(jh);
2514 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(indx);
2515 if (mClusTr[hit->GetDigi(0)].count(itr) == 0 || mClusTr[hit->GetDigi(1)].count(itr) == 0)
2516 // AZ-300822 { cout << " !!! No track found: " << itr << endl; exit(0); }
2517 {
2518 if (fVerbose > 0)
2519 cout << " !!! No track found: " << itr << endl; /*exit(0);*/
2520 }
2521 mClusTr[hit->GetDigi(0)].erase(itr);
2522 mClusTr[hit->GetDigi(1)].erase(itr);
2523 }
2524 fVectorArray->Remove(tr);
2525 break;
2526 }
2527 } else
2528 break;
2529 } // while (1)
2530
2531 fVectorArray->Compress();
2532
2533 // AZ-280623 - kill short tracks (3 or 4 hits without consecutive triplet)
2534 int nKilled = 0;
2535 ncand = fVectorArray->GetEntriesFast();
2536 /* AZ-190125 - does not kill anything
2537 for (Int_t j = 0; j < ncand; ++j) {
2538 CbmStsTrack *tr = (CbmStsTrack*) fVectorArray->UncheckedAt(j);
2539 Int_t nhits = tr->GetNStsHits();
2540 // AZ-190125 if (nhits > 4) continue;
2541 if (nhits > 44) continue; // AZ-190125
2542 // AZ-190125 int sta0 = -1, ncons = 0;
2543 int sta0 = -1, ncons = 1; // AZ-190125
2544
2545 for (Int_t jh = 0; jh < nhits; ++jh) {
2546 Int_t indx = tr->GetStsHitIndex(jh);
2547 CbmStsHit *hit = (CbmStsHit*) fHitArray->UncheckedAt(indx);
2548 int sta = hit->GetStationNr();
2549 if (jh == 0) sta0 = hit->GetStationNr();
2550 if (sta - sta0 < 2) {
2551 //fVectorArray->RemoveAt(j);
2552 ++ncons;
2553 } else ncons = 1;
2554 if (ncons >= 3) break;
2555 sta0 = sta;
2556 }
2557 if (ncons < 3) { fVectorArray->RemoveAt(j); ++nKilled; }
2558 }
2559 fVectorArray->Compress();
2560 cout << " !!! Killed w/out triplet: " << nKilled << endl;
2561 */
2562 // AZ-030723 - check short tracks for missing hits (remove if nmissMax hits in the acceptance are missing)
2563 ncand = fVectorArray->GetEntriesFast();
2564 nKilled = 0;
2565
2566 for (Int_t j = 0; j < ncand; ++j) {
2567 CbmStsTrack* tr = (CbmStsTrack*)fVectorArray->UncheckedAt(j);
2568 Int_t nhits = tr->GetNStsHits();
2569 // if (nhits > 4) continue;
2570 if (nhits > -4)
2571 continue; // AZ-200125 - do not kill
2572 // if (nhits > 44) continue;
2573 set<int> setStat;
2574
2575 for (int ih = 0; ih < nhits; ++ih) {
2576 int indx = tr->GetStsHitIndex(ih);
2577 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(indx);
2578 setStat.insert(hit->GetStationNr());
2579 }
2580
2581 CbmKFTrack kftr = CbmKFTrack(*tr);
2582 fitter.SetKFHits(kftr, tr);
2583 FairTrackParam param;
2584
2585 int firstSta = *setStat.begin(), nmisSi = 0, nmisGem = 0, nmiss = 0;
2586
2587 // Go upstream
2588
2589 for (int ista = firstSta - 2; ista >= 0; --ista) {
2590 nmiss = 0;
2591 if (ista >= fNSi) {
2592 BmnGemStripStation* stat = fGemStationSet->GetStation(ista - fNSi);
2593 kftr.Smooth(stat->GetZPosition());
2594 kftr.GetTrackParam(param);
2595 // fitter.Extrapolate (&param, stat->GetZPosition(), &param);
2596 // if (param.GetX() < stat->GetXMinStation() || param.GetX() > stat->GetXMaxStation()) continue;
2597 // if (param.GetY() < stat->GetYMinStation() || param.GetY() > stat->GetYMaxStation()) continue;
2598
2599 for (int imod = 0; imod < stat->GetNModules(); ++imod) {
2600 BmnGemStripModule* mod = stat->GetModule(imod);
2601 if (mod->IsPointInsideModule(param.GetX(), param.GetY())) {
2602 ++nmiss;
2603 ++nmisGem;
2604 // cout << " +++ " << param.GetX() << " " << param.GetY() << endl;
2605 break;
2606 } // else cout << " --- " << param.GetX() << " " << param.GetY() << endl;
2607 }
2608 } else {
2609 BmnSiliconStation* stat = fSilStationSet->GetStation(ista);
2610 kftr.Smooth(stat->GetZPosition());
2611 kftr.GetTrackParam(param);
2612 // fitter.Extrapolate (&param, stat->GetZPosition(), &param);
2613 // if (param.GetX() < stat->GetXMinStation() || param.GetX() > stat->GetXMaxStation()) continue;
2614 // if (param.GetY() < stat->GetYMinStation() || param.GetY() > stat->GetYMaxStation()) continue;
2615
2616 for (int imod = 0; imod < stat->GetNModules(); ++imod) {
2617 BmnSiliconModule* mod = stat->GetModule(imod);
2618 // AZ-180125 if (mod->IsPointInsideModule(param.GetX(),param.GetY())) {
2619 if (mod->IsPointInsideModule(param.GetX(), param.GetY(), kFALSE)) { // AZ-180125
2620 ++nmiss;
2621 ++nmisSi;
2622 // cout << " +++ " << param.GetX() << " " << param.GetY() << endl;
2623 break;
2624 } // else cout << " --- " << param.GetX() << " " << param.GetY() << endl;
2625 }
2626 }
2627 if (nmiss == 0)
2628 break; // no need for checking other stations
2629 } // for (int ista = firstSta - 2;
2630
2631 // Check downstream stations
2632 nmiss = 0;
2633
2634 for (int ista = firstSta; ista <= fNsta; ++ista) {
2635 if (setStat.find(ista + 1) != setStat.end())
2636 continue;
2637 nmiss = 0;
2638 if (ista >= fNSi) {
2639 BmnGemStripStation* stat = fGemStationSet->GetStation(ista - fNSi);
2640 kftr.Smooth(stat->GetZPosition());
2641 kftr.GetTrackParam(param);
2642 // fitter.Extrapolate (&param, stat->GetZPosition(), &param);
2643 // if (param.GetX() < stat->GetXMinStation() || param.GetX() > stat->GetXMaxStation()) continue;
2644 // if (param.GetY() < stat->GetYMinStation() || param.GetY() > stat->GetYMaxStation()) continue;
2645
2646 for (int imod = 0; imod < stat->GetNModules(); ++imod) {
2647 BmnGemStripModule* mod = stat->GetModule(imod);
2648 if (mod->IsPointInsideModule(param.GetX(), param.GetY())) {
2649 ++nmiss;
2650 ++nmisGem;
2651 // cout << " +++ " << param.GetX() << " " << param.GetY() << endl;
2652 break;
2653 } // else cout << " --- " << param.GetX() << " " << param.GetY() << endl;
2654 }
2655 } else {
2656 BmnSiliconStation* stat = fSilStationSet->GetStation(ista);
2657 kftr.Smooth(stat->GetZPosition());
2658 kftr.GetTrackParam(param);
2659 // fitter.Extrapolate (&param, stat->GetZPosition(), &param);
2660 // if (param.GetX() < stat->GetXMinStation() || param.GetX() > stat->GetXMaxStation()) continue;
2661 // if (param.GetY() < stat->GetYMinStation() || param.GetY() > stat->GetYMaxStation()) continue;
2662
2663 for (int imod = 0; imod < stat->GetNModules(); ++imod) {
2664 BmnSiliconModule* mod = stat->GetModule(imod);
2665 // AZ-180125 if (mod->IsPointInsideModule(param.GetX(),param.GetY())) {
2666 if (mod->IsPointInsideModule(param.GetX(), param.GetY(), kFALSE)) { // AZ-180125
2667 ++nmiss;
2668 ++nmisSi;
2669 // cout << " +++ " << param.GetX() << " " << param.GetY() << endl;
2670 break;
2671 } // else cout << " --- " << param.GetX() << " " << param.GetY() << endl;
2672 }
2673 }
2674 if (nmiss == 0)
2675 break; // no need for checking other stations
2676 } // for (int ista = firstSta; ista <= fNsta;
2677
2678 if (nmisSi >= 2) {
2679 fVectorArray->RemoveAt(j);
2680 ++nKilled;
2681 continue;
2682 }
2683 tr->SetFlag(nmisSi * 10 + nmisGem);
2684
2685 } // for (Int_t j = 0; j < ncand;
2686 // cout << " !!! Killed due to missing: " << nKilled << endl;
2687 fVectorArray->Compress();
2688
2689 if (fVerbose > 0)
2690 cout << " Exclude fakes: " << ncand << " " << fVectorArray->GetEntriesFast() << endl;
2691}
2692
2693// -------------------------------------------------------------------------
2694
2696{
2697 // Compute momentum correction for parabolic extrapolation
2698
2699 Double_t pars[19][4] = {{0, 0, 0, 0},
2700 {0, 0, 0, 0},
2701 {8.28698e-06, 13.3515, 0, 0},
2702 {0.031189, 4.56933, 0.031189, 4.56933},
2703 {0.395468, 3.77954, 0.190848, 3.41027},
2704 {0.128467, 4.26652, 0.128467, 4.26652},
2705 {0.160979, 4.95095, 0.160979, 4.95095}};
2706
2707 Double_t pxz = vec.momxz;
2708 Int_t endsta = vec.stahit.rbegin()->first;
2709 Double_t p0 = pars[ista][0];
2710 Double_t p1 = pars[ista][1];
2711 if (endsta > ista + 2) {
2712 p0 = pars[ista][2];
2713 p1 = pars[ista][3];
2714 }
2715
2716 Double_t dx = p0 / TMath::Power(TMath::Log10(10 * pxz), p1);
2717 return dx;
2718}
2719
2720// -------------------------------------------------------------------------
2721
2723{
2724 /// Adjust angle phi to be "around" phi0 - to avoid discontinuity around +- Pi
2725
2726 Double_t dPhi = phi0 - phi;
2727 if (TMath::Abs(dPhi) > TMath::Pi())
2728 phi += TMath::Pi() * 2 * TMath::Sign(1., dPhi);
2729 return phi;
2730}
2731
2732// -------------------------------------------------------------------------
2733// AZ-280722 Double_t BmnStsVectorFinderV9::LinearFit(CbmStsTrack *tr, Int_t newtr, Double_t& ty)
2735 candvec& cand2,
2736 CbmStsTrack* tr,
2737 Int_t newtr,
2738 Double_t& ty) // AZ-280722
2739{
2740 /// Linear LS fit of 3 points (in R-Y plane): y = a + b * l, l is a track projection length on X-Z plane
2741
2742 // static Double_t x[3], y[3], z[3], xs[3], ys[3], xys[3], x2s[3];
2743 static Double_t /*x[3],*/ y[3], /*z[3],*/ l[3] = {0}, lens[3] = {0}, ys[3], lys[3], l2s[3];
2744
2745 // AZ-150722 Int_t i0 = (newtr == 1) ? 0 : 2;
2746 Int_t i0 = (newtr == 0) ? 0 : 2;
2747
2748 for (Int_t i = i0; i < 3; ++i) {
2749 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(tr->GetStsHitIndex(i));
2750 // AZ-280722 x[i] = hit->GetX();
2751 // AZ-280722 z[i] = hit->GetZ();
2752 if (i) {
2753 /*AZ-280722
2754 Double_t dx = x[i] - x[i-1];
2755 Double_t dz = z[i] - z[i-1];
2756 l[i] = lens[i] = TMath::Sqrt (dx * dx + dz * dz) + l[i-1];
2757 */
2758 if (i == 1)
2759 l[i] = lens[i] = cand.lengxz; // AZ-280722
2760 else
2761 l[i] = lens[i] = cand2.lengxz + l[i - 1]; // AZ-280722
2762 }
2763 y[i] = ys[i] = hit->GetY();
2764 // cout << " ily " << i << " " << l[i] << " " << y[i] << endl;
2765 }
2766
2767 for (Int_t i = i0; i < 3; ++i) {
2768 lys[i] = l[i] * y[i];
2769 l2s[i] = l[i] * l[i];
2770 if (i) {
2771 lens[i] += lens[i - 1];
2772 ys[i] += ys[i - 1];
2773 lys[i] += lys[i - 1];
2774 l2s[i] += l2s[i - 1];
2775 }
2776 }
2777 Double_t b = 3 * lys[2] - lens[2] * ys[2];
2778 b /= (3 * l2s[2] - lens[2] * lens[2]);
2779 Double_t a = (ys[2] - b * lens[2]) / 3;
2780
2781 Double_t chi2 = 0.0;
2782
2783 for (int i = 0; i < 3; ++i) {
2784 Double_t dy = a + b * l[i] - y[i];
2785 chi2 += (dy * dy);
2786 }
2787 // Check
2788 // TGraph gr(3,l,y);
2789 // gr.Fit("pol1");
2790 // cout << " LS fit: " << a << " " << b << " " << chi2 << endl;
2791 ty = b;
2792 return chi2;
2793}
2794
2795// -------------------------------------------------------------------------
2796
2798{
2799 // Compute triplet curvature in ZX plane
2800
2801 static TVector3 points3[3], midPoint;
2802 int indx = 1;
2803 static Double_t by = 0.0;
2804 // static int first = 99;
2805
2806 // if (first != fPass) {
2807 // first = fPass;
2808 // AZ-270625 if (first) {
2809 // if (cand3.stahit.size() <= 2 && first) { // AZ-270625 - for doublets
2810 if (cand3.stahit.size() <= 2) { // AZ-270625 - for doublets
2811 // first = 0;
2812 points3[0].SetXYZ(fXyzv[0], fXyzv[1], fXyzv[2]);
2813 }
2814
2815 map<int, int>::iterator mit = cand3.stahit.begin();
2816 if (0) { // fPass > 1) { //0 - assuming tracks coming from (0,0,0)
2817 // if (newtr == 0 && cand3.stahit.size() > 2) {
2818 points3[0] = fmapHits[mit->second].xyz; // AZ-280722
2819 points3[0].SetY(0.0); // AZ-280722
2820 }
2821 // AZ-310722 ++mit;
2822 // AZ-270625 if (cand3.stahit.size() > 2) ++mit; //AZ-310722
2823 if (cand3.stahit.size() > 2) {
2824 indx = 0;
2825 // first = 99;
2826 } // AZ-270625
2827
2828 for (; mit != cand3.stahit.end(); ++mit) {
2829 // if (newtr > 0 && indx < 2) { ++indx; continue; }
2830 points3[indx] = fmapHits[mit->second].xyz;
2831 if (indx == 1)
2832 midPoint = points3[indx];
2833 // AZ-270625 points3[indx] -= points3[0];
2834 if (indx)
2835 points3[indx] -= points3[0]; // AZ-270625
2836 points3[indx++].SetY(0.0);
2837 }
2838
2839 TVector3 vec21 = points3[2] - points3[1];
2840 // AZ-280722 Double_t cosAlpha = points3[2] * vec21 / points3[2].Mag() / vec21.Mag();
2841 // Double_t cosAlpha = points3[1] * vec21 / points3[1].Mag() / vec21.Mag(); //AZ-280722
2842 Double_t cosAlpha = points3[1] * vec21 / points3[1].Mag() / cand2.lengxz; // AZ-280722
2843 // AZ-280722 Double_t rad = points3[1].Mag() / 2. / TMath::Sin(TMath::ACos(cosAlpha));
2844 Double_t rad = points3[2].Mag() / 2. / TMath::Sin(TMath::ACos(cosAlpha)); // AZ-280722
2845 // Double_t bz = FairRunAna::Instance()->GetField()->GetBz(0.,0.,0.);
2846 // Double_t factor = 0.003 * bz / 10.; // 0.3 * 0.01 * 5kG / 10
2847 // AZ-310722 Double_t sign = TMath::Sign (1.0, points3[1].Cross(points3[2]).Y());
2848 Double_t sign = TMath::Sign(3e-4, points3[1].Cross(points3[2]).Y()); // AZ-310722
2849 if (newtr == 0) {
2850 FairField* magField = FairRunAna::Instance()->GetField();
2851 by = magField->GetBy(midPoint[0], midPoint[1], midPoint[2]);
2852 if (TMath::Abs(by) < 0.1)
2853 by = -10.0; // AZ-261222 - zero magnetic field
2854 }
2855 // AZ-270625 Double_t pxz = by * rad * sign;
2856 Double_t pxz = -by * rad * sign;
2857 // cout << " pt " << pxz << endl;
2858 // AZ-170722 return pxz;
2859 return 1 / pxz; // AZ-170722
2860}
2861// -------------------------------------------------------------------------
2862
2864{
2865 // Find hits around extrapolated track
2866
2867 CbmStsTrack track;
2868 string hitcode;
2869 MakeStsTrack(cand, hitcode, track);
2870 fitter.DoFit(&track);
2871 FairTrackParam param;
2872 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(hitIndx);
2873 Double_t z = hit->GetZ();
2874 fitter.Extrapolate(&track, z, &param);
2875 Double_t sigx = 5 * TMath::Sqrt(param.GetCovariance(0, 0));
2876 Double_t sigy = 5 * TMath::Sqrt(param.GetCovariance(1, 1));
2877 if (fVerbose > 0)
2878 cout << " Kalman: " << z << " " << hit->GetStationNr() << " " << sigx << " " << sigy << endl;
2879
2880 // Get hits on the downstream station
2881 int istanext = hit->GetStationNr() - 1;
2882 multimap<Double_t, Int_t>::iterator mityb = fmapY[istanext].lower_bound(param.GetY() - sigy);
2883 multimap<Double_t, Int_t>::iterator mitye = fmapY[istanext].upper_bound(param.GetY() + sigy);
2884 multimap<Double_t, Int_t>::iterator mitxb = fmapX[istanext].lower_bound(param.GetX() - sigx);
2885 multimap<Double_t, Int_t>::iterator mitxe = fmapX[istanext].upper_bound(param.GetX() + sigx);
2886 // Get hits from the acceptance window
2887 set<Int_t> setX, setY, intersect;
2888 for (multimap<Double_t, Int_t>::iterator mit = mitxb; mit != mitxe; ++mit)
2889 if (fmapHits[mit->second].used == 0)
2890 setX.insert(mit->second);
2891 for (multimap<Double_t, Int_t>::iterator mit = mityb; mit != mitye; ++mit)
2892 if (fmapHits[mit->second].used == 0)
2893 setY.insert(mit->second);
2894 set_intersection(setX.begin(), setX.end(), setY.begin(), setY.end(), std::inserter(intersect, intersect.begin()));
2895 return intersect;
2896}
2897
2898// -------------------------------------------------------------------------
2899
2901{
2902 // Make track code
2903
2904 string code("-");
2905 for (map<int, int>::iterator it = cand.stahit.begin(); it != cand.stahit.end(); ++it)
2906 code += (to_string(it->second) + "-");
2907 return code;
2908}
2909
2910// -------------------------------------------------------------------------
2911
2913{
2914 // Print hits
2915
2916 for (map<int, int>::iterator mit = cand.stahit.begin(); mit != cand.stahit.end(); ++mit) {
2917 int ista = mit->first, ih = mit->second;
2918 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(ih);
2919 // cout << mit->first << "(" << hit->GetZ() << "):" << mit->second << " - ";
2920 printf("%d(%5.2f,%5.2f,%5.2f):%d", ista, hit->GetZ(), fmapHits[ih].tx, fmapHits[ih].ty, ih);
2921 auto ret = fHit2id.equal_range(ih);
2922 for (unordered_multimap<Int_t, Int_t>::iterator mit1 = ret.first; mit1 != ret.second; ++mit1) {
2923 if (mit1 == ret.first)
2924 cout << "*";
2925 else
2926 cout << ":";
2927 cout << mit1->second;
2928 }
2929 cout << " - ";
2930 }
2931 cout << endl;
2932}
2933
2934// -------------------------------------------------------------------------
2935
2937{
2938 // Initialize TMVA package for triplets - AZ-300922
2939
2940 // This loads the library
2941 // TMVA::Tools::Instance();
2942
2943 // Default MVA methods to be trained + tested
2944 std::map<std::string, int> Use;
2945
2946 // Use["MLPBNN"] = 1; // Recommended ANN with BFGS training method and bayesian regulator
2947 Use["BDTD"] = 1; // decorrelation + Adaptive Boost
2948 Float_t* var = fVarTMVA;
2949
2950 fReadersTMVA3.insert(pair<int, TMVA::Reader*>(-13, nullptr)); // pass3 for negative
2951 fReadersTMVA3.insert(pair<int, TMVA::Reader*>(-11, nullptr));
2952 fReadersTMVA3.insert(pair<int, TMVA::Reader*>(-10, nullptr));
2953 fReadersTMVA3.insert(pair<int, TMVA::Reader*>(10, nullptr));
2954 fReadersTMVA3.insert(pair<int, TMVA::Reader*>(11, nullptr));
2955 fReadersTMVA3.insert(pair<int, TMVA::Reader*>(13, nullptr));
2956
2957 // --- Create the Reader objects
2958
2959 for (auto mit = fReadersTMVA3.begin(); mit != fReadersTMVA3.end(); ++mit) {
2960 TMVA::Reader* reader = new TMVA::Reader("!Color:!Silent");
2961 fReadersTMVA3[mit->first] = reader;
2962
2963 // Create a set of variables and declare them to the reader
2964 // The variable names MUST corresponds in name and type to those given in the weight file(s) used
2965
2966 // FIXME
2967 int iii = 0;
2968
2969 reader->AddVariable("tanx", &var[iii++]);
2970 reader->AddVariable("tany", &var[iii++]);
2971 reader->AddVariable("zb", &var[iii++]);
2972 reader->AddVariable("dty", &var[iii++]);
2973 // reader->AddVariable( "1/pxz1", &var[iii++] );
2974 // reader->AddVariable( "log(abs(pxz1))", &var[iii++] );
2975 reader->AddVariable("log(abs(pxz2))", &var[iii++]);
2976 reader->AddVariable("dpxz", &var[iii++]);
2977 reader->AddVariable("corrq[0]", &var[iii++]);
2978 reader->AddVariable("corrq[1]", &var[iii++]);
2979 reader->AddVariable("corrq[2]", &var[iii++]);
2980 // reader->AddVariable( "log(mult+rndm)", &var[iii++] );
2981 reader->AddVariable("log(mult)", &var[iii++]);
2982
2983 // --- Book the MVA methods
2984
2985 TString dir = "datasetTMVA3/weights";
2986 dir += mit->first;
2987 dir += "/";
2988 TString prefix = "TMVAClassification";
2989
2990 // Book method(s)
2991 for (std::map<std::string, int>::iterator it = Use.begin(); it != Use.end(); it++) {
2992 if (it->second) {
2993 TString methodName = TString(it->first) + TString(" method");
2994 TString weightfile = dir + prefix + TString("_") + TString(it->first) + TString(".weights.xml");
2995 reader->BookMVA(methodName, weightfile);
2996 }
2997 }
2998 } // for (auto mit = fReadersTMVA3.begin();
2999}
3000
3001// -------------------------------------------------------------------------
3002
3004{
3005 // Compute TMVA output for triplets: aaa1 - triplet, aaa2 - first doublet
3006
3007 Float_t* var = fVarTMVA;
3008 map<Int_t, Int_t>& hitMap = aaa1.stahit;
3009 CbmStsHit* hit[3] = {nullptr};
3010 int iii = 0, indx = 0, inds[3];
3011 inds[0] = inds[1] = inds[2] = 0;
3012
3013 /// hitMap ---- aaa.stahit
3014 for (map<Int_t, Int_t>::iterator mit = hitMap.begin(); mit != hitMap.end(); ++mit) {
3015 inds[indx] = mit->second;
3016 hit[indx++] = (CbmStsHit*)fHitArray->UncheckedAt(mit->second);
3017 }
3018
3019 Double_t dx = hit[1]->GetX() - hit[0]->GetX();
3020 Double_t dz = hit[1]->GetZ() - hit[0]->GetZ();
3021 Double_t lenxz1 = TMath::Sqrt(dx * dx + dz * dz);
3022 Double_t dx1 = hit[2]->GetX() - hit[1]->GetX();
3023 Double_t dz1 = hit[2]->GetZ() - hit[1]->GetZ();
3024 Double_t lenxz2 = TMath::Sqrt(dx1 * dx1 + dz1 * dz1);
3025 Double_t dty = (hit[2]->GetY() - hit[1]->GetY()) / lenxz2 - (hit[1]->GetY() - hit[0]->GetY()) / lenxz1;
3026 Double_t pxz1 = aaa1.momxz; // triplet curvature
3027 Double_t dpxz = (aaa2.momxz - pxz1) / (TMath::Abs(aaa2.momxz) + TMath::Abs(pxz1));
3028
3029 var[iii++] = hit[0]->GetX() / hit[0]->GetZ();
3030 var[iii++] = hit[0]->GetY() / hit[0]->GetZ();
3031 var[iii++] = hit[0]->GetZ();
3032 var[iii++] = dty;
3033 // var[iii++] = pxz1;
3034 var[iii++] = TMath::Log(TMath::Abs(1 / pxz1));
3035 var[iii++] = dpxz;
3036 var[iii++] = hit[0]->GetSignalDiv();
3037 var[iii++] = hit[1]->GetSignalDiv();
3038 var[iii++] = hit[2]->GetSignalDiv();
3039 var[iii++] = TMath::Log(mult);
3040
3041 int iread = (fPass == 2) ? 1 : fPass; // fPass==2 has the same triplet cuts as fPass==1
3042 iread += 10;
3043 if (pxz1 < 0)
3044 iread = -iread;
3045 Float_t tmvaout = fReadersTMVA3[iread]->EvaluateMVA("BDTD method");
3046 /*
3047 if (fOutf) {
3048 for (int j = 0; j < iii; ++j) *fOutf << var[j] << " ";
3049 *fOutf << mult << " " << tmvaout << " " << iread << " " << inds[0] << " " << inds[1] << " "
3050 << inds[2] << " " << fEvNo << endl;
3051 }
3052 */
3053 return tmvaout;
3054}
3055
3056// -------------------------------------------------------------------------
3057
3059{
3060 // Initialize TMVA package for doublets - AZ-221022
3061
3062 // This loads the library
3063 // TMVA::Tools::Instance();
3064
3065 // Default MVA methods to be trained + tested
3066 std::map<std::string, int> Use;
3067
3068 Use["MLPBNN"] = 1; // Recommended ANN with BFGS training method and bayesian regulator
3069 Use["BDTD"] = 1; // decorrelation + Adaptive Boost
3070
3071 // --- Create the Reader object
3072
3073 TMVA::Reader* reader = new TMVA::Reader("!Color:!Silent");
3074 fReaderTMVA2 = reader;
3075
3076 // Create a set of variables and declare them to the reader
3077 // The variable names MUST corresponds in name and type to those given in the weight file(s) used
3078
3079 // FIXME
3080 Float_t* var = fVarTMVA;
3081 int iii = 0;
3082 reader->AddVariable("xb", &var[iii++]);
3083 reader->AddVariable("yb", &var[iii++]);
3084 reader->AddVariable("zb", &var[iii++]);
3085 reader->AddVariable("tx", &var[iii++]);
3086 reader->AddVariable("ty", &var[iii++]);
3087 // reader->AddVariable( "dphixsc", &var[iii++] );
3088 reader->AddVariable("dtanysc", &var[iii++]);
3089 reader->AddVariable("lenxz", &var[iii++]);
3090 reader->AddVariable("1/pxz", &var[iii++]);
3091 reader->AddVariable("corrq[1]-corrq[0]", &var[iii++]);
3092 reader->AddVariable("corrn[1]-corrn[0]", &var[iii++]);
3093 reader->AddVariable("pass", &var[iii++]);
3094
3095 // --- Book the MVA methods
3096
3097 TString dir = "dataset4diff/weights2/";
3098 TString prefix = "TMVAClassification";
3099
3100 // Book method(s)
3101 for (std::map<std::string, int>::iterator it = Use.begin(); it != Use.end(); it++) {
3102 if (it->second) {
3103 TString methodName = TString(it->first) + TString(" method");
3104 TString weightfile = dir + prefix + TString("_") + TString(it->first) + TString(".weights.xml");
3105 reader->BookMVA(methodName, weightfile);
3106 }
3107 }
3108}
3109
3110// -------------------------------------------------------------------------
3111
3113{
3114 // Compute TMVA output for doublets
3115
3116 Float_t* var = fVarTMVA;
3117 map<Int_t, Int_t>& hitMap = aaa1.stahit;
3118 CbmStsHit *hit = nullptr, *hit1 = nullptr;
3119 int iii = 0, indx = 0;
3120
3121 /// hitMap ---- aaa.stahit
3122 for (map<Int_t, Int_t>::iterator mit = hitMap.begin(); mit != hitMap.end(); ++mit) {
3123 hit = (CbmStsHit*)fHitArray->UncheckedAt(mit->second);
3124 if (indx == 0) {
3125 var[iii++] = hit->GetX();
3126 var[iii++] = hit->GetY();
3127 var[iii++] = hit->GetZ();
3128 hit1 = hit;
3129 } else if (indx == 1) {
3130 Double_t dx = hit->GetX() - var[0];
3131 Double_t dy = hit->GetY() - var[1];
3132 Double_t dz = hit->GetZ() - var[2];
3133 var[iii++] = dx / dz;
3134 var[iii++] = dy / dz;
3135 var[iii++] = aaa1.ty;
3136 var[iii++] = aaa1.lengxz;
3137 var[iii++] = aaa1.momxz;
3138 var[iii++] = hit->GetSignalDiv() - hit1->GetSignalDiv();
3139 var[iii++] = hit->GetTimeStamp() - hit1->GetTimeStamp();
3140 var[iii++] = (fPass == 2) ? 1 : fPass; // fPass==2 has the same triplet cuts as fPass==1
3141 }
3142 ++indx;
3143 }
3144 return fReaderTMVA2->EvaluateMVA("MLPBNN method");
3145}
3146
3147// -------------------------------------------------------------------------
3148
3150{
3151 // Initialize TMVA package for rejecting fake tracks (4- and 5-hits)
3152
3153 // This loads the library
3154 // TMVA::Tools::Instance();
3155
3156 // Default MVA methods to be trained + tested
3157 std::map<std::string, int> Use;
3158
3159 Use["BDTD"] = 1; // decorrelation + Adaptive Boost
3160 Float_t* var = fVarTMVA;
3161 fTmvaReaders.insert(pair<int, TMVA::Reader*>(-5, nullptr));
3162 fTmvaReaders.insert(pair<int, TMVA::Reader*>(-4, nullptr));
3163 fTmvaReaders.insert(pair<int, TMVA::Reader*>(4, nullptr));
3164 fTmvaReaders.insert(pair<int, TMVA::Reader*>(5, nullptr));
3165
3166 // --- Create the Reader objects
3167
3168 for (auto mit = fTmvaReaders.begin(); mit != fTmvaReaders.end(); ++mit) {
3169 TMVA::Reader* reader = new TMVA::Reader("!Color:!Silent");
3170 int nhits = mit->first;
3171 fTmvaReaders[nhits] = reader;
3172
3173 // Create a set of variables and declare them to the reader
3174 // The variable names MUST corresponds in name and type to those given in the weight file(s) used
3175
3176 // FIXME
3177 int iii = 0;
3178 // reader->AddVariable( "sqrt(xb*xb+yb*yb)", &var[iii++] );
3179 reader->AddVariable("atan2(yb,xb)", &var[iii++]);
3180 // reader->AddVariable( "zb", &var[iii++] );
3181 reader->AddVariable("tx", &var[iii++]);
3182 // reader->AddVariable( "ty", &var[iii++] );
3183 reader->AddVariable("log(abs(momr))", &var[iii++]);
3184 reader->AddVariable("chi2", &var[iii++]);
3185 // reader->AddVariable( "log(sqrt(xextr*xextr+yextr*yextr))", &var[iii++] );
3186 // reader->AddVariable( "atan2(yextr,xextr)", &var[iii++] );
3187 reader->AddVariable("corrq[0]", &var[iii++]);
3188 reader->AddVariable("corrq[1]", &var[iii++]);
3189 reader->AddVariable("corrq[2]", &var[iii++]);
3190 reader->AddVariable("corrq[3]", &var[iii++]);
3191 if (TMath::Abs(nhits) == 5)
3192 reader->AddVariable("corrq[4]", &var[iii++]);
3193 reader->AddVariable("corrq3", &var[iii++]);
3194 // reader->AddVariable( "nmiss+rndm", &var[iii++] );
3195 reader->AddVariable("nseqmx", &var[iii++]);
3196 // reader->AddVariable( "leng", &var[iii++] );
3197 reader->AddVariable("corrn[0]", &var[iii++]);
3198 reader->AddVariable("corrn[1]", &var[iii++]);
3199 reader->AddVariable("corrn[2]", &var[iii++]);
3200 reader->AddVariable("corrn[3]", &var[iii++]);
3201 if (TMath::Abs(nhits) == 5)
3202 reader->AddVariable("corrn[4]", &var[iii++]);
3203 reader->AddVariable("nsigem", &var[iii++]);
3204
3205 // --- Book the MVA methods
3206
3207 TString dir = gSystem->Getenv("VMCWORKDIR");
3208 // TString dir = "datasetTMVA1/weights";
3209 dir += "/parameters/reco/datasetTMVAV8/weights";
3210 // dir += nhits;
3211 dir += (nhits < 10) ? TMath::Abs(nhits) : nhits / 10;
3212 if (nhits < 0)
3213 dir += "neg";
3214 else
3215 dir += "pos";
3216 dir += "/";
3217 TString prefix = "TMVAClassification";
3218
3219 // Book method(s)
3220 for (std::map<std::string, int>::iterator it = Use.begin(); it != Use.end(); it++) {
3221 if (it->second) {
3222 TString methodName = TString(it->first) + TString(" method");
3223 TString weightfile = dir + prefix + TString("_") + TString(it->first) + TString(".weights.xml");
3224 reader->BookMVA(methodName, weightfile);
3225 }
3226 }
3227 } // for (auto mit = fTmvaReaders.begin();
3228}
3229
3230// -------------------------------------------------------------------------
3231
3233{
3234 // Compute TMVA output for tracks
3235
3236 // Fill cluster overlap map
3237 map<Int_t, set<Int_t>> mClusTr;
3238 int nTracks = fVectorArray->GetEntriesFast();
3239
3240 for (int itr = 0; itr < nTracks; ++itr) {
3241 CbmStsTrack* tr = (CbmStsTrack*)fVectorArray->UncheckedAt(itr);
3242 int nhit = tr->GetNStsHits();
3243 if (nhit < 4)
3244 continue; // exclude 3-hit tracks
3245
3246 for (int ih = 0; ih < nhit; ++ih) {
3247 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(tr->GetStsHitIndex(ih));
3248 // Check clusters
3249
3250 for (Int_t side = 0; side < 2; ++side) {
3251 Int_t iclus = hit->GetDigi(side);
3252 if (mClusTr.count(iclus) == 0) {
3253 set<Int_t> aaa;
3254 mClusTr[iclus] = aaa;
3255 }
3256 mClusTr[iclus].insert(itr);
3257 }
3258 }
3259 } // for (int itr = 0; itr < ntracks;
3260
3261 Float_t* var = fVarTMVA;
3262
3263 for (int itr = 0; itr < nTracks; ++itr) {
3264 CbmStsTrack* track = (CbmStsTrack*)fVectorArray->UncheckedAt(itr);
3265 int nhit = track->GetNStsHits();
3266 // if (nhit < 4 || nhit > 5) return 1.0;
3267 if (nhit < 4 || nhit > 5) {
3268 track->SetB(1.0);
3269 continue;
3270 }
3271 const FairTrackParam* param = track->GetParamFirst();
3272 Float_t momr = 1. / param->GetQp();
3273 int iq = (momr >= 0) ? 1 : -1;
3274 TVector3 posb, pose, mom3;
3275 Float_t corrq[19], corrn[19] = {0}, corrn3 = 0, corrq3 = 0;
3276 int nmiss = 0, ista0 = -1, nsigem = 0, nseqmx = 1, nseq = 1;
3277
3278 for (int ih = 0; ih < nhit; ++ih) {
3279 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(track->GetStsHitIndex(ih));
3280 Int_t ista = hit->GetStationNr() - 1;
3281 if (ih == 0) {
3282 hit->Position(posb);
3283 ista0 = ista;
3284 } else {
3285 if (ista - ista0 > 1) {
3286 ++nmiss;
3287 nseqmx = TMath::Max(nseqmx, nseq);
3288 nseq = 1;
3289 } else
3290 ++nseq;
3291 if (ih == nhit - 1)
3292 hit->Position(pose);
3293 }
3294 corrq[ih] = hit->GetSignalDiv();
3295 corrq3 += TMath::Abs(corrq[ih]);
3296 ista0 = ista;
3297
3298 for (Int_t side = 0; side < 2; ++side) {
3299 Int_t iclus = hit->GetDigi(side);
3300 int over = mClusTr[iclus].size();
3301 corrn[ih] += (over - 1);
3302 }
3303 corrn3 += corrn[ih];
3304 if (ista < 4)
3305 nsigem += 10;
3306 else
3307 nsigem += 1;
3308 } // for (int ih = 0; ih < nhit;
3309
3310 nseqmx = TMath::Max(nseqmx, nseq);
3311 pose -= posb;
3312 // Float_t leng = pose.Mag() / (nhit-1);
3313
3314 // Extrapolate track to the target
3315 CbmKFTrack trKF = CbmKFTrack(*track);
3316 FairTrackParam par;
3317 // track.Extrapolate(xyzv[2]);
3318 trKF.Extrapolate(0.0);
3319 trKF.GetTrackParam(par);
3320 par.Momentum(mom3);
3321 momr = TMath::Sqrt(mom3.X() * mom3.X() + mom3.Z() * mom3.Z());
3322 par.Position(mom3);
3323
3324 int iii = 0;
3325 // var[iii++] = TMath::Sqrt (xb*xb+yb*yb);
3326 // var[iii++] = posb.Pt();
3327 // var[iii++] = TMath::ATan2 (yb, xb);
3328 var[iii++] = posb.Phi();
3329 // var[iii++] = zb;
3330 // var[iii++] = posb.Z();
3331 var[iii++] = param->GetTx();
3332 var[iii++] = TMath::Log(TMath::Abs(momr));
3333 var[iii++] = track->GetChi2() / track->GetNDF();
3334 // var[iii++] = TMath::Log (TMath::Sqrt (xextr*xextr+yextr*yextr));
3335 // var[iii++] = TMath::ATan2 (yextr, xextr);
3336 // var[iii++] = TMath::Log (mom3.Pt());
3337 // var[iii++] = mom3.Phi();
3338 var[iii++] = corrq[0];
3339 var[iii++] = corrq[1];
3340 var[iii++] = corrq[2];
3341 var[iii++] = corrq[3];
3342 if (nhit == 5)
3343 var[iii++] = corrq[4];
3344 var[iii++] = corrq3;
3345 // var[iii++] = nmiss + gRandom->Rndm();
3346 var[iii++] = nseqmx;
3347 // var[iii++] = leng;
3348 // var[iii++] = corrn3;
3349 var[iii++] = corrn[0];
3350 var[iii++] = corrn[1];
3351 var[iii++] = corrn[2];
3352 var[iii++] = corrn[3];
3353 if (nhit == 5)
3354 var[iii++] = corrn[4];
3355 var[iii++] = nsigem;
3356
3357 // return fTmvaReaders[nhit*iq]->EvaluateMVA("BDTD method");
3358 track->SetB(fTmvaReaders[nhit * iq]->EvaluateMVA("BDTD method"));
3359 } // for (int itr = 0; itr < nTracks;
3360}
3361
3362// -------------------------------------------------------------------------
3363
3365{
3366 // Evaluate vertex coordinates
3367
3368 int ntracks = fVectorArray->GetEntriesFast();
3369 Double_t xv = 0, yv = 0, wwwxtot = 0, wwwytot = 0;
3370
3371 for (int itr = 0; itr < ntracks; ++itr) {
3372 CbmStsTrack* tr = (CbmStsTrack*)fVectorArray->UncheckedAt(itr);
3373 FairTrackParam param = *(tr->GetParamFirst());
3374 fitter.Extrapolate(&param, fXyzv[2], &param);
3375 // Double_t wwwx = 1 / TMath::Sqrt(param.GetCovariance(0,0));
3376 // Double_t wwwy = 1 / TMath::Sqrt(param.GetCovariance(1,1));
3377 Double_t wwwx = 1 / param.GetCovariance(0, 0);
3378 Double_t wwwy = 1 / param.GetCovariance(1, 1);
3379 xv += (param.GetX() * wwwx);
3380 yv += (param.GetY() * wwwy);
3381 wwwxtot += wwwx;
3382 wwwytot += wwwy;
3383 // cout << itr << " " << tr->GetNStsHits() << " " << param.GetX() << " " <<
3384 // TMath::Sqrt(param.GetCovariance(0,0)) << " "
3385 // << param.GetY() << " " << TMath::Sqrt(param.GetCovariance(1,1)) << " " << tr->GetParamFirst()->GetZ() <<
3386 // endl;
3387 }
3388 cout << " Vertex coords: " << fEvent << " " << fPass << " " << xv / wwwxtot << " " << yv / wwwytot << endl;
3389}
3390
3391// -------------------------------------------------------------------------
3392// AZ-220626
3393
3395{
3396 // Kill hits on tracks in momentum space
3397
3398 if (fHitConverter == nullptr) {
3399 fHitConverter = (BmnToCbmHitConverter*)FairRun::Instance()->GetTask("BMN to CBM Hits Converter");
3400 BmnStsVectorFinderV9* vf = (BmnStsVectorFinderV9*)FairRun::Instance()->GetTask("STS Vector Finder V9");
3401 // BmnStsVectorFinderV9 *vf = (BmnStsVectorFinderV9*) FairRun::Instance()->GetTask ("aaabbbccc");
3403 }
3404
3405 int ntracks = fTracksToKill->GetEntriesFast(), nhits0 = fHitArray->GetEntriesFast(), nkilled = 0;
3406 FairTrackParam param;
3407 cout << " Initial ntracks: " << ntracks << endl;
3408
3409 for (int itr = 0; itr < ntracks; ++itr) {
3410 CbmStsTrack* tr = (CbmStsTrack*)fTracksToKill->UncheckedAt(itr);
3411 CbmKFTrack kftr = CbmKFTrack(*tr, kTRUE);
3412 kftr.Extrapolate(0.0); // extrapolate to the target
3413 kftr.GetTrackParam(param);
3414 Double_t tx = param.GetTx();
3415 Double_t ty = param.GetTy();
3416 Double_t pmom = 1 / param.GetQp();
3417 int iq = (pmom >= 0) ? 1 : -1;
3418 int nhits = tr->GetNStsHits();
3419
3420 for (int ih = 0; ih < nhits; ++ih) {
3421 int ihh = tr->GetStsHitIndex(ih);
3422 CbmStsHit* hit = (CbmStsHit*)fHitArray->UncheckedAt(ihh);
3423 if (hit == nullptr)
3424 continue;
3425 Bool_t ok = fHitConverter->CorrectEffic(hit, iq, tx, ty, TMath::Abs(pmom), 1);
3426 // if (!ok) fHitArray->RemoveAt (ihh);
3427 if (!ok) {
3428 hit->SetUniqueID(999); // exclude hit from tracking
3429 ++nkilled;
3430 }
3431 }
3432 }
3433 fHitArray->Compress();
3434 cout << " !!! Hits: " << nhits0 << " " << fHitArray->GetEntriesFast() << " " << nkilled << endl;
3435}
3436
3437// -------------------------------------------------------------------------
3438
vector< Double_t > dist(vector< Double_t > qp, Double_t mu)
Definition BmnMath.cxx:869
static Double_t workTime
int i
Definition P4_F32vec4.h:22
bool Bool_t
int Int_t
float Float_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
#define ClassImp(name)
void Fatal(const char *location, const char *msgfmt,...)
TGLVector3 Cross(const TGLVector3 &v1, const TGLVector3 &v2)
R__EXTERN TSystem * gSystem
@ kGEM
@ kVSP
Bool_t IsPointInsideModule(Double_t x, Double_t y)
BmnGemStripModule * GetModule(Int_t module_num)
Bool_t IsPointInsideModule(Double_t x, Double_t y)
BmnSiliconModule * GetModule(Int_t module_num)
std::set< string > fCandCodes[19]
virtual InitStatus Init()
Virtual method Init.
std::unordered_multimap< int, int > fMap3[19]
Double_t Curv3(candvec &cand1, candvec &cand2, candvec &cand3, int newtr3)
std::unordered_multimap< int, int > fTxBins[19]
void ReadTxInfo(TString fileName)
std::unordered_multimap< Int_t, Int_t > fHit2id
vector< Double_t > fPTcut
vector< Double_t > fCurvSta
std::multimap< Double_t, Int_t > fmapTx[19]
Float_t TMVAOutput3(candvec &aaa1, candvec &aaa2, int mult2)
std::set< Int_t > GetHitIdBmn(CbmStsHit *hit, Int_t &idmaxP)
virtual void Finish()
Virtual method Finish.
vector< Double_t > fPhiXZ
vector< Double_t > fdTanX
std::multimap< Double_t, Int_t > fmapX[19]
std::unordered_map< Int_t, hitinfo > fmapHits
std::set< int > KalmanWindow(candvec &cand, int hitIndx)
std::set< Int_t > GetHitId(CbmStsHit *hit, Int_t &idmaxP)
std::vector< candvec > fCandVec2[19]
vector< Double_t > fZmean
void DTxWindow(int ista2, Float_t tx, int idu, Float_t curvCut, Float_t *dtx)
Int_t ExcludeHits(Int_t minHits, TClonesArray *trArray)
TClonesArray * GetVectorArray()
std::unordered_map< int, std::unordered_map< int, std::vector< Float_t > > > fStatData
Double_t Proxim(Double_t ang1, Double_t ang2)
vector< Double_t > fTanXmax
void MakeStsTrack(candvec &cand, std::string &hitcode, CbmStsTrack &track)
std::map< int, TMVA::Reader * > fTmvaReaders
std::vector< candvec > fCandVec[19]
BmnToCbmHitConverter * fHitConverter
std::vector< candvec > fSeedVec[19]
void SetTracksToKill(TClonesArray *tracks)
Double_t LinearFit(candvec &cand, candvec &cand2, CbmStsTrack *tr, Int_t newtr, Double_t &ty)
Double_t FitTrack(candvec &cand)
std::multimap< Double_t, Int_t > fmapY[19]
BmnStsKFTrackFitter fitter
std::unordered_multimap< Int_t, Int_t > fClusMaps[2]
Double_t FilterHit(candvec &cand, CbmStsTrack &track)
std::string MakeCode(candvec &cand)
std::map< int, TMVA::Reader * > fReadersTMVA3
std::unordered_map< std::string, int > fMap2Out
std::unordered_map< std::string, int > fMap3Out
Float_t BinCenterTx(int ista, int ibin, Float_t binw)
virtual void FinishEvent()
Virtual method FinishEvent.
BmnGemStripStationSet * fGemStationSet
vector< Double_t > fdTanXB0
int FindBin(int ista, Float_t binw, Float_t tx)
Float_t TMVAOutput2(candvec &aaa1)
vector< Double_t > fdTanY
std::multimap< Double_t, CbmStsTrack > fTracks
vector< Double_t > fdTanY3
std::unordered_map< std::string, int > fMapCode3[19]
Double_t DxVsMom(Int_t ista, candvec &aaa)
void PrintHits(candvec &cand)
std::multimap< Double_t, Int_t > fmapTy[19]
TClonesArray * fClusArray[4]
Input / output array of CbmStsHits.
std::unordered_multimap< int, int > fMap2[19]
Bool_t AreTracksDoubles(CbmStsTrack &tr1, CbmStsTrack &tr2)
BmnStsVectorFinderV9()
Default constructor.
std::set< string > fCandSet[19]
Bool_t CheckVarx(Double_t dx, Double_t dz, Double_t tx, Double_t distxz, Double_t &varx)
TVector3 Parabola(TVector3 &pos0, TVector3 &pos1, TVector3 &pos2, int ix=0)
BmnSiliconStationSet * fSilStationSet
Entire GEM detector.
virtual void Exec(Option_t *opt)
Virtual method Exec.
std::vector< candvec > fCandVec3[19]
Abstract base class for hit is being used by the CbmKF Kalman Filter.
Definition CbmKFHit.h:17
virtual Int_t Filter(CbmKFTrackInterface &track, Bool_t downstream, Double_t &QP0)=0
Int_t Extrapolate(Double_t z, Double_t *QP0=0, Bool_t line=false)
Access to i-th hit.
void SetStsTrack(CbmStsTrack &track, bool first=1)
CbmKFHit * GetHit(Int_t i)
Number of hits.
Definition CbmKFTrack.h:81
void GetTrackParam(FairTrackParam &track)
Double_t & GetRefChi2()
array[15] of covariance matrix
Definition CbmKFTrack.h:76
static CbmKF * Instance()
Definition CbmKF.h:34
int GetNStsStations() const
Definition CbmKF.h:87
CbmStsCluster.h.
Int_t GetNDigis() const
Int_t GetDigi(Int_t inum)
CbmStsDigiMatch.h.
Int_t GetRefIndex(Int_t i=0) const
Accessor to StsPoint indizes.
static CbmStsDigiScheme * Instance(int version=1)
CbmStsStation * GetStationByNr(Int_t stationNr)
Station by index.
virtual Int_t GetStationNr() const
Definition CbmStsHit.h:67
Double_t GetSignalDiv() const
Definition CbmStsHit.h:78
Int_t GetSystemId() const
Accessors.
Definition CbmStsHit.h:66
Int_t GetDigi(Int_t iSide) const
Double_t GetDx() const
CbmStsSector * GetSector(Int_t iSector)
void SetNDF(Int_t ndf)
Definition CbmStsTrack.h:87
FairTrackParam * GetParamLast()
Definition CbmStsTrack.h:70
void SetParamLast(FairTrackParam &par)
Definition CbmStsTrack.h:84
TArrayI * GetStsHits()
Definition CbmStsTrack.h:71
void SetParamFirst(FairTrackParam &par)
Definition CbmStsTrack.h:83
Int_t GetFlag() const
Definition CbmStsTrack.h:65
void SetChi2(Double_t chi2)
Definition CbmStsTrack.h:86
void SetFlag(Int_t flag)
Definition CbmStsTrack.h:85
Int_t GetNStsHits() const
Accessors.
Definition CbmStsTrack.h:60
Double_t GetChi2() const
Definition CbmStsTrack.h:66
Int_t GetStsHitIndex(Int_t iHit) const
Definition CbmStsTrack.h:62
FairTrackParam * GetParamFirst()
Definition CbmStsTrack.h:69
Int_t GetNDF() const
Definition CbmStsTrack.h:67
void SetB(Double_t b)
Definition CbmStsTrack.h:88
void Set(Int_t n) override
Int_t GetSize() const
void Compress() override
TObject * Remove(TObject *obj) override
IMethod * BookMVA(const TString &methodTag, const TString &weightfile)
void AddVariable(const TString &expression, Float_t *)
Int_t GetEntriesFast() const
void Delete(Option_t *option="") override
TObject * UncheckedAt(Int_t i) const
Double_t RealTime()
void Start(Bool_t reset=kTRUE)
void Stop()
TObjArray * Tokenize(const TString &delim) const
std::istream & ReadLine(std::istream &str, Bool_t skipWhite=kTRUE)
Double_t Z() const
void SetY(Double_t)
void SetXYZ(Double_t x, Double_t y, Double_t z)
Double_t Phi() const
Double_t X() const
Double_t Mag() const
Double_t Min(Double_t a, Double_t b)
Double_t ACos(Double_t)
Double_t Sign(Double_t a, Double_t b)
Double_t Exp(Double_t x)
Double_t ATan2(Double_t y, Double_t x)
Double_t Power(Double_t x, Double_t y)
Double_t Log(Double_t x)
Double_t Sqrt(Double_t x)
constexpr Double_t Pi()
Double_t Abs(Double_t d)
Double_t Sin(Double_t)
Double_t Max(Double_t a, Double_t b)
Double_t Log10(Double_t x)
std::map< Int_t, Int_t > stahit