Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaVDCCluster.cxx
Go to the documentation of this file.
1
2// //
3// THaVDCCluster //
4// //
5// A group of VDC hits and routines for linear and non-linear fitting of //
6// drift distances. //
7// //
9
10#include "THaVDCCluster.h"
11#include "THaVDCHit.h"
12#include "THaVDCPlane.h"
13#include "THaTrack.h"
14#include "TMath.h"
15#include "TClass.h"
16
17#include <iostream>
18
19using namespace VDC;
20using namespace std;
21
22static const Int_t kDefaultNHit = 16;
23
24//_____________________________________________________________________________
26 : fPlane(owner), fPointPair(nullptr), fTrack(nullptr), fTrkNum(0),
27 fSlope(kBig), fLocalSlope(kBig), fSigmaSlope(kBig),
28 fInt(kBig), fSigmaInt(kBig), fT0(kBig), fSigmaT0(kBig),
29 fPivot(nullptr), fTimeCorrection(0),
30 fFitOK(false), fChi2(kBig), fNDoF(0.0), fClsBeg(kMaxInt), fClsEnd(-1)
31{
32 // Constructor
33
34 fHits.reserve(kDefaultNHit);
35 fCoord.reserve(kDefaultNHit);
36}
37
38//_____________________________________________________________________________
40{
41 // Add a hit to the cluster
42
43 assert( hit );
44
45 fHits.push_back( hit );
46 if( fClsBeg > hit->GetWireNum() )
47 fClsBeg = hit->GetWireNum();
48 if( fClsEnd < hit->GetWireNum() )
49 fClsEnd = hit->GetWireNum();
50}
51
52//_____________________________________________________________________________
54{
55 // Clear the contents of the cluster and reset status
56
57 ClearFit();
58 fHits.clear();
59 fPivot = nullptr;
60 fPlane = nullptr;
61 fPointPair = nullptr;
62 fTrack = nullptr;
63 fTrkNum = 0;
64 fClsBeg = kMaxInt-1;
65 fClsEnd = -1;
66}
67
68//_____________________________________________________________________________
70{
71 // Clear fit results only
72
73 fSlope = kBig;
76 fInt = kBig;
78 fT0 = kBig;
79 fSigmaT0 = kBig;
80 fFitOK = false;
82 fChi2 = kBig;
83 fNDoF = 0.0;
84}
85
86//_____________________________________________________________________________
88{
89 // Compare this cluster to another via the wire number of the pivot.
90 // Returns -1 if comparison cannot be made (unlike class, no pivot).
91
92 if( !obj || IsA() != obj->IsA() )
93 return -1;
94
95 const auto* rhs = static_cast<const THaVDCCluster*>( obj );
96 if( GetPivotWireNum() < rhs->GetPivotWireNum() )
97 return -1;
98 if( GetPivotWireNum() > rhs->GetPivotWireNum() )
99 return +1;
100
101 return 0;
102}
103
104//_____________________________________________________________________________
106{
107 // Estimate Track Parameters
108 // Calculates pivot wire and uses its position as position of cluster
109 // Estimates the slope based on the distance between the first and last
110 // wires to be hit in the U (or V) and detector Z directions
111
112 fFitOK = false;
113 if( GetSize() == 0 )
114 return;
115
116 // Find pivot
117 Double_t minTime = 1000; // drift-times in seconds
118 for (int i = 0; i < GetSize(); i++) {
119 Double_t time = fHits[i]->GetTime();
120 if (time < minTime) { // look for lowest time
121 minTime = time;
122 fPivot = fHits[i];
123 }
124 }
125
126 // Now set intercept
127 fInt = fPivot->GetPos();
128
129 // Now find the approximate slope
130 // X = Drift Distance (m)
131 // Y = Position of Wires (m)
132 if( GetSize() > 1 ) {
133 Double_t conv = fPlane->GetDriftVel(); // m/s
134 Double_t dx = conv * (fHits[0]->GetTime() + fHits[GetSize()-1]->GetTime());
135 Double_t dy = fHits[0]->GetPos() - fHits[GetSize()-1]->GetPos();
136 fSlope = dy / dx;
137 } else
138 fSlope = 1.0;
139
140 fFitOK = true;
141}
142
143//_____________________________________________________________________________
145{
146 // Convert TDC Times in wires to drift distances
147
148 //Do conversion for each hit in cluster
149 for (int i = 0; i < GetSize(); i++)
151}
152
153//_____________________________________________________________________________
155{
156 // Calculate and store the distance of the global track to the wires.
157 // We can then inspect the quality of the fits.
158 //
159 // This is actually a bit tedious: we need to project the track
160 // (given by its detector coordinates) onto this cluster's plane (u or v),
161 // then find the track's z coordinate for each active wire's position.
162 // It takes two pages of vector algebra.
163 //
164 // Return value: sum of squares of distances and number of hits used
165
166 assert( fTrack );
167
168 Int_t npt = 0;
169 Double_t chi2 = 0;
170 for (int j = 0; j < GetSize(); j++) {
171 // Use only hits marked to belong to this track
172 if( fHits[j]->GetTrkNum() != fTrack->GetTrkNum() )
173 continue;
174 Double_t u = fHits[j]->GetPos(); // u (v) coordinate of wire
175 Double_t sina = fPlane->GetSinWAngle();
176 Double_t cosa = fPlane->GetCosWAngle();
177 Double_t denom = cosa*fTrack->GetDTheta() + sina*fTrack->GetDPhi();
178 Double_t z = (u - cosa*fTrack->GetDX() - sina*fTrack->GetDY()) / denom;
179 Double_t dz = z - fPlane->GetZ();
180 fHits[j]->SetFitDist(TMath::Abs(dz));
181 chi2 += dz*dz;
182 npt++;
183 }
184 return make_pair( chi2, npt );
185}
186
187//_____________________________________________________________________________
189{
190 //FIXME: clean this up - duplicate of chi2 calculation
191 // Calculate and store the distance of the local fitted track to the wires.
192 // We can then inspect the quality of the local fits
193 for (int j = 0; j < GetSize(); j++) {
194 Double_t y = fHits[j]->GetPos();
195 if (fLocalSlope != 0. && fLocalSlope < kBig) {
197 fHits[j]->SetLocalFitDist(TMath::Abs(X));
198 } else {
199 fHits[j]->SetLocalFitDist(kBig);
200 }
201 }
202}
203
204//_____________________________________________________________________________
206{
207 // Return index of assigned track (-1 = none, 0 = first/best, etc.)
208
209 if( !fTrack ) return -1;
210 return fTrack->GetIndex();
211}
212
213//_____________________________________________________________________________
215{
216 // Fit track to drift distances. Supports three modes:
217 //
218 // kSimple: Linear fit, ignore t0 and multihits
219 // kWeighted: Linear fit with weights, ignore t0
220 // kT0: Fit t0, but ignore multihits
221
222 switch( mode ) {
223 case kSimple:
224 FitSimpleTrack(false);
225 break;
226 case kWeighted:
227 FitSimpleTrack(true);
228 break;
229 case kT0:
231 break;
232 }
234}
235
236//_____________________________________________________________________________
238{
239 // Perform linear fit on drift times. Calculates slope, intercept, and errors.
240 // Does not assume the uncertainty is the same for all hits.
241 //
242 // Assume t0 = 0.
243
244 // For this function, the final results is (m,b) in Y = m X + b
245 // X = Drift Distance
246 // Y = Position of Wires
247
248 fFitOK = false;
249 if( GetSize() < 3 ) {
250 return; // Too few hits to get meaningful results
251 // Do keep current values of slope and intercept
252 }
253
254 fCoord.clear();
255
256 Double_t bestFit = 0.0;
257
258 // Find the index of the pivot wire and copy distances into local arrays
259 // Note that as the index of the hits is increasing, the position of the
260 // wires is decreasing
261
262 Int_t pivotNum = 0;
263 for (int i = 0; i < GetSize(); i++) {
264
265 // In order to take into account the varying uncertainty in the
266 // drift distance, we will be working with the X' and Y', and
267 // Y' = F + G X'
268 // where Y' = X, and X' = Y (swapping it around)
269 if (fHits[i] == fPivot) {
270 pivotNum = i;
271 }
272
273 Double_t x = fHits[i]->GetPos();
274 Double_t y = fHits[i]->GetDist() + fTimeCorrection;
275 Double_t w = 1.0;
276 if( weighted ) {
277 w = fHits[i]->GetdDist();
278 // the hit will be ignored if the uncertainty is < 0
279 if (w>0)
280 w = 1./(w*w); // sigma^-2 is the weight
281 else
282 w = -1.;
283 }
284 fCoord.push_back( FitCoord_t(x,y,w) );
285 }
286
287 const Int_t nSignCombos = 2; //Number of different sign combinations
288 for (int i = 0; i < nSignCombos; i++) {
289 Double_t sumX = 0.0; //Positions
290// Double_t sumXW = 0.0;
291 Double_t sumXX = 0.0;
292 Double_t sumY = 0.0; //Drift distances
293 Double_t sumXY = 0.0;
294// Double_t sumYY = 0.0;
295// Double_t sumXXW= 0.0;
296
297 Double_t W = 0.0;
298// Double_t WW= 0.0;
299
300 if (i == 0)
301 for (int j = pivotNum+1; j < GetSize(); j++)
302 fCoord[j].y *= -1;
303 else if (i == 1)
304 fCoord[pivotNum].y *= -1;
305
306 for (int j = 0; j < GetSize(); j++) {
307 Double_t x = fCoord[j].x; // Position of wire
308 Double_t y = fCoord[j].y; // Distance to wire
309 Double_t w = fCoord[j].w;
310
311 if (w <= 0) continue;
312 W += w;
313// WW += w*w;
314 sumX += x * w;
315// sumXW += x * w * w;
316 sumXX += x * x * w;
317// sumXXW+= x * x * w * w;
318 sumY += y * w;
319 sumXY += x * y * w;
320// sumYY += y * y * w;
321 }
322
323 // Standard formulae for linear regression (see Bevington)
324 Double_t Delta = W * sumXX - sumX * sumX;
325
326 // intermediate slope and St. Dev.**2
327 Double_t F = (sumXX * sumY - sumX * sumXY) / Delta;
328 Double_t sigmaF2 = ( sumXX / Delta );
329 // intermediate intercept and St. Dev.**2
330 Double_t G = (W * sumXY - sumX * sumY) / Delta;
331 Double_t sigmaG2 = ( W / Delta );
332
333 // correlated uncertainty
334 Double_t sigmaFG = ( -sumX / Delta );
335
336 // calculate chi2 for the track given this slope and intercept
337 chi2_t chi2 = CalcChisquare( G, F, 0 );
338
339 // Slope, St. Dev. in slope
340 Double_t m = 1/G;
341 Double_t sigmaM = m * m * TMath::Sqrt( sigmaG2 );
342 // Intercept, St. Dev in Intercept
343 Double_t b = - F/G;
344 Double_t sigmaB = TMath::Sqrt(sigmaF2 + F * F / (G * G) * sigmaG2
345 - 2 * F / G * sigmaFG) / TMath::Abs(G);
346
347
348 // scale the uncertainty of the fit parameters based upon the
349 // quality of the fit. This really should not be necessary if
350 // we believe the drift-distance uncertainties
351 // sigmaM *= chi2/(nhits - 2);
352 // sigmaB *= chi2/(nhits - 2);
353
354 // Pick the better value
355 if (i == 0 || chi2.first < bestFit) {
356 bestFit = fChi2 = chi2.first;
357 fNDoF = chi2.second - 2;
358 fLocalSlope = m;
359 fInt = b;
360 fSigmaSlope = sigmaM;
361 fSigmaInt = sigmaB;
362 fT0 = 0.0;
363 }
364 }
365
366 fFitOK = true;
367}
368
369//_____________________________________________________________________________
371{
372 // Perform linear fit on drift times. Calculates slope, intercept, time
373 // offset t0, and errors.
374 // Accounts for different uncertainties of each drift distance.
375 //
376 // Fits the parameters m, b, and d0 in
377 //
378 // s_i ( d_i + d0 ) = m x_i + b
379 //
380 // where
381 // s_i = sign of ith drift distance (+/- 1)
382 // d_i = ith measured drift distance
383 // x_i = ith wire position
384 //
385 // The sign vector, s_i, is automatically optimized to yield the smallest
386 // chi^2. Normally, s_i = -1 for i < i_pivot, and s_i = 1 for i >= i_pivot,
387 // but this may occasionally not be the best choice in the presence of
388 // a significant negative offset d0.
389 //
390 // The results, m, b, and d0, are converted to the "slope" and "intercept"
391 // of the cluster geometry, where slope = 1/m and intercept = -b/m.
392 // d0 is simply converted to time units to give t0, using the asymptotic
393 // drift velocity.
394
395
396 fFitOK = false;
397 if( GetSize() < 4 || !fPlane ) {
398 return -1; // Too few hits to get meaningful results
399 // Do keep current values of slope and intercept
400 }
401
402 Double_t sigmaM = 0, sigmaB = 0, sigmaD0 = 0;
403
404 fCoord.clear();
405
406 //--- Copy hit data into local arrays
407 Int_t ihit = 0, incr = 1, ilast = GetSize()-1;
408 // Ensure that the first element of the local arrays always corresponds
409 // to the wire with the smallest x position
410 bool reversed = ( fPlane->GetWSpac() < 0 );
411 if( reversed ) {
412 ihit = ilast;
413 incr = -1;
414 }
415 for( Int_t i = 0; i < GetSize(); ihit += incr, ++i ) {
416 assert( ihit >= 0 && ihit < GetSize() );
417 Double_t x = fHits[ihit]->GetPos();
418 Double_t y = fHits[ihit]->GetDist() + fTimeCorrection;
419
420 Double_t wt = fHits[ihit]->GetdDist();
421 if( wt>0 ) // the hit will be ignored if the uncertainty is <= 0
422 wt = 1./(wt*wt);
423 else
424 wt = -1.;
425
426 fCoord.push_back( FitCoord_t(x,y,wt) );
427
428 assert( i == 0 || fCoord[i-1].x < fCoord[i].x );
429 }
430
431 Double_t bestFit = 0.0;
432
433 //--- Perform 3-parameter for different sign coefficients
434 //
435 // We make some simplifying assumptions:
436 // - The first wire of the cluster always has negative drift distance.
437 // - The last wire always has positive drift.
438 // - The sign flips exactly once from - to + somewhere in between
439 fCoord[0].s = -1;
440 for( Int_t i = 1; i < GetSize(); ++i )
441 fCoord[i].s = 1;
442
443 for( Int_t ipivot = 0; ipivot < ilast; ++ipivot ) {
444 if( ipivot != 0 )
445 fCoord[ipivot].s *= -1;
446
447 // Do the fit
448 Double_t m = kBig, b = kBig, d0 = kBig;
449 Linear3DFit( m, b, d0 );
450
451 // calculate chi2 for the track given this slope,
452 // intercept, and distance offset
453 chi2_t chi2 = CalcChisquare( m, b, d0 );
454
455 // scale the uncertainty of the fit parameters based upon the
456 // quality of the fit. This really should not be necessary if
457 // we believe the drift-distance uncertainties
458// sigmaM *= chi2/(nhits - 2);
459// sigmaB *= chi2/(nhits - 2);
460
461 // Pick the better value
462 if( ipivot == 0 || chi2.first < bestFit ) {
463 bestFit = fChi2 = chi2.first;
464 fNDoF = chi2.second - 3;
465 fLocalSlope = m;
466 fInt = b;
467 fT0 = d0;
468 fSigmaSlope = sigmaM;
469 fSigmaInt = sigmaB;
470 fSigmaT0 = sigmaD0;
471 }
472 }
473
474 // Rotate the coordinate system to match the VDC definition of "slope"
475 fLocalSlope = 1.0/fLocalSlope; // 1/m
476 fInt = -fInt * fLocalSlope; // -b/m
477 fT0 /= fPlane->GetDriftVel();
479
480 fFitOK = true;
481
482 return 0;
483}
484
485//_____________________________________________________________________________
487{
488 // 3-parameter fit
489// Double_t F, sigmaF2; // intermediate slope and St. Dev.**2
490// Double_t G, sigmaG2; // intermediate intercept and St. Dev.**2
491// Double_t sigmaFG; // correlated uncertainty
492
493 Double_t sumX = 0.0; //Positions
494 Double_t sumXX = 0.0;
495 Double_t sumD = 0.0; //Drift distances
496// Double_t sumXD = 0.0;
497 Double_t sumS = 0.0; //sign vector
498 Double_t sumSX = 0.0;
499 Double_t sumSD = 0.0;
500 Double_t sumSDX = 0.0;
501
502 // Double_t sumXW = 0.0;
503 // Double_t sumXXW= 0.0;
504
505 Double_t sumW = 0.0;
506 // Double_t sumWW = 0.0;
507 // Double_t sumDD = 0.0;
508
509
510 for (int j = 0; j < GetSize(); j++) {
511 Double_t x = fCoord[j].x; // Position of wire
512 Double_t d = fCoord[j].y; // Distance to wire
513 Double_t w = fCoord[j].w; // Weight/error of distance measurement
514 Int_t s = fCoord[j].s; // Sign of distance
515
516 if (w <= 0) continue;
517
518 sumX += x * w;
519 sumXX += x * x * w;
520 sumD += d * w;
521// sumXD += x * d * w;
522 sumS += s * w;
523 sumSX += s * x * w;
524 sumSD += s * d * w;
525 sumSDX += s * d * x * w;
526 sumW += w;
527 // sumWW += w*w;
528 // sumXW += x * w * w;
529 // sumXXW += x * x * w * w;
530 // sumDD += d * d * w;
531 }
532
533 // Standard formulae for linear regression (see Bevington)
534 Double_t Delta =
535 sumXX * ( sumW * sumW - sumW * sumS ) -
536 sumX * ( sumX * sumW - sumX * sumS );
537
538 m =
539 sumSDX * ( sumW * sumW - sumW * sumS ) -
540 sumSD * ( sumX * sumW - sumW * sumSX ) +
541 sumD * ( sumX * sumS - sumW * sumSX );
542
543 b =
544 -sumSDX * ( sumX * sumW - sumX * sumS ) +
545 sumSD * ( sumXX * sumW - sumX * sumSX ) -
546 sumD * ( sumXX * sumS - sumX - sumSX );
547
548 d0 = ( sumD - sumSD ) * ( sumXX * sumW - sumX * sumX );
549
550 m /= Delta;
551 b /= Delta;
552 d0 /= Delta;
553
554
555 // F = (sumXX * sumD - sumX * sumXD) / Delta;
556 // G = (sumW * sumXD - sumX * sumD) / Delta;
557 // sigmaF2 = ( sumXX / Delta );
558 // sigmaG2 = ( sumW / Delta );
559 // sigmaFG = ( sumXW * sumW * sumXX - sumXXW * sumW * sumX
560 // - sumWW * sumX * sumXX + sumXW * sumX * sumX ) / (Delta*Delta);
561
562 // m = 1/G;
563 // b = - F/G;
564
565 // sigmaM = m * m * TMath::Sqrt( sigmaG2 );
566 // sigmaB = TMath::Sqrt( sigmaF2/(G*G) + F*F/(G*G*G*G)*sigmaG2 - 2*F/(G*G*G)*sigmaFG);
567
568}
569
570//_____________________________________________________________________________
572{
573 // Get wire number of cluster pivot (hit with smallest drift distance)
574
575 return fPivot ? fPivot->GetWireNum() : -1;
576}
577
578
579//_____________________________________________________________________________
581{
582 // Mark this cluster as used by the given track whose number (index+1) is num
583
584 Int_t num = track ? track->GetTrkNum() : 0;
585
586 // Mark all hits
587 // FIXME: naahh - only the hits used in the fit! (ignore for now)
588 for( int i=0; i<GetSize(); i++ ) {
589 // Bugcheck: hits must either be unused or been used by this cluster's
590 // track (so SetTrack(0) can release a cluster from a track)
591 assert( fHits[i] );
592 assert( fHits[i]->GetTrkNum() == 0 || fHits[i]->GetTrkNum() == fTrkNum );
593
594 fHits[i]->SetTrkNum( num );
595 }
596 fTrack = track;
597 fTrkNum = num;
598}
599
600//_____________________________________________________________________________
602 Double_t d0 ) const
603{
604 Int_t npt = 0;
605 Double_t chi2 = 0;
606 for( int j = 0; j < GetSize(); ++j ) {
607 Double_t x = fCoord[j].x;
608 Double_t y = fCoord[j].s * fCoord[j].y;
609 Double_t w = fCoord[j].w;
610 Double_t yp = x*slope + icpt + d0*fCoord[j].s;
611 if( w < 0 ) continue;
612 Double_t d = y-yp;
613 chi2 += d*d*w;
614 ++npt;
615 }
616 return make_pair( chi2, npt );
617}
618
619//_____________________________________________________________________________
621 Double_t slope, bool do_print ) const
622{
623 // Implementation of chi2 calculation for this cluster.
624
625 if( TMath::Abs(slope) < 1e-3 ) {
626 // Near zero slope = perpendicular incidence. No meaningful chi2 can be
627 // calculated because such a track would only cross one, maybe two, cells.
628 chi2 += kBig;
629 nhits += GetSize();
630 return;
631 }
632
633 // Parameters of the track in the flipped coordinate system where the
634 // independent, uncertainty-free variable x is the wire position.
635 Double_t m = 1.0/slope;
636 Double_t b = -fInt*m;
637
638 bool past_pivot = false;
639 Int_t nHits = GetSize();
640 for (int j = 0; j < nHits; ++j) {
641 Double_t x = fHits[j]->GetPos();
642 Double_t y = fHits[j]->GetDist() + fTimeCorrection;
643 Double_t dy = fHits[j]->GetdDist();
644 // The Y calculation is numerically not quite optimal since it is a
645 // difference of two relatively large numbers. The result is 2 to 4 orders
646 // of magnitude smaller than each term. This should fit easily within
647 // double precision, however.
648 Double_t Y = m*x + b;
649
650 // Handle negative slopes correctly for generality. With the VDCs,
651 // negative slopes never correspond to signal tracks.
652 if (m<0) y = -y;
653
654 if (past_pivot)
655 y = -y;
656 else if (fHits[j] == fPivot) {
657 // Test the other side of the pivot wire, take the 'best' choice.
658 // This isn't statistically correct, but it's the best one can do
659 // since the sign of the drift distances isn't measured.
660 if (TMath::Abs(y-Y) > TMath::Abs(y+Y))
661 y = -y;
662 past_pivot = true;
663 }
664 if (dy <= 0) continue;
665
666 if (do_print) {
667 cout << " " << (y-Y)/dy;
668 if( fHits[j] == fPivot )
669 cout << "*";
670 }
671
672 chi2 += (Y - y)/dy * (Y - y)/dy;
673 nhits++;
674 }
675}
676
677//_____________________________________________________________________________
678void THaVDCCluster::CalcChisquare( Double_t& chi2, Int_t& nhits ) const
679{
680 // Given the parameters of the track (global slope and intercept), calculate
681 // the chi2 for the cluster.
682
683 DoCalcChisquare( chi2, nhits, fSlope, false );
684}
685
686//_____________________________________________________________________________
688{
689 // Print contents of cluster
690
691 Int_t nHits = GetSize();
692 if( fPlane )
693 cout << "Plane: " << fPlane->GetPrefix() << endl;
694 cout << "Size: " << nHits << endl;
695
696 cout << "Wire numbers:";
697 for( int i = 0; i < nHits; i++ ) {
698 cout << " " << fHits[i]->GetWireNum();
699 if( fHits[i] == fPivot )
700 cout << "*";
701 }
702 cout << endl;
703 cout << "Wire raw times:";
704 for( int i = 0; i < nHits; i++ ) {
705 cout << " " << fHits[i]->GetRawTime();
706 if( fHits[i] == fPivot )
707 cout << "*";
708 }
709 cout << endl;
710 cout << "Wire times:";
711 for( int i = 0; i < nHits; i++ ) {
712 cout << " " << fHits[i]->GetTime();
713 if( fHits[i] == fPivot )
714 cout << "*";
715 }
716 cout << endl;
717 cout << "Wire positions:";
718 for( int i = 0; i < nHits; i++ ) {
719 cout << " " << fHits[i]->GetPos();
720 if( fHits[i] == fPivot )
721 cout << "*";
722 }
723 cout << endl;
724 cout << "Wire drifts:";
725 for( int i = 0; i < nHits; i++ ) {
726 cout << " " << fHits[i]->GetDist();
727 if( fHits[i] == fPivot )
728 cout << "*";
729 }
730 cout << endl;
731 cout << "Wire drifts sigmas:";
732 for( int i = 0; i < nHits; i++ ) {
733 cout << " " << fHits[i]->GetdDist();
734 if( fHits[i] == fPivot )
735 cout << "*";
736 }
737 cout << endl;
738
739 cout << "Fit done: " << fFitOK << endl;
740 cout << "Crossing pos (err) = "
741 << fInt << " (" << fSigmaInt << ")" << endl
742 << "Local slope (err) = "
743 << fLocalSlope << " (" << fSigmaSlope << ")" << endl
744 << "Global slope = "
745 << fSlope << endl
746 << "Time offset (err) = "
747 << fT0 << " (" << fSigmaT0 << ")" << endl;
748
749 if( fFitOK ) {
750 Double_t chi2 = 0, lchi2 = 0;
751 Int_t nhits = 0;
752 cout << "Local residuals = ";
753 DoCalcChisquare( lchi2, nhits, fLocalSlope, true );
754 cout << endl;
755 nhits = 0;
756 cout << "Global residuals = ";
757 DoCalcChisquare( chi2, nhits, fSlope, true );
758 cout << endl;
759 cout << "Local/global chi2 = " << lchi2 << ", " << chi2 << endl;
760 }
761}
762
int Int_t
const Data_t kBig
Definition DataType.h:15
uint32_t time
#define d(i)
#define e(i)
bool Bool_t
const Int_t kMaxInt
double Double_t
const char Option_t
winID w
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char mode
static const Int_t kDefaultNHit
const char * GetPrefix() const
Double_t GetDPhi() const
Definition THaTrack.h:101
Double_t GetDX() const
Definition THaTrack.h:98
Double_t GetDTheta() const
Definition THaTrack.h:100
Int_t GetTrkNum() const
Definition THaTrack.h:84
Int_t GetIndex() const
Definition THaTrack.h:79
Double_t GetDY() const
Definition THaTrack.h:99
Int_t GetTrackIndex() const
virtual void Clear(Option_t *opt="")
THaVDCPlane * fPlane
Double_t fTimeCorrection
THaVDCHit * fPivot
virtual void EstTrackParameters()
VDC::VDCpp_t * fPointPair
Double_t fLocalSlope
THaTrack * fTrack
virtual void Print(Option_t *opt="") const
Double_t fSigmaSlope
virtual void ClearFit()
void SetTrack(THaTrack *track)
Int_t GetTrkNum() const
void FitSimpleTrack(Bool_t weighted=false)
VDC::Vhit_t fHits
virtual void ConvertTimeToDist()
VDC::Vcoord_t fCoord
Int_t GetSize() const
virtual void AddHit(THaVDCHit *hit)
virtual Int_t Compare(const TObject *obj) const
virtual void FitTrack(EMode mode=kSimple)
Double_t fSigmaT0
VDC::chi2_t CalcDist()
virtual void CalcChisquare(Double_t &chi2, Int_t &nhits) const
Double_t fSigmaInt
void Linear3DFit(Double_t &slope, Double_t &icpt, Double_t &d0) const
Int_t GetPivotWireNum() const
Int_t LinearClusterFitWithT0()
THaVDCCluster(THaVDCPlane *owner=nullptr)
void DoCalcChisquare(Double_t &chi2, Int_t &nhits, Double_t slope, bool do_print=false) const
Int_t GetWireNum() const
Definition THaVDCHit.h:33
Double_t GetPos() const
Definition THaVDCHit.h:37
Double_t GetSinWAngle() const
Definition THaVDCPlane.h:66
Double_t GetWSpac() const
Definition THaVDCPlane.h:63
Double_t GetZ() const
Definition THaVDCPlane.h:61
Double_t GetCosWAngle() const
Definition THaVDCPlane.h:65
Double_t GetDriftVel() const
Definition THaVDCPlane.h:68
virtual TClass * IsA() const
Double_t y[n]
Double_t x[n]
#define F(x, y, z)
constexpr Double_t G()
Double_t Sqrt(Double_t x)
Double_t Abs(Double_t d)
std::pair< Double_t, Int_t > chi2_t
STL namespace.
TMarker m
ClassImp(TPyArg)