3 // The format of output data from Neural Tracker
4 // It can export data in the format of AliITSIOTrack
6 // Compatibility adaptation to V2 tracking is on the way.
7 // Author: A. Pulvirenti
13 //#include <TObject.h>
17 //#include <TObjArray.h>
21 //#include "AliITSVertex.h"
22 #include "AliITSIOTrack.h"
23 #include "AliITSNeuralPoint.h"
25 #include "AliITSNeuralTrack.h"
29 ClassImp(AliITSNeuralTrack)
33 AliITSNeuralTrack::AliITSNeuralTrack() : fMatrix(5,5), fVertex()
35 // Default constructor
39 fMass = 0.1396; // default assumption: pion
40 fField = 2.0; // default assumption: B = 0.4 Tesla
42 fXC = fYC = fR = fC = 0.0;
43 fTanL = fG0 = fDt = fDz = 0.0;
44 fStateR = fStatePhi = fStateZ = fChi2 = fNSteps = 0.0;
48 for (i = 0; i < 6; i++) fPoint[i] = 0;
60 AliITSNeuralTrack::AliITSNeuralTrack(AliITSNeuralTrack &track)
61 : TObject((TObject&)track), fMatrix(5,5), fVertex()
67 fMass = 0.1396; // default assumption: pion
68 fField = 2.0; // default assumption: B = 0.4 Tesla
70 fXC = fYC = fR = fC = 0.0;
71 fTanL = fG0 = fDt = fDz = 0.0;
72 fStateR = fStatePhi = fStateZ = fChi2 = fNSteps = 0.0;
76 for (i = 0; i < 6; i++) fPoint[i] = track.fPoint[i];
88 AliITSNeuralTrack::~AliITSNeuralTrack()
91 for (l = 0; l < 6; l++) fPoint[l] = 0;
96 void AliITSNeuralTrack::AssignLabel()
98 // Assigns a GEANT label to the found track.
99 // Every cluster has up to three labels (it can have less). Then each label is
100 // recorded for each point. Then, counts are made to check if some of the labels
101 // appear more than once. Finally, the label which appears most times is assigned
102 // to the track in the field fLabel.
103 // The number of points containing that label is counted in the fCount data-member.
106 Int_t i, j, l, lab, max = 0;
108 // We have up to 6 points for 3 labels each => up to 18 possible different values
109 Int_t idx[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
110 Int_t count[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
112 for (l = 0; l < 6; l++) {
113 if (!fPoint[l]) continue;
114 // Sometimes the same label appears two times in the same recpoint.
115 // With these if statements, such problem is solved by turning
116 // one of them to -1.
117 if (fPoint[l]->GetLabel(1) >= 0 && fPoint[l]->GetLabel(1) == fPoint[l]->GetLabel(0))
118 fPoint[l]->SetLabel(1, -1);
119 if (fPoint[l]->GetLabel(2) >= 0 && fPoint[l]->GetLabel(2) == fPoint[l]->GetLabel(0))
120 fPoint[l]->SetLabel(2, -1);
121 if (fPoint[l]->GetLabel(2) >= 0 && fPoint[l]->GetLabel(2) == fPoint[l]->GetLabel(1))
122 fPoint[l]->SetLabel(2, -1);
123 for (i = 0; i < 3; i++) {
124 lab = fPoint[l]->GetLabel(i);
125 if (lab < 0) continue;
127 for (j = 0; j < max; j++) {
141 j = 0, max = count[0];
142 for (i = 0; i < 18; i++) {
143 if (count[i] > max) {
154 void AliITSNeuralTrack::CleanSlot(Int_t i, Bool_t del)
156 // Removes a point from the corresponding layer slot in the found track.
157 // If the argument is TRUE, the point object is also deleted from heap.
159 if (i >= 0 && i < 6) {
160 if (del) delete fPoint[i];
167 void AliITSNeuralTrack::GetModuleData(Int_t layer, Int_t &mod, Int_t &pos)
169 // Returns the point coordinates according to the TreeR philosophy in galice.root files
170 // that consist in the module number (mod) and the position in the TClonesArray of
171 // the points reconstructed in that module for the run being examined.
173 if (layer < 0 || layer > 5) {
174 Error("GetModuleData", "Layer out of range: %d", layer);
177 mod = fPoint[layer]->GetModule();
178 pos = fPoint[layer]->GetIndex();
183 void AliITSNeuralTrack::Insert(AliITSNeuralPoint *point)
185 // A trivial method to insert a point in the tracks;
186 // the point is inserted to the slot corresponding to its ITS layer.
190 Int_t layer = point->GetLayer();
191 if (layer < 0 || layer > 6) {
192 Error("Insert", "Layer index %d out of range", layer);
196 fPoint[layer] = point;
201 Int_t AliITSNeuralTrack::OccupationMask()
203 // Returns a byte which maps the occupied slots.
204 // Each bit represents a layer going from the less significant on.
206 Int_t i, check, mask = 0;
207 for (i = 0; i < 6; i++) {
209 if (fPoint[i]) mask |= check;
216 void AliITSNeuralTrack::PrintLabels()
218 // Prints the results of the AssignLabel() method, together with
219 // the GEANT labels assigned to each point, in order to evaluate
220 // how the assigned label is distributed among points.
222 cout << "Assigned label = " << fLabel << " -- counted " << fCount << " times: " << endl << endl;
223 for (Int_t i = 0; i < 6; i++) {
224 cout << "Point #" << i + 1 << " --> ";
226 cout << "labels = " << fPoint[i]->GetLabel(0) << ", ";
227 cout << fPoint[i]->GetLabel(1) << ", ";
228 cout << fPoint[i]->GetLabel(2) << endl;
231 cout << "not assigned" << endl;
239 Bool_t AliITSNeuralTrack::AddEL(Int_t layer, Double_t sign)
241 // Calculates the correction for energy loss
243 Double_t width = 0.0;
245 case 0: width = 0.00260 + 0.00283; break;
246 case 1: width = 0.0180; break;
247 case 2: width = 0.0094; break;
248 case 3: width = 0.0095; break;
249 case 4: width = 0.0091; break;
250 case 5: width = 0.0087; break;
252 Error("AddEL", "Layer value %d out of range!", layer);
257 if((layer == 5) && (fStatePhi < 0.174 || fStatePhi > 6.100 || (fStatePhi > 2.960 && fStatePhi < 3.31))) {
261 Double_t invSqCosL = 1. + fTanL * fTanL; // = 1 / (cos(lambda)^2) = 1 + tan(lambda)^2
262 Double_t invCosL = TMath::Sqrt(invSqCosL); // = 1 / cos(lambda)
263 Double_t pt = GetPt(); // = transverse momentum
264 Double_t p2 = pt *pt * invSqCosL; // = square modulus of momentum
265 Double_t energy = TMath::Sqrt(p2 + fMass * fMass); // = energy
266 Double_t beta2 = p2 / (p2 + fMass * fMass); // = (v / c) ^ 2
268 printf("Anomaly in AddEL: pt=%8.6f invSqCosL=%8.6f fMass=%8.7f --> beta2 = %8.7f\n", pt, invSqCosL, fMass, beta2);
272 Double_t dE = 0.153 / beta2 * (log(5940. * beta2 / (1. - beta2)) - beta2) * width * 21.82 * invCosL;
273 dE = sign * dE * 0.001;
276 p2 = energy * energy - fMass * fMass;
277 pt = TMath::Sqrt(p2) / invCosL;
278 if (fC < 0.) pt = -pt;
279 fC = (0.299792458 * 0.2 * fField) / (pt * 100.);
286 Bool_t AliITSNeuralTrack::AddMS(Int_t layer)
288 // Calculates the noise perturbation due to multiple scattering
290 Double_t width = 0.0;
292 case 0: width = 0.00260 + 0.00283; break;
293 case 1: width = 0.0180; break;
294 case 2: width = 0.0094; break;
295 case 3: width = 0.0095; break;
296 case 4: width = 0.0091; break;
297 case 5: width = 0.0087; break;
299 Error("AddEL", "Layer value %d out of range!", layer);
304 if((layer == 5) && (fStatePhi < 0.174 || fStatePhi > 6.100 || (fStatePhi > 2.960 && fStatePhi < 3.31))) {
308 Double_t cosL = TMath::Cos(TMath::ATan(fTanL));
309 Double_t halfC = fC / 2.;
310 Double_t q20 = 1. / (cosL * cosL);
311 Double_t q30 = fC * fTanL;
313 Double_t q40 = halfC * (fStateR * fStateR - fDt * fDt) / (1. + 2. * halfC * fDt);
314 Double_t dd = fDt + halfC * fDt * fDt - halfC * fStateR * fStateR;
315 Double_t dprova = fStateR * fStateR - dd * dd;
317 if(dprova > 0.) q41 = -1. / cosL * TMath::Sqrt(dprova) / (1. + 2. * halfC *fDt);
319 Double_t p2 = (GetPt()*GetPt()) / (cosL * cosL);
320 Double_t beta2 = p2 / (p2 + fMass * fMass);
321 Double_t theta2 = 14.1 * 14.1 / (beta2 * p2 * 1.e6) * (width / TMath::Abs(cosL));
323 fMatrix(2,2) += theta2 * (q40 * q40 + q41 * q41);
324 fMatrix(3,2) += theta2 * q20 * q40;
325 fMatrix(2,3) += theta2 * q20 * q40;
326 fMatrix(3,3) += theta2 * q20 * q20;
327 fMatrix(4,2) += theta2 * q30 * q40;
328 fMatrix(2,4) += theta2 * q30 * q40;
329 fMatrix(4,3) += theta2 * q30 * q20;
330 fMatrix(3,4) += theta2 * q30 * q20;
331 fMatrix(4,4) += theta2 * q30 * q30;
338 Int_t AliITSNeuralTrack::PropagateTo(Double_t rk)
340 // Propagation method.
341 // Changes the state vector according to a new radial position
342 // which is specified by the passed 'r' value (in cylindircal coordinates).
343 // The covariance matrix is also propagated (and enlarged) according to
344 // the FCFt technique, where F is the jacobian of the new parameters
345 // w.r.t. their old values.
346 // The option argument forces the method to add also the energy loss
347 // and the multiple scattering effects, which respectively have the effect
348 // of changing the curvature and widening the covariance matrix.
350 if (rk < fabs(fDt)) {
351 Error("PropagateTo", Form("Impossible propagation to r (=%17.15g) < Dt (=%17.15g)", rk, fDt));
355 Double_t duepi = 2. * TMath::Pi();
356 Double_t rkm1 = fStateR;
357 Double_t aAk = ArgPhi(rk), aAkm1 = ArgPhi(rkm1);
358 Double_t ak = ArgZ(rk), akm1 = ArgZ(rkm1);
360 fStatePhi += TMath::ASin(aAk) - TMath::ASin(aAkm1);
361 if(fStatePhi > duepi) fStatePhi -= duepi;
362 if(fStatePhi < 0.) fStatePhi += duepi;
364 Double_t halfC = 0.5 * fC;
365 fStateZ += fTanL / halfC * (TMath::ASin(ak)-TMath::ASin(akm1));
367 Double_t bk = ArgB(rk), bkm1 = ArgB(rkm1);
368 Double_t ck = ArgC(rk), ckm1 = ArgC(rkm1);
370 Double_t f02 = ck / TMath::Sqrt(1. - aAk * aAk) - ckm1 / TMath::Sqrt(1. - aAkm1 * aAkm1);
371 Double_t f04 = bk / TMath::Sqrt(1. - aAk * aAk) - bkm1 / TMath::Sqrt(1. - aAkm1 * aAkm1);
372 Double_t f12 = fTanL * fDt * (1. / rk - 1. / rkm1);
373 Double_t f13 = rk - rkm1;
375 Double_t c00 = fMatrix(0,0);
376 Double_t c10 = fMatrix(1,0);
377 Double_t c11 = fMatrix(1,1);
378 Double_t c20 = fMatrix(2,0);
379 Double_t c21 = fMatrix(2,1);
380 Double_t c22 = fMatrix(2,2);
381 Double_t c30 = fMatrix(3,0);
382 Double_t c31 = fMatrix(3,1);
383 Double_t c32 = fMatrix(3,2);
384 Double_t c33 = fMatrix(3,3);
385 Double_t c40 = fMatrix(4,0);
386 Double_t c41 = fMatrix(4,1);
387 Double_t c42 = fMatrix(4,2);
388 Double_t c43 = fMatrix(4,3);
389 Double_t c44 = fMatrix(4,4);
391 Double_t r10 = c10 + c21*f02 + c41*f04;
392 Double_t r20 = c20 + c22*f02 + c42*f04;
393 Double_t r30 = c30 + c32*f02 + c43*f04;
394 Double_t r40 = c40 + c42*f02 + c44*f04;
395 Double_t r21 = c21 + c22*f12 + c32*f13;
396 Double_t r31 = c31 + c32*f12 + c33*f13;
397 Double_t r41 = c41 + c42*f12 + c43*f13;
399 fMatrix(0,0) = c00 + c20*f02 + c40*f04 + f02*r20 + f04*r40;
400 fMatrix(1,0) = fMatrix(0,1) = r10 + f12*r20 + f13*r30;
401 fMatrix(1,1) = c11 + c21*f12 + c31*f13 + f12*r21 + f13*r31;
402 fMatrix(2,0) = fMatrix(0,2) = r20;
403 fMatrix(2,1) = fMatrix(1,2) = r21;
404 fMatrix(3,0) = fMatrix(0,3) = r30;
405 fMatrix(3,1) = fMatrix(1,3) = r31;
406 fMatrix(4,0) = fMatrix(0,4) = r40;
407 fMatrix(4,1) = fMatrix(1,4) = r41;
411 if (rkm1 < fStateR) // going to greater R --> energy LOSS
413 else // going to smaller R --> energy GAIN
419 Bool_t AliITSNeuralTrack::SeedCovariance()
421 // generate a covariance matrix depending on the results obtained from
422 // the preliminary seeding fit procedure.
423 // It calculates the variances for C, D ans TanL, according to the
424 // differences of the fitted values from the requested ones necessary
425 // to make the curve exactly pass through each point.
429 AliITSNeuralPoint *p = 0;
430 Double_t r, argPhi, phiC, phiD, argZ, zL;
431 Double_t sumC = 0.0, sumD = 0.0, sumphi = 0., sumz = 0., sumL = 0.;
432 for (i = 0; i < fNum; i++) {
436 // weight and derivatives of phi and zeta w.r.t. various params
437 sumphi += 1./ p->ErrorGetPhi();
440 if (argPhi > 100.0 || argZ > 100.0) {
441 Error("InitCovariance", "Argument error");
444 phiC = DerArgPhiC(r) / TMath::Sqrt(1.0 - argPhi * argPhi);
445 phiD = DerArgPhiD(r) / TMath::Sqrt(1.0 - argPhi * argPhi);
446 if (phiC > 100.0 || phiD > 100.0) {
447 Error("InitCovariance", "Argument error");
450 zL = asin(argZ) / fC;
454 sumz += 1.0 / (p->fError[2] * p->fError[2]);
457 for (i = 0; i < 5; i++) for (j = 0; j < 5; j++) fMatrix(i,j) = 0.;
458 fMatrix(0,0) = 1. / sumphi;
459 fMatrix(1,1) = 1. / sumz;
460 fMatrix(2,2) = 1. / sumD;
461 fMatrix(3,3) = 1. / sumL;
462 fMatrix(4,4) = 1. / sumC;
466 AliITSNeuralPoint *p = 0;
467 Double_t delta, cs, sn, r, argz;
468 Double_t diffC, diffD, diffL, calcC, calcD, calcL;
471 for (l = 0; l < 6; l++) {
474 sn = TMath::Sin(p->GetPhi() - fG0);
475 cs = TMath::Cos(p->GetPhi() - fG0);
477 calcC = (fDt/r - sn) / (2.*fDt*sn - r - fDt*fDt/r);
480 Error("Covariance", "Value too high");
483 calcL = (p->Z() - fDz) * fC / asin(argz);
484 delta = fR*fR + r*r + 2.0*fR*r*sin(p->GetPhi() - fG0);
489 Error("Covariance", Form("Discriminant = %g --- Dt = %g", delta, fDt));
499 diffL = calcL - fTanL;
501 fMatrix(0,0) += 100000000.0 * p->GetError("phi") * p->GetError("phi");
502 fMatrix(1,1) += 10000.0 * p->ErrZ() * p->ErrZ();
503 fMatrix(2,2) += 100000.0 * diffD * diffD;
504 fMatrix(3,3) += diffL * diffL;
505 fMatrix(4,4) += 100000000.0 * diffC * diffC;
508 for (l = 0; l < 6; l++) if (fPoint[l]) n++;
509 fMatrix *= 1./(n++ * n);
515 Bool_t AliITSNeuralTrack::Filter(AliITSNeuralPoint *test)
517 // Makes all calculations which apply the Kalman filter to the
518 // stored guess of the state vector, after propagation to a new layer
521 Error("Filter", "Null pointer passed");
526 Double_t rk, phik, zk;
528 phik = test->GetPhi();
533 //////////////////////// Evaluation of the error matrix V /////////
534 Double_t v00 = test->GetError("phi") * rk;
535 Double_t v11 = test->ErrZ();
536 ////////////////////////////////////////////////////////////////////
538 // Get the covariance matrix
539 Double_t cin00, cin10, cin20, cin30, cin40;
540 Double_t cin11, cin21, cin31, cin41, cin22;
541 Double_t cin32, cin42, cin33, cin43, cin44;
542 cin00 = fMatrix(0,0);
543 cin10 = fMatrix(1,0);
544 cin20 = fMatrix(2,0);
545 cin30 = fMatrix(3,0);
546 cin40 = fMatrix(4,0);
547 cin11 = fMatrix(1,1);
548 cin21 = fMatrix(2,1);
549 cin31 = fMatrix(3,1);
550 cin41 = fMatrix(4,1);
551 cin22 = fMatrix(2,2);
552 cin32 = fMatrix(3,2);
553 cin42 = fMatrix(4,2);
554 cin33 = fMatrix(3,3);
555 cin43 = fMatrix(4,3);
556 cin44 = fMatrix(4,4);
558 // Calculate R matrix
559 Double_t rold00 = cin00 + v00;
560 Double_t rold10 = cin10;
561 Double_t rold11 = cin11 + v11;
563 ////////////////////// R matrix inversion /////////////////////////
564 Double_t det = rold00*rold11 - rold10*rold10;
565 Double_t r00 = rold11/det;
566 Double_t r10 = -rold10/det;
567 Double_t r11 = rold00/det;
568 ////////////////////////////////////////////////////////////////////
570 // Calculate Kalman matrix
571 Double_t k00 = cin00*r00 + cin10*r10;
572 Double_t k01 = cin00*r10 + cin10*r11;
573 Double_t k10 = cin10*r00 + cin11*r10;
574 Double_t k11 = cin10*r10 + cin11*r11;
575 Double_t k20 = cin20*r00 + cin21*r10;
576 Double_t k21 = cin20*r10 + cin21*r11;
577 Double_t k30 = cin30*r00 + cin31*r10;
578 Double_t k31 = cin30*r10 + cin31*r11;
579 Double_t k40 = cin40*r00 + cin41*r10;
580 Double_t k41 = cin40*r10 + cin41*r11;
582 // Get state vector (will keep the old values for phi and z)
583 Double_t x0, x1, x2, x3, x4, savex0, savex1;
584 x0 = savex0 = fStatePhi;
585 x1 = savex1 = fStateZ;
590 // Update the state vector
591 x0 += k00*(m[0]-savex0) + k01*(m[1]-savex1);
592 x1 += k10*(m[0]-savex0) + k11*(m[1]-savex1);
593 x2 += k20*(m[0]-savex0) + k21*(m[1]-savex1);
594 x3 += k30*(m[0]-savex0) + k31*(m[1]-savex1);
595 x4 += k40*(m[0]-savex0) + k41*(m[1]-savex1);
597 // Update the covariance matrix
598 Double_t cout00, cout10, cout20, cout30, cout40;
599 Double_t cout11, cout21, cout31, cout41, cout22;
600 Double_t cout32, cout42, cout33, cout43, cout44;
602 cout00 = cin00 - k00*cin00 - k01*cin10;
603 cout10 = cin10 - k00*cin10 - k01*cin11;
604 cout20 = cin20 - k00*cin20 - k01*cin21;
605 cout30 = cin30 - k00*cin30 - k01*cin31;
606 cout40 = cin40 - k00*cin40 - k01*cin41;
607 cout11 = cin11 - k10*cin10 - k11*cin11;
608 cout21 = cin21 - k10*cin20 - k11*cin21;
609 cout31 = cin31 - k10*cin30 - k11*cin31;
610 cout41 = cin41 - k10*cin40 - k11*cin41;
611 cout22 = cin22 - k20*cin20 - k21*cin21;
612 cout32 = cin32 - k20*cin30 - k21*cin31;
613 cout42 = cin42 - k20*cin40 - k21*cin41;
614 cout33 = cin33 - k30*cin30 - k31*cin31;
615 cout43 = cin43 - k30*cin40 - k31*cin41;
616 cout44 = cin44 - k40*cin40 - k41*cin41;
618 // Store the new covariance matrix
619 fMatrix(0,0) = cout00;
620 fMatrix(1,0) = fMatrix(0,1) = cout10;
621 fMatrix(2,0) = fMatrix(0,2) = cout20;
622 fMatrix(3,0) = fMatrix(0,3) = cout30;
623 fMatrix(4,0) = fMatrix(0,4) = cout40;
624 fMatrix(1,1) = cout11;
625 fMatrix(2,1) = fMatrix(1,2) = cout21;
626 fMatrix(3,1) = fMatrix(1,3) = cout31;
627 fMatrix(4,1) = fMatrix(1,4) = cout41;
628 fMatrix(2,2) = cout22;
629 fMatrix(3,2) = fMatrix(2,3) = cout32;
630 fMatrix(4,2) = fMatrix(2,4) = cout42;
631 fMatrix(3,3) = cout33;
632 fMatrix(4,3) = fMatrix(3,4) = cout43;
633 fMatrix(4,4) = cout44;
635 // Calculation of the chi2 increment
636 Double_t vmcold00 = v00 - cout00;
637 Double_t vmcold10 = -cout10;
638 Double_t vmcold11 = v11 - cout11;
639 ////////////////////// Matrix vmc inversion ///////////////////////
640 det = vmcold00*vmcold11 - vmcold10*vmcold10;
641 Double_t vmc00=vmcold11/det;
642 Double_t vmc10 = -vmcold10/det;
643 Double_t vmc11 = vmcold00/det;
644 ////////////////////////////////////////////////////////////////////
645 Double_t chi2 = (m[0] - x0)*( vmc00*(m[0] - x0) + 2.*vmc10*(m[1] - x1) ) + (m[1] - x1)*vmc11*(m[1] - x1);
654 Bool_t AliITSNeuralTrack::KalmanFit()
656 // Applies the Kalman Filter to improve the track parameters resolution.
657 // First, thre point which lies closer to the estimated helix is chosen.
658 // Then, a fit is performed towards the 6th layer
659 // Finally, the track is refitted to the 1st layer
662 Int_t l, layer, sign;
664 fStateR = fPoint[0]->GetR2();
665 fStatePhi = fPoint[0]->GetPhi();
666 fStateZ = fPoint[0]->Z();
668 if (!PropagateTo(3.0)) {
669 Error("KalmanFit", "Unsuccessful initialization");
674 // Performs a Kalman filter going from the actual state position
675 // towards layer 6 position
676 // Now, the propagation + filtering operations can be performed
677 Double_t argPhi = 0.0, argZ = 0.0;
680 Error("KalmanFit", "Not six points!");
683 layer = fPoint[l]->GetLayer();
684 rho = fPoint[l]->GetR2();
685 sign = PropagateTo(rho);
686 if (!sign) return kFALSE;
689 if (!Filter(fPoint[l])) return kFALSE;
690 // these two parameters are update according to the filtered values
691 argPhi = ArgPhi(fStateR);
692 argZ = ArgZ(fStateR);
693 if (argPhi > 1.0 || argPhi < -1.0 || argZ > 1.0 || argZ < -1.0) {
694 Error("Filter", Form("Filtering returns too large values: %g, %g", argPhi, argZ));
697 fG0 = fStatePhi - asin(argPhi);
698 fDz = fStateZ - (2.0 * fTanL / fC) * asin(argZ);
702 // Now a Kalman filter i performed going from the actual state position
703 // towards layer 1 position and then propagates to vertex
706 layer = fPoint[l]->GetLayer();
707 rho = fPoint[l]->GetR2();
709 sign = PropagateTo(rho);
710 if (!sign) return kFALSE;
712 if (!Filter(fPoint[l])) return kFALSE;
713 // these two parameters are update according to the filtered values
714 argPhi = ArgPhi(fStateR);
715 argZ = ArgZ(fStateR);
716 if (argPhi > 1.0 || argPhi < -1.0 || argZ > 1.0 || argZ < -1.0) {
717 Error("Filter", Form("Filtering returns too large values: %g, %g", argPhi, argZ));
720 fG0 = fStatePhi - asin(argPhi);
721 fDz = fStateZ - (2.0 * fTanL / fC) * asin(argZ);
729 Bool_t AliITSNeuralTrack::RiemannFit()
731 // Method which executes the circle fit via a Riemann Sphere projection
732 // with the only improvement of a weighted mean, due to different errors
733 // over different point measurements.
734 // As an output, it returns kTRUE or kFALSE respectively if the fit succeeded or not
735 // in fact, if some variables assume strange values, the fit is aborted,
736 // in order to prevent the class from raising a floating point error;
740 // M1 - matrix of ones
742 for (i = 0; i < 6; i++) m1(i,0) = 1.0;
744 // X - matrix of Rieman projection coordinates
746 for (i = 0; i < 6; i++) {
747 mX(i,0) = fPoint[i]->X();
748 mX(i,1) = fPoint[i]->Y();
749 mX(i,2) = fPoint[i]->GetR2sq();
752 // W - matrix of weights
753 Double_t xterm, yterm, ex, ey;
755 for (i = 0; i < 6; i++) {
756 xterm = fPoint[i]->X() * fPoint[i]->GetPhi() - fPoint[i]->Y() / fPoint[i]->GetR2();
757 ex = fPoint[i]->ErrX();
758 yterm = fPoint[i]->Y() * fPoint[i]->GetPhi() + fPoint[i]->X() / fPoint[i]->GetR2();
759 ey = fPoint[i]->ErrY();
760 mW(i,i) = fPoint[i]->GetR2sq() / (xterm * xterm * ex * ex + yterm * yterm * ey * ey);
763 // Xm - weighted sample mean
764 Double_t meanX = 0.0, meanY = 0.0, meanW = 0.0, sw = 0.0;
765 for (i = 0; i < 6; i++) {
766 meanX += mW(i,i) * mX(i,0);
767 meanY += mW(i,i) * mX(i,1);
768 meanW += mW(i,i) * mX(i,2);
775 // V - sample covariance matrix
776 for (i = 0; i < 6; i++) {
781 TMatrixD mXt(TMatrixD::kTransposed, mX);
782 TMatrixD mWX(mW, TMatrixD::kMult, mX);
783 TMatrixD mV(mXt, TMatrixD::kMult, mWX);
784 for (i = 0; i < 3; i++) {
785 for (j = i + 1; j < 3; j++) {
786 mV(i,j) = mV(j,i) = (mV(i,j) + mV(j,i)) * 0.5;
790 // Eigenvalue problem solving for V matrix
792 TVectorD eval(3), n(3);
793 TMatrixD evec = mV.EigenVectors(eval);
794 if (eval(1) < eval(ileast)) ileast = 1;
795 if (eval(2) < eval(ileast)) ileast = 2;
796 n(0) = evec(0, ileast);
797 n(1) = evec(1, ileast);
798 n(2) = evec(2, ileast);
800 // c - known term in the plane intersection with Riemann axes
801 Double_t c = -(meanX * n(0) + meanY * n(1) + meanW * n(2));
803 fXC = -n(0) / (2. * n(2));
804 fYC = -n(1) / (2. * n(2));
805 fR = (1. - n(2)*n(2) - 4.*c*n(2)) / (4. * n(2) * n(2));
808 Error("RiemannFit", "Radius comed less than zero!!!");
811 fR = TMath::Sqrt(fR);
814 // evaluating signs for curvature and others
815 Double_t phi1 = 0.0, phi2, temp1, temp2, sumdphi = 0.0, ref = TMath::Pi();
816 AliITSNeuralPoint *p = fPoint[0];
818 for (i = 1; i < 6; i++) {
819 p = (AliITSNeuralPoint*)fPoint[i];
824 if (temp1 > ref && temp2 < ref)
826 else if (temp1 < ref && temp2 > ref)
828 sumdphi += temp2 - temp1;
831 if (sumdphi < 0.E0) fC = -fC;
832 Double_t diff, angle = TMath::ATan2(fYC, fXC);
834 fG0 = angle + 0.5 * TMath::Pi();
836 fG0 = angle - 0.5 * TMath::Pi();
839 Double_t d = TMath::Sqrt(fXC*fXC + fYC*fYC) - fR;
846 Double_t halfC = 0.5 * fC;
847 Double_t *s = new Double_t[nn], *z = new Double_t[nn], *ws = new Double_t[nn];
848 for (j = 0; j < 6; j++) {
851 s[j] = ArgZ(p->GetR2());
852 if (s[j] > 100.0) return kFALSE;
854 s[j] = asin(s[j]) / halfC;
855 ws[j] = 1.0 / (p->ErrZ()*p->ErrZ());
858 // second tep final fit
859 Double_t sums2 = 0.0, sumz = 0.0, sumsz = 0.0, sums = 0.0, sumw = 0.0;
860 for (i = 0; i < nn; i++) {
861 sums2 += ws[i] * s[i] * s[i];
862 sumz += ws[i] * z[i];
863 sums += ws[i] * s[i];
864 sumsz += ws[i] * s[i] * z[i];
871 d = sums2 - sums*sums;
873 fDz = (sums2*sumz - sums*sumsz) / d;
874 fTanL = (sumsz - sums*sumz) / d;
885 void AliITSNeuralTrack::PrintState(Bool_t matrix)
887 // Prints the state vector values.
888 // The argument switches on or off the printing of the covariance matrix.
890 cout << "\nState vector: " << endl;
891 cout << " Rho = " << fStateR << "\n";
892 cout << " Phi = " << fStatePhi << "\n";
893 cout << " Z = " << fStateZ << "\n";
894 cout << " Dt = " << fDt << "\n";
895 cout << " Dz = " << fDz << "\n";
896 cout << "TanL = " << fTanL << "\n";
897 cout << " C = " << fC << "\n";
898 cout << " G0 = " << fG0 << "\n";
899 cout << " XC = " << fXC << "\n";
900 cout << " YC = " << fYC << "\n";
902 cout << "\nCovariance Matrix: " << endl;
905 cout << "Actual square chi = " << fChi2;
910 Double_t AliITSNeuralTrack::GetDz() const
912 // Double_t argZ = ArgZ(fStateR);
914 // Error("GetDz", "Too large value: %g", argZ);
917 // fDz = fStateZ - (2.0 * fTanL / fC) * asin(argZ);
923 Double_t AliITSNeuralTrack::GetGamma() const
925 // these two parameters are update according to the filtered values
926 // Double_t argPhi = ArgPhi(fStateR);
927 // if (argPhi > 9.9) {
928 // Error("Filter", "Too large value: %g", argPhi);
931 // fG0 = fStatePhi - asin(argPhi);
937 Double_t AliITSNeuralTrack::GetPhi(Double_t r) const
939 // Gives the value of azymuthal coordinate in the helix
940 // as a function of cylindric radius
942 Double_t arg = ArgPhi(r);
943 if (arg > 0.9) return 0.0;
944 arg = fG0 + asin(arg);
945 while (arg >= 2.0 * TMath::Pi()) { arg -= 2.0 * TMath::Pi(); }
946 while (arg < 0.0) { arg += 2.0 * TMath::Pi(); }
952 Double_t AliITSNeuralTrack::GetZ(Double_t r) const
954 // gives the value of Z in the helix
955 // as a function of cylindric radius
957 Double_t arg = ArgZ(r);
958 if (arg > 0.9) return 0.0;
959 return fDz + fTanL * asin(arg) / fC;
964 Double_t AliITSNeuralTrack::GetdEdX()
966 // total energy loss of the track
968 Double_t q[4] = {0., 0., 0., 0.}, dedx = 0.0;
969 Int_t i = 0, swap = 0;
970 for (i = 2; i < 6; i++) {
971 if (!fPoint[i]) continue;
972 q[i - 2] = (Double_t)fPoint[i]->GetCharge();
973 q[i - 2] /= (1 + fTanL*fTanL);
981 for (i = 0; i < 3; i++) {
982 if (q[i] <= q[i + 1]) continue;
995 dedx = (q[0] + q[1]) / 2.;
1001 void AliITSNeuralTrack::SetVertex(Double_t *pos, Double_t *err)
1003 // Stores vertex data
1005 if (!pos || !err) return;
1006 fVertex.ErrX() = err[0];
1007 fVertex.ErrY() = err[1];
1008 fVertex.ErrZ() = err[2];
1009 fVertex.SetLayer(0);
1010 fVertex.SetModule(0);
1011 fVertex.SetIndex(0);
1012 fVertex.SetLabel(0, -1);
1013 fVertex.SetLabel(1, -1);
1014 fVertex.SetLabel(2, -1);
1020 AliITSIOTrack* AliITSNeuralTrack::ExportIOtrack(Int_t min)
1022 // Exports an object in the standard format for reconstructed tracks
1025 AliITSIOTrack *track = new AliITSIOTrack;
1027 // covariance matrix
1028 track->SetCovMatrix(fMatrix(0,0), fMatrix(1,0), fMatrix(1,1),
1029 fMatrix(2,0), fMatrix(2,1), fMatrix(2,2),
1030 fMatrix(3,0), fMatrix(3,1), fMatrix(3,2),
1031 fMatrix(3,3), fMatrix(4,0), fMatrix(4,1),
1032 fMatrix(4,2), fMatrix(4,3), fMatrix(4,4));
1035 track->SetLabel(IsGood(min) ? fLabel : -fLabel);
1036 track->SetTPCLabel(-1);
1038 // points characteristics
1039 for (layer = 0; layer < 6; layer++) {
1040 if (fPoint[layer]) {
1041 track->SetIdModule(layer, fPoint[layer]->GetModule());
1042 track->SetIdPoint(layer, fPoint[layer]->GetIndex());
1047 track->SetStatePhi(fStatePhi);
1048 track->SetStateZ(fStateZ);
1049 track->SetStateD(fDt);
1050 track->SetStateTgl(fTanL);
1051 track->SetStateC(fC);
1052 track->SetRadius(fStateR);
1053 track->SetCharge((fC > 0.0) ? -1 : 1);
1056 // track parameters in the closest point
1057 track->SetX(fStateR * cos(fStatePhi));
1058 track->SetY(fStateR * cos(fStatePhi));
1059 track->SetZ(fStateZ);
1060 track->SetPx(GetPt() * cos(fG0));
1061 track->SetPy(GetPt() * sin(fG0));
1062 track->SetPz(GetPt() * fTanL);
1065 track->SetPid(fPDG);
1066 track->SetMass(fMass);
1072 //====================================================================================
1073 //============================ PRIVATE METHODS ============================
1074 //====================================================================================
1077 Double_t AliITSNeuralTrack::ArgPhi(Double_t r) const
1079 // calculates the expression ((1/2)Cr + (1 + (1/2)CD) D/r) / (1 + CD)
1081 Double_t arg, num, den;
1082 num = (0.5 * fC * r) + (1. + (0.5 * fC * fDt)) * (fDt / r);
1083 den = 1. + fC * fDt;
1085 Error("ArgPhi", "Denominator = 0!");
1089 if (TMath::Abs(arg) < 1.) return arg;
1090 if (TMath::Abs(arg) <= 1.00001) return (arg > 0.) ? 0.99999999999 : -0.9999999999;
1091 Error("ArgPhi", "Value too large: %17.15g", arg);
1097 Double_t AliITSNeuralTrack::ArgZ(Double_t r) const
1099 // calculates the expression (1/2)C * sqrt( (r^2 - Dt^2) / (1 + CD) )
1102 arg = (r * r - fDt * fDt) / (1. + fC * fDt);
1104 if (fabs(arg) < 1.E-6) arg = 0.;
1106 Error("ArgZ", "Square root argument error: %17.15g < 0", arg);
1110 arg = 0.5 * fC * TMath::Sqrt(arg);
1111 if (TMath::Abs(arg) < 1.) return arg;
1112 if (TMath::Abs(arg) <= 1.00001) return (arg > 0.) ? 0.99999999999 : -0.9999999999;
1113 Error("ArgZ", "Value too large: %17.15g", arg);
1119 Double_t AliITSNeuralTrack::ArgB(Double_t r) const
1124 arg = (r*r - fDt*fDt);
1125 arg /= (r*(1.+ fC*fDt)*(1.+ fC*fDt));
1131 Double_t AliITSNeuralTrack::ArgC(Double_t r) const
1136 arg = (1./r - fC * ArgPhi(r));