StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StiKalmanTrack.cxx
1 //StiKalmanTrack.cxx
2 /*
3  * $Id: StiKalmanTrack.cxx,v 2.167 2019/04/28 02:36:42 genevb Exp $
4  * $Id: StiKalmanTrack.cxx,v 2.167 2019/04/28 02:36:42 genevb Exp $
5  *
6  * /author Claude Pruneau
7  *
8  * $Log: StiKalmanTrack.cxx,v $
9  * Revision 2.167 2019/04/28 02:36:42 genevb
10  * Restore NHitsPossible by swimming through other layers in getAllPointCount() after removing from initalize0()
11  *
12  * Revision 2.166 2019/04/13 02:11:27 genevb
13  * Remove swimming through hit-less TPC layers in initialize0 importing StiCA seeds (resolves RT3388)
14  *
15  * Revision 2.165 2018/11/27 20:21:57 smirnovd
16  * Correct indentation, white space, and comments
17  *
18  * Revision 2.164 2018/11/27 20:21:51 smirnovd
19  * Use bitwise AND operator instead of logical one
20  *
21  * This is the correct way to check a bit set in 'mode'
22  *
23  * Revision 2.163 2018/11/27 20:21:44 smirnovd
24  * Properly set default mode for StiKalmanTrack::approx()
25  *
26  * Revision 2.162 2018/11/27 20:21:38 smirnovd
27  * Remove unused local variables
28  *
29  * Revision 2.161 2018/11/27 20:21:32 smirnovd
30  * Remove unused function argument
31  *
32  * Revision 2.160 2018/11/27 20:21:24 smirnovd
33  * Remove debug code
34  *
35  * Revision 2.159 2018/11/27 20:21:16 smirnovd
36  * Remove commented out code
37  *
38  * Revision 2.158 2018/11/13 18:40:20 perev
39  * Put back constant for approx()
40  *
41  * Revision 2.157 2018/11/10 03:15:24 perev
42  * JetCorr fix +tuning
43  *
44  * Revision 2.156 2018/11/10 00:45:31 perev
45  * 1. for approx() added options:
46  * kAppGud - errors are correct
47  * kAppRR - fit with errors
48  * kAppUpd - update only one node
49  * kAppUPD - update all nodes
50  * 2. Fit in direction inner ==> outer
51  *
52  * Revision 2.155 2018/07/06 22:13:16 smirnovd
53  * [Cosmetic] Remove unused variables and commented code
54  *
55  * Revision 2.154 2018/06/29 21:46:27 smirnovd
56  * Revert iTPC-related changes committed on 2018-06-20 through 2018-06-28
57  *
58  * Revert "NoDead option added"
59  * Revert "Fill mag field more carefully"
60  * Revert "Assert commented out"
61  * Revert "Merging with TPC group code"
62  * Revert "Remove too strong assert"
63  * Revert "Restore removed by mistake line"
64  * Revert "Remove not used anymore file"
65  * Revert "iTPCheckIn"
66  *
67  * Revision 2.152 2018/04/30 23:18:11 smirnovd
68  * [Cosmetic] Minor changes in various files
69  *
70  * - Renamed data member s/m/mMass/ in StikalmanTrack
71  * - Changes in white space
72  * - Return STAR code
73  *
74  * Revision 2.151 2018/04/11 02:41:08 smirnovd
75  * Remove deprecated methods in StikalmanTrack
76  *
77  * Revision 2.150 2018/04/11 02:40:55 smirnovd
78  * Add new method StikalmanTrack::getInnerMostDetHitNode()
79  *
80  * Use it in StiCA to replace getInnerMostTPCHitNode()
81  *
82  * Revision 2.149 2018/04/10 11:38:34 smirnovd
83  * Replace thrown exceptions with runtime asserts
84  *
85  * Revision 2.148 2018/01/12 23:17:09 smirnovd
86  * Removed declared but undefined functions
87  *
88  * Revision 2.147 2017/01/26 21:32:41 perev
89  * 1. Method removeNode added. It removes node from the track.
90  * It becames important for the case with reuse hits when old Dca node
91  * is not more correct and must be removed and new one created
92  * 2. Method getChi2Max() added to calculate maximal bad node.
93  * It could (but not yet used) for filtering with reuse hits ON.
94  * 3. Method idTruth added. It uses idTruth's of hits and calculates
95  * dominant contrubutor
96  *
97  * Revision 2.146 2016/11/07 22:42:13 perev
98  * 1. Workaround for the bug in CA #3233 moved into StiCA
99  * 2. Bug #3231, Layer radius replaced by Normal one
100  * 3. Workaround for bug #3232 modified. Now node parameters for the case
101  * wrong ones from CA recalculated for both, first and last node.
102  * This must help to refit().
103  * 4. Simplified code in refitL()
104  *
105  * Revision 2.145 2016/07/08 16:16:55 perev
106  * It is workaround for bug in CA (#3230). CA sometimes gives the same hit twice
107  * Here I test all hits to be in decreasing order of x() (local x).
108  * If not, bad hits skipped.
109  * It is not the best way, it is better to fix it inside CA.
110  * but temporary it will work(VP)
111  *
112  * Revision 2.144 2016/07/07 01:15:00 perev
113  * Removed changing of timesUsed in releaseHits.
114  * This method is called inside refit when hits is not yet marked as used
115  *
116  * Revision 2.143 2016/06/30 19:51:52 perev
117  * WarnOff
118  *
119  * Revision 2.142 2016/06/29 18:18:30 perev
120  * See comments in StiKalmanTrack.h
121  *
122  * Revision 2.139.4.5 2016/06/02 16:50:03 smirnovd
123  * StiKalmanTrack: Refactored public refit() to use protected refit(int&)
124  *
125  * Two return values from protected refit(int&) can be used in different context.
126  * For example, derived class StiCAKalmanTrack return a value different from the
127  * base class.
128  *
129  * Revision 2.139.4.4 2016/06/02 16:45:42 smirnovd
130  * Squashed changes on MAIN branch after StiCA_2016 was brached off
131  *
132  * commit 0b534582b5bf40a64870088f6864387a7941a9be
133  * Author: perev <perev>
134  * Date: Tue May 31 17:11:46 2016 +0000
135  *
136  * Coverity
137  *
138  * commit cbfeeef5e8f9a6e24ddd7329ff5770086e535493
139  * Author: perev <perev>
140  * Date: Tue Apr 19 01:58:39 2016 +0000
141  *
142  * Assignment out of array boundary removed(J.Lauret)
143  *
144  * commit a49f5f23dc613c1ee8ab61c543e713f776d3c7fe
145  * Author: perev <perev>
146  * Date: Tue Apr 19 01:37:22 2016 +0000
147  *
148  * WarnOff
149  *
150  * commit 48ca225cc052db66cd8a3934f15c46345c9862c6
151  * Author: perev <perev>
152  * Date: Fri Apr 15 20:47:42 2016 +0000
153  *
154  * Warnoff
155  *
156  * commit b1b0f73cef0f5675bd84106241067329e0221079
157  * Author: perev <perev>
158  * Date: Fri Apr 15 20:13:06 2016 +0000
159  *
160  * Warnoff
161  *
162  * commit 393adde57febc06a90d054f71e621e8efd082e10
163  * Author: perev <perev>
164  * Date: Wed Apr 13 23:08:44 2016 +0000
165  *
166  * -opt2 proble solved. Array A[1] removed
167  *
168  * commit 1c105bdc0cbde40ccec63fdbf40e79dfb3e7f0e0
169  * Author: perev <perev>
170  * Date: Mon Mar 28 00:17:55 2016 +0000
171  *
172  * 1st hit must be not used at all
173  *
174  * commit 1eca42192ef93788d149625ecebc8390f8b0bc3a
175  * Author: perev <perev>
176  * Date: Mon Mar 28 00:15:53 2016 +0000
177  *
178  * Add max number of tracks assigned to one hit
179  *
180  * commit b349ba99342bc38eaa82f3d2a8d25aa29ba73c29
181  * Author: genevb <genevb>
182  * Date: Thu Feb 25 23:04:50 2016 +0000
183  *
184  * kSsdId => kSstId
185  *
186  * commit a06d8162931b223b4a405ea5714e703b1cad14e3
187  * Author: perev <perev>
188  * Date: Mon Dec 28 23:50:27 2015 +0000
189  *
190  * Remove assert temporary
191  *
192  * commit f8646d17ed86b9be5b5fa940691f9871346a5ee2
193  * Author: perev <perev>
194  * Date: Mon Dec 21 19:41:31 2015 +0000
195  *
196  * bug #3166 assert vertex closer to 0,0 <9 removed
197  *
198  * commit 48a6813db30f593a90a79beb688c27d0e8946bfa
199  * Author: perev <perev>
200  * Date: Sat Dec 19 03:40:50 2015 +0000
201  *
202  * assert rxy<4 ==> <9 temporary
203  *
204  * commit d49576f25ba887ba4ff82c3bf1ffcc760c8da6b2
205  * Author: perev <perev>
206  * Date: Fri Dec 18 03:50:06 2015 +0000
207  *
208  * *** empty log message ***
209  *
210  * commit 23e9c0447bd41151e45728a6f4dd3cc554be1cfb
211  * Author: perev <perev>
212  * Date: Thu Dec 3 19:12:24 2015 +0000
213  *
214  * Remove redundant GTrack error: mFlag: is Negative
215  *
216  * Revision 2.140 2016/04/13 23:08:44 perev
217  * -opt2 proble solved. Array A[1] removed
218  *
219  * Revision 2.139 2015/04/02 16:29:16 perev
220  * Member mCombUsed introdused to memorize combination of hits selected
221  * Enum keepHit and kGoodHir added instead of using 1 & 2.
222  * StiKalmanTrack::add added new parameter StiTrackNode *near. It allows
223  * to add node in the middle. It is important for combinatorics.
224  * It is not clear how it was working before, but there is no time to investigate
225  *
226  * Revision 2.138 2015/02/09 15:47:59 genevb
227  * Restore inversion of hh because it is used in multiple places
228  *
229  * Revision 2.137 2015/02/09 04:14:52 perev
230  * Remove redundant hit->subTimesUsed() + Cleanup
231  *
232  * Revision 2.136 2015/02/07 04:21:05 perev
233  * More accurate zero field accounting
234  *
235  * Revision 2.135 2015/02/02 04:37:19 perev
236  * replacemens of names *TimesUsed to new versions
237  *
238  * Revision 2.134 2015/01/15 19:10:19 perev
239  * Added mthod test() for debug only
240  *
241  * Revision 2.133 2014/11/10 21:45:09 perev
242  * In approx more carefully accounted case mag field == 0
243  * To deside that field == 0 method isZeroH() is used
244  *
245  * Revision 2.132 2014/10/30 15:03:54 jeromel
246  * Reverted to Oct 2nd
247  *
248  * Revision 2.127 2014/09/29 21:44:55 perev
249  * Check cos>=1 replaced to cos>=.99
250  *
251  * Revision 2.126 2014/07/09 00:15:45 perev
252  * Fix wrong Xi2 for 5hits track
253  *
254  * Revision 2.125 2013/04/10 22:09:01 fisyak
255  * Roll back to version 04/04/2013
256  *
257  * Revision 2.123 2012/03/12 23:17:12 fisyak
258  * Correct detectorOld cast for StiCA
259  *
260  * Revision 2.122 2012/03/12 20:51:42 fisyak
261  * Restrict new No. possible point calculation to StiCA only
262  *
263  * Revision 2.121 2011/11/21 17:05:26 fisyak
264  * Correct no. of possible point for CA case
265  *
266  * Revision 2.120 2010/09/07 18:37:31 fisyak
267  * Restore Sti logic before TPCCATracker
268  *
269  * Revision 2.119 2010/09/06 18:20:48 fisyak
270  * Add TPCCATracker
271  *
272  * Revision 1.8 2010/08/25 21:34:05 ikulakov
273  * Warnings fix.
274  *
275  * Revision 1.7 2010/08/23 21:56:28 ikulakov
276  * Fix - alinghment bag.
277  *
278  * Revision 1.6 2010/08/09 17:51:14 mzyzak
279  * StiPerformance is added; bug with cov matrix of the seed parameters is fixed; bug with the q/p sign of the seed parameters is fixed; functionality of the performance is extended
280  *
281  * Revision 1.5 2010/08/05 21:16:53 ikulakov
282  * Add fit status statistic.
283  *
284  * Revision 1.4 2010/08/04 13:45:46 ikulakov
285  * Fix - hz & sign pt.
286  *
287  * Revision 1.3 2010/08/02 16:45:27 ikulakov
288  * Use tracks params obtained from CATracker for StRoot KF fitter initialization.
289  *
290  * Revision 1.2 2010/07/29 16:19:11 fisyak
291  * GSI CA tracker
292  *
293  * Revision 2.118 2010/04/03 04:04:57 perev
294  * Account field=0
295  *
296  * Revision 2.117 2010/02/17 14:28:07 fisyak
297  * Add seed quality information
298  *
299  * Revision 2.116 2009/10/18 22:49:52 perev
300  * remove STAR LOG in print()
301  *
302  * Revision 2.115 2009/10/15 03:30:20 perev
303  * Add primary vertex number
304  *
305  * Revision 2.114 2009/03/16 13:50:15 fisyak
306  * Move out all Sti Chairs into StDetectorDb
307  *
308  * Revision 2.113 2008/10/27 21:01:30 perev
309  * Free not used hits again
310  *
311  * Revision 2.112 2008/07/23 18:41:52 fisyak
312  * Remove 100 cm cut on hit radius to calculate DcaGeometry,,bug 1243, left after big step back
313  *
314  * Revision 2.111 2008/06/09 20:12:07 perev
315  * BigStepBack
316  *
317  * Revision 2.104 2008/04/08 21:39:43 perev
318  * No any cuts in isPrimary()
319  *
320  * Revision 2.103 2008/04/08 14:21:17 fisyak
321  * 2 cm => StiKalmanTrackFinderParameters::instance()->maxDca3dVertex() in StiKalmanTrack::isPrimary()
322  *
323  * Revision 2.102 2008/04/07 19:20:53 perev
324  * More clear isPrimary()
325  *
326  * Revision 2.101 2008/04/03 20:03:33 fisyak
327  * Straighten out DB access via chairs
328  *
329  * Revision 2.100 2008/03/24 21:38:46 jeromel
330  * Undo setTimesUsed() - seeding seems to not take advantage of more hits (TBC)
331  *
332  * Revision 2.99 2008/03/24 19:32:03 perev
333  * BugFix vertex is not SvtHit
334  *
335  * Revision 2.98 2008/03/20 01:31:16 perev
336  * HitSet rejecting via StiKalmanTrackFinderParameters
337  *
338  * Revision 2.97 2007/12/20 01:10:18 perev
339  * WarnOff
340  *
341  * Revision 2.96 2007/09/10 00:34:28 perev
342  * member mgMaxRefiter added
343  *
344  * Revision 2.95 2007/08/16 20:21:23 fine
345  * replace printf with logger
346  *
347  * Revision 2.94 2007/06/26 19:17:25 perev
348  * Path to hit in 2dim space only
349  *
350  * Revision 2.93 2007/06/25 19:35:10 perev
351  * DEbug off
352  *
353  * Revision 2.92 2007/06/25 19:28:50 perev
354  * New better THelix fit in approx
355  *
356  * Revision 2.91 2007/03/21 17:49:16 fisyak
357  * add includes for ROOT 5.14
358  *
359  * Revision 2.90 2006/12/19 19:50:01 perev
360  * method getPoint added
361  *
362  * Revision 2.89 2006/12/18 01:14:08 perev
363  * operator= added
364  *
365  * Revision 2.88 2006/10/16 20:29:35 fisyak
366  * Clean up useless classes
367  *
368  * Revision 2.87 2006/10/09 15:47:06 fisyak
369  * take out Central represantation, remove StiDedxCalculator
370  *
371  * Revision 2.86 2006/05/31 03:58:06 fisyak
372  * Add Victor's dca track parameters, clean up
373  *
374  * Revision 2.85 2006/04/26 19:17:05 perev
375  * mIdDb for debug instead of mId
376  *
377  * Revision 2.84 2006/04/15 23:11:18 perev
378  * For zero field min curvature 1/1km
379  *
380  * Revision 2.83 2006/04/07 18:01:55 perev
381  * Back to the latest Sti
382  *
383  * Revision 2.80 2006/02/21 23:25:51 perev
384  * StiConfidence flag added
385  *
386  * Revision 2.79 2006/02/16 01:58:43 perev
387  * StiOldRefit env added
388  *
389  * Revision 2.78 2006/02/14 18:04:45 perev
390  * approx() accounts errors now
391  *
392  * Revision 2.77 2005/12/31 01:38:50 perev
393  * Primary track can loose few nodes
394  *
395  * Revision 2.76 2005/12/18 23:39:20 perev
396  * Cleanup
397  *
398  * Revision 2.75 2005/12/08 21:18:35 perev
399  * track id must < 2*16
400  *
401  * Revision 2.74 2005/12/07 21:30:32 perev
402  * new refit,refitL,approx etc...
403  *
404  * Revision 2.73 2005/10/26 21:55:02 fisyak
405  * get rid off dependencies from StMcEvent
406  *
407  * Revision 2.72 2005/08/18 02:35:23 perev
408  * Cleanup
409  *
410  * Revision 2.71 2005/08/17 22:00:17 perev
411  * getAllPointCount(...) added
412  *
413  * Revision 2.70 2005/08/16 20:11:10 perev
414  * Typo corrected
415  *
416  * Revision 2.69 2005/08/14 01:10:55 perev
417  * Non empty unset(). Free all nodes when track is freed
418  *
419  * Revision 2.68 2005/08/09 14:51:25 perev
420  * Add reduce method, reducing all the nodes
421  *
422  * Revision 2.67 2005/08/04 03:50:31 perev
423  * removeLastNode() added
424  *
425  * Revision 2.66 2005/07/20 17:21:44 perev
426  * MultiVertex
427  *
428  * Revision 2.65 2005/06/09 03:12:39 perev
429  * Fix typo in getNodes()
430  *
431  * Revision 2.64 2005/05/31 16:33:32 perev
432  * Method refitL added
433  *
434  * Revision 2.63 2005/05/13 19:33:11 perev
435  * Defence against all nodes are bad added
436  *
437  * Revision 2.62 2005/05/12 17:56:17 perev
438  * refit tuned
439  *
440  * Revision 2.61 2005/04/11 17:27:59 perev
441  * Error status added to fit()
442  *
443  * Revision 2.60 2005/03/31 18:14:00 perev
444  * getMaxPointCount() fixed(thank to Jan)
445  *
446  * Revision 2.59 2005/03/31 17:25:57 perev
447  * getMaxPointCount() fixed(thank to Jan)
448  *
449  * Revision 2.58 2005/03/28 05:48:49 perev
450  * Reorganization of node container
451  *
452  * Revision 2.57 2005/03/24 17:59:38 perev
453  * refit() method added
454  *
455  * Revision 2.56 2005/03/17 06:19:36 perev
456  * Cleanup
457  *
458  * Revision 2.55 2005/02/25 16:36:14 perev
459  * Iteration in refit added
460  *
461  * Revision 2.54 2005/02/18 19:02:31 fisyak
462  * Add debug print out for extendToVertex
463  *
464  * Revision 2.53 2005/02/17 23:19:02 perev
465  * NormalRefangle + Error reseting
466  *
467  * Revision 2.52 2005/02/17 19:58:06 fisyak
468  * Add debug print out flags
469  *
470  * Revision 2.51 2005/02/07 18:33:42 fisyak
471  * Add VMC dead material
472  *
473  * Revision 2.50 2005/01/17 01:31:25 perev
474  * New parameter model
475  *
476  * Revision 2.49 2004/12/23 15:06:28 pruneau
477  * use _alpha instead of getRefAngle while extending to vertex
478  *
479  * Revision 2.48 2004/12/11 04:31:36 perev
480  * set of bus fixed
481  *
482  * Revision 2.47 2004/12/01 18:04:32 perev
483  * test for -ve and too big track length added
484  *
485  * Revision 2.46 2004/12/01 03:57:08 pruneau
486  * d<4
487  *
488  * Revision 2.45 2004/11/12 22:48:28 fisyak
489  * Back to use chi2 instead DCA for Vertex fit
490  *
491  * Revision 2.44 2004/11/11 03:19:05 pruneau
492  * implementation of extrapolation functions for Jan
493  *
494  * Revision 2.43 2004/11/10 21:44:26 pruneau
495  * adding functions for extrapolation
496  *
497  * Revision 2.42 2004/11/08 15:32:50 pruneau
498  * 3 sets of modifications
499  * (1) Changed the StiPlacement class to hold keys to both the radial and angle placement. Propagated the use
500  * of those keys in StiSvt StiTpc StiSsd and all relevant Sti classes.
501  * (2) Changed the StiKalmanTrackFinder::find(StiTrack*) function's algorithm for the navigation of the
502  * detector volumes. The new code uses an iterator to visit all relevant volumes. The code is now more robust and compact
503  * as well as much easier to read and maintain.
504  * (3) Changed the chi2 calculation in StiKalmanTrack::getChi2 and propagated the effects of this change
505  * in both StiTrackingPlots and StiStEventFiller classes.
506  *
507  * Revision 2.41 2004/10/28 19:30:42 perev
508  * Hack. Infinite Chi2 skipped in Chi2 calculation. Claude??? (VP)
509  *
510  * Revision 2.40 2004/10/28 04:59:18 perev
511  * Fixed iterator for nodes. v3V2
512  *
513  * Revision 2.39 2004/10/27 03:25:49 perev
514  * Version V3V
515  *
516  * Revision 2.38 2004/10/26 21:52:07 pruneau
517  * No truncation but bad hits dropped
518  *
519  * Revision 2.37 2004/10/26 06:45:37 perev
520  * version V2V
521  *
522  * Revision 2.36 2004/10/25 14:15:49 pruneau
523  * various changes to improve track quality.
524  *
525  * Revision 2.35 2004/08/17 20:55:42 perev
526  * memory cleanup heap==>stack
527  *
528  * Revision 2.34 2004/08/06 02:28:53 andrewar
529  * Added getMaxPointCount(int detectorId)< where detectorId corresponds to the
530  * StDetectorId value.
531  *
532  * Revision 2.33 2004/04/04 23:19:28 jeromel
533  * isfinite() -> finite()
534  *
535  * Revision 2.32 2004/03/31 00:23:41 calderon
536  * -Fixed memory leak in StiDetectorTreeBuilder::hangWhere (100 chars were lost
537  * every time this function was called)
538  * -Changed algorithm to count fit points in StiKalmanTrack. Now it is based
539  * on counting the nodes that have a chi2 < chi2Max from
540  * StiKalmanTrackFitterParameters.
541  * -Which meant that I had to somehow introduce a pointer to it so that the
542  * track could know about the chi2Max used in the fitter.
543  * -And I also added a method to retrieve the pointer to the fitterParams
544  * to be used in StiStEventFiller.
545  * -Which was then modified to calculate the encoded fit points based on
546  * a similar algorithm (chi2<chi2Max test).
547  * -Cleaned up the includes in StiKalmanTrack.h, left only the ones
548  * needed to keep the code compiling.
549  * -Which required a slight modification in the include of StiKalmanTrackFinder
550  * -StiTrackKalmanTrackFitter now also sets a pointer to itself in
551  * static StiKalmanTrack::setFitParameters()
552  * -Removed some print outs from VectorizedFactory to reduce the size of the log
553  * files.
554  *
555  * Revision 2.31 2004/03/23 23:10:37 calderon
556  * Check for nan's in getTrackLength() calculation. When the argument for the
557  * asin() is >1, the code instead calculates a length iteratively.
558  * For these cases, the returned value is negative so that they can be inspected
559  * in the gui, or filtered in the StiStEventFiller.
560  *
561  * Revision 2.30 2004/02/21 18:27:34 pruneau
562  * Updates to comply with changes made in abstract interfaces.
563  *
564  * Revision 2.29 2003/09/02 17:59:41 perev
565  * gcc 3.2 updates + WarnOff
566  *
567  * Revision 2.28 2003/08/02 08:22:43 pruneau
568  * best performance so far
569  *
570  * Revision 2.27 2003/07/30 19:18:25 pruneau
571  * sigh
572  *
573  * Revision 2.25 2003/05/14 21:37:59 pruneau
574  * Fixed "chi2" problem. 5 first nodes on a track did not have
575  * relevant errors. Fix the problem by inserting a call to calculateError()
576  * inside the add(stiHit*...) method used while initializing tracks from the
577  * seed finder. CP
578  *
579  * Revision 2.24 2003/05/06 15:33:49 mmiller
580  * iCommitting changes to turn on multiple regions (StiPlacement::StiRegion -> kMidRapidity, kForwardRapidity, etc).
581  * Also added a point to StiToolkit for StiMaker. This allows for the req. GetDataSet calls in the FTPC code.
582  * Not so elegant...
583  *
584  * Revision 2.23 2003/04/29 18:48:21 pruneau
585  * *** empty log message ***
586  *
587  * Revision 2.22 2003/04/22 21:20:05 pruneau
588  * Added hit filter
589  * Tuning of finder pars
590  * Tuning of KalmanTrackNode
591  *
592  * Revision 2.21 2003/04/10 12:02:13 pruneau
593  * various changes
594  *
595  * Revision 2.20 2003/03/31 17:18:47 pruneau
596  * various
597  *
598  * Revision 2.19 2003/03/17 17:45:31 pruneau
599  * *** empty log message ***
600  *
601  * Revision 2.18 2003/03/14 20:50:29 pruneau
602  * Added groupId member and accessor functions to StiDetector, StiDetectorGroup, StiDetectorBuilder,
603  * and modified getNodes of the StiKalmanTrack class to use it. This eliminates explicit
604  * references to Tpc and Svt within StiKalmanTrack...
605  *
606  * Revision 2.17 2003/03/14 19:02:20 pruneau
607  * various minor updates
608  *
609  * Revision 2.16 2003/03/13 21:21:26 pruneau
610  * getPhase() fixed. MUST inclde -helicity()*pi/2
611  *
612  * Revision 2.15 2003/03/13 18:59:08 pruneau
613  * various updates
614  *
615  * Revision 2.14 2003/03/13 16:38:11 andrewar
616  * Made use of X0() calls in getTrackRadLength()
617  *
618  * Revision 2.13 2003/03/13 15:16:41 pruneau
619  * fixed getPhi, getPseudoRapdity, getPhase methods
620  *
621  * Revision 2.12 2003/03/12 17:57:29 pruneau
622  * Elss calc updated.
623  *
624  * Revision 2.11 2003/03/04 15:16:22 andrewar
625  * Added getTrackRadLength function to return radiation thickness along track (%).
626  *
627  */
628 
629 
630 #include <cassert>
631 //Std
632 #include <stdexcept>
633 #include <cmath>
634 
635 //SCL
636 #include "StThreeVector.hh"
637 #include "StThreeVectorF.hh"
638 #include "StThreeVectorD.hh"
639 #include "StPhysicalHelixD.hh"
640 #include "THelixTrack.h"
641 
642 #include "StHit.h"
643 
644 //Sti
645 #include "StiKalmanTrack.h"
646 #include "StiKalmanTrackFinder.h"
647 #include "StiToolkit.h"
648 #include "StiDetectorContainer.h"
649 #include "StiHit.h"
650 #include "StiKalmanTrackNode.h"
651 #include "StiKalmanTrack.h"
652 #include "StiDetector.h"
653 #include "StiDetectorGroups.h"
654 #include "StiDetectorBuilder.h"
655 #include "StiPlacement.h"
656 #include "StiMaterial.h"
657 #include "StDetectorDbMaker/StiHitErrorCalculator.h"
658 #include "StPhysicalHelixD.hh"
659 #include "StHelix.hh"
660 #include "StDetectorDbMaker/StiKalmanTrackFitterParameters.h"
661 #include "StDetectorDbMaker/StiKalmanTrackFinderParameters.h"
662 #include "StiHitContainer.h"
663 #include "StiUtilities/StiDebug.h"
664 #include "TCernLib.h"
665 #include "StMessMgr.h"
666 ostream& operator<<(ostream&, const StiHit&);
667 
668 Factory<StiKalmanTrackNode>* StiKalmanTrack::trackNodeFactory = 0;
670 int StiKalmanTrack::_debug = 0;
671 int debugCount=0;
672 
673 StiTrackNodeHelper StiKalmanTrack::sTNH;
674 
675 
686 //_____________________________________________________________________________
688 {
689 static int mIdCount = 0;
690  if ((++mIdCount) >= 1<<16) mIdCount = 1;
691  mIdDb = mIdCount;
692  firstNode = 0;
693  lastNode = 0;
694  mSeedHitCount = 0;
695  mCombUsed = 0;
696  mVertex = 0;
697  mMass = -1.;
698  mFlag = 0;
699  _dca = 0;
700  _vChi2=-2;
701  StiDebug::Break(mIdDb);
702 }
703 //_____________________________________________________________________________
708 //_____________________________________________________________________________
710 {
711  trackNodeFactory = val;
712 }
713 
714 
715 
716 //_____________________________________________________________________________
748 //_____________________________________________________________________________
749 int StiKalmanTrack::initialize(const std::vector<StiHit*> &hits)
750 {
751  reset();
752  const StiDetector* detector=0;
753  UInt_t nhits = hits.size();
754  setSeedHitCount(nhits);
755 
756  for (UInt_t ihit=0;ihit<nhits;ihit++)
757  {
758  StiHit *hit = hits[ihit]; //loop from in to out to keep sign of dir
759  detector = hit->detector();
760  assert(detector);
761  StiKalmanTrackNode * n = trackNodeFactory->getInstance();
762  n->initialize(hit);
763  add(n,kOutsideIn);
764  }
765 
766  int ierr = approx(kAppRR|kAppUPD);
767  if (!ierr) return 0;
768  BFactory::Free(this);
769  return 1;
770 }
771 //_____________________________________________________________________________
772 int StiKalmanTrack::initialize0(const std::vector<StiHit*> &hits, StiNodePars *firstPars, StiNodePars *lastPars, StiNodeErrs *firstErrs, StiNodeErrs *lastErrs)
773 {
774  reset();
775  const StiDetector* detector=0;
776  UInt_t nhits = hits.size();
777  setSeedHitCount(nhits);
778 
779  for (UInt_t ihit = 0; ihit < nhits; ihit++) {
780  StiHit *hit = hits[ihit];
781  detector = hit->detector();
782  assert(detector);
783  StiKalmanTrackNode * n = trackNodeFactory->getInstance();
784  n->initialize(hit);
785  add(n,kOutsideIn);
786  }
787  if (!firstPars) {approx(); return 0;}
788  else {firstNode->fitPars() = *firstPars;}
789 
790  if (firstErrs) {firstNode->fitErrs() = *firstErrs;}
791  if (lastPars) {lastNode ->fitPars() = *lastPars ;}
792  if (lastErrs) {lastNode->fitErrs() = *lastErrs ;}
793 
794  return 0;
795 }
796 
797 
798 
799 //_____________________________________________________________________________
806 //_____________________________________________________________________________
808 {
810  if (!node) return 0;
811  return node->getCharge();
812 }
813 
814 //_____________________________________________________________________________
821 {
822  double fitHits = 0;
823  double trackChi2 = 0;
824  double maxChi2 = StiKalmanTrackFitterParameters::instance()->getMaxChi2();
825  if (!firstNode) return 1.e+60;
826  StiKTNIterator it;
827  for (it=begin();it!=end();++it) {
828  StiKalmanTrackNode *node = &(*it);
829  if (!node->isValid()) continue;
830  if (!node->getHit() ) continue;
831  if (!node->getDetector()) continue;
832  double nodeChi2 = node->getChi2();
833  if (nodeChi2>maxChi2) continue;
834  trackChi2 += nodeChi2;
835  ++fitHits;
836  }
837  return (fitHits>3)?trackChi2/(2.*fitHits-5.):1e30;
838 }
839 //_____________________________________________________________________________
842 {
843  double trackChi2 = 0;
844  double maxChi2 = StiKalmanTrackFitterParameters::instance()->getMaxChi2();
845  if (!firstNode) return 1e11;
846  for (auto it=begin();it!=end();++it) {
847  StiKalmanTrackNode *node = &(*it);
848  if (!node->isValid()) continue;
849  if (!node->getHit() ) continue;
850  if (!node->getDetector()) continue;
851  double nodeChi2 = node->getChi2();
852  if (nodeChi2>maxChi2) continue;
853  if (trackChi2<nodeChi2) trackChi2=nodeChi2;
854  }
855  return trackChi2;
856 }
857 
867 //_____________________________________________________________________________
868 int StiKalmanTrack::getPointCount(int detectorId) const
869 {
870  const StiDetector *detector=0;
871  int nPts = 0;
872  StiKTNIterator it;
873  for (it=begin();it!=end();it++) {
874  StiKalmanTrackNode *node = &(*it);
875  if (!node->isValid()) continue;
876  if (!node->getHit()) continue;
877  detector = node->getDetector();
878  if (!detector) continue;
879  if (node->getChi2()>=1000) continue;
880  if (detectorId && detector->getGroupId() != detectorId) continue;
881  nPts++;
882  }
883  return nPts;
884 }
885 
886 //_____________________________________________________________________________
897 //_____________________________________________________________________________
898 int StiKalmanTrack::getMaxPointCount(int detectorId) const
899 {
900  int nPts = 0;
901  StiKTNIterator it;
902 
903  for (it=begin();it!=end();it++){
904  const StiKalmanTrackNode *node = &(*it);
905  if (!node->isValid()) continue;
906  const StiDetector *detector = node->getDetector();
907  if (!detector) continue;
908  StiHit* h = node->getHit();
909  if (!h && !detector->isActive(node->getY(),node->getZ())) continue;
910  if (detectorId && detector->getGroupId() != detectorId) continue;
911  nPts++;
912  }
913  return nPts;
914 }
915 
916 
917 //_____________________________________________________________________________
928 {
929  int gaps = 0;
930  if (firstNode)
931  {
932  StiKTNIterator it;
933  bool inGap = false;
934  for (it=begin();it!=end();it++)
935  {
936  const StiDetector * detector = (*it).getDetector();
937  if (detector && detector->isActive())
938  {
939  if ((*it).getHit())
940  {
941  if (inGap)
942  inGap = false;
943  }
944  else
945  {
946  if (!inGap)
947  {
948  inGap = true;
949  gaps++;
950  }
951  }
952  }
953  }
954  }
955  return gaps;
956 }
957 
958 //_____________________________________________________________________________
968 //_____________________________________________________________________________
970 int StiKalmanTrack::getFitPointCount(int detectorId) const
971 {
972  int fitPointCount = 0;
973  StiKTNIterator it;
974  for (it=begin();it!=end();it++) {
975  StiKalmanTrackNode* node = &(*it);
976  if(!node->isValid()) continue;
977  StiHit* hit = node->getHit();
978  if (!hit) continue;
979  if (!node->isFitted()) continue;
980  const StiDetector *det = hit->detector();
981  if (!det) continue;
982  if (detectorId && detectorId!=det->getGroupId())continue;
983  fitPointCount++;
984  }
985  return fitPointCount;
986 }
987 //_____________________________________________________________________________
988 void StiKalmanTrack::getAllPointCount(int count[1][3],int maxDetId) const
989 {
990 // output array actually is count[maxDetId+1][3]
991 // count[0] all detectors
992 // count[detId] for particular detector
993 // count[detId][0] == number of possible points
994 // count[detId][1] == number of measured points
995 // count[detId][2] == number of fitted points
996 enum {kPP=0,kMP=1,kFP=2};
997 
998  StiDetectorContainer *detectorContainer = StiToolkit::instance()->getDetectorContainer();
999  const StiDetector* detectorOld = 0;
1000 
1001  memset(count[0],0,(maxDetId+1)*3*sizeof(int));
1002  StiKTNIterator it;
1003 
1004  for (it=begin();it!=end();it++){
1005  const StiKalmanTrackNode *node = &(*it);
1006  if (!node->isValid()) continue;
1007  const StiDetector *detector = node->getDetector();
1008  if (!detector) continue;
1009  int detId = detector->getGroupId();
1010  StiHit* h = node->getHit();
1011  if (detectorOld && detId == kTpcId) {
1012  Double_t R = detector->getPlacement()->getNormalRadius();
1013  Double_t angle = detector->getPlacement()->getNormalRefAngle();
1014  Double_t R_OLD = detectorOld->getPlacement()->getNormalRadius();
1015  while (R < R_OLD) {
1016  detectorContainer->setToDetector( detectorOld );
1017  if ( detectorContainer->moveIn(TMath::DegToRad()*5,100,R)) {
1018  StiDetector* d = detectorContainer->getCurrentDetector(); //**detectorContainer;
1019  if (d == detector) break;
1020  detectorOld = d;
1021  R_OLD = detectorOld->getPlacement()->getNormalRadius();
1022  Double_t angle_OLD = detectorOld->getPlacement()->getNormalRefAngle();
1023  if (detectorOld->isActive() && R < R_OLD && TMath::Abs(angle - angle_OLD) < TMath::DegToRad()*5) { // the same sector
1024  count[0][kPP]++; count[detId][kPP]++;
1025  }
1026  } else break;
1027  }
1028  }
1029 
1030 //fill possible points
1031  if (h || detector->isActive(node->getY(),node->getZ())) {
1032  count[0][kPP]++; count[detId][kPP]++;
1033  }
1034  detectorOld = detector;
1035 
1036  if (!h ) continue;
1037 //fill measured points
1038  count[0][kMP]++; count[detId][kMP]++;
1039  if (!node->isFitted()) continue;
1040  count[0][kFP]++; count[detId][kFP]++;
1041  }
1042 }
1043 
1044 //_____________________________________________________________________________
1055 {
1056  double x[2][4];
1057  for (int i = 0; i < 4; i++){ x[0][i] = 0; }
1058  double len=0;
1059  int iready=0;
1060  StiKalmanTrackNode *node;
1061  StiKTNIterator it = begin();
1062  for (;(node=it());it++){
1063  if (!node->isValid()) continue;
1064  if (!node->getHit()) continue;
1065  if ( node->getChi2()>10000.)continue;
1066  x[1][0]=node->x_g();
1067  x[1][1]=node->y_g();
1068  x[1][2]=node->z_g();
1069  x[1][3]=node->getCurvature();
1070  if (iready) {
1071  double dlen = sqrt(pow(x[1][0]-x[0][0],2) + pow(x[1][1]-x[0][1],2));
1072  double curv = fabs(0.5*(x[0][3]+x[1][3]));
1073  double dsin = (0.5*dlen*curv);
1074  if (dsin>0.9) {
1075  LOG_DEBUG <<
1076  Form("StiKalmanTrack::getTrackLength ***ERROR*** dsin %g >.9",dsin)
1077  << endm;
1078  dsin = 0.9;
1079  }
1080  dlen = (dsin<0.1)? dlen*(1.+dsin*dsin/6) : 2*asin(dsin)/curv;
1081  len +=sqrt(dlen*dlen + pow(x[1][2]-x[0][2],2));
1082  }
1083  memcpy(x[0],x[1],4*sizeof(double)); iready=2005;
1084  }
1085  return len;
1086 }
1087 
1088 
1092 //_____________________________________________________________________________
1094 {
1095  double x1, x2, x3; //lengths in different media
1096  double totalR=0.;
1097  //Are we going in or out? Makes a difference which material to call
1098 
1099  StiKTNIterator tNode = begin();
1100 
1101  //set initial conditions for tNode, the 'current' node;
1102  //will also need 'nextNode', ie node which is next
1103  StiKalmanTrackNode *thisNode = &(*tNode);
1104 
1105  x1=thisNode->pathlength()/2.;
1106  x3=0.;
1107 
1108 
1109  // while ((++tNode)!=end() && (*tNode).getDetector())
1110  while ((tNode++)!=end() && (*tNode).getDetector())
1111  {
1112 
1113  StiKalmanTrackNode *nextNode = &(*(tNode)); //incrimented tNode
1114 
1115 
1116  x2=thisNode->pathLToNode(nextNode);
1117  x3=nextNode->pathlength()/2.;
1118 
1119  if(x3==-1.) continue;
1120  //if there is an error with "next" node, proceed along track
1121  //without updating current node. This should provide
1122  //function thisNode=thisNode, nextNode=new node
1123 
1124  if (x2> (x1+x3)) x2 = x2 - x1 - x3; //x2 is now the gap distance
1125  else x2=0.;
1126 
1127  cout
1128  <<"getTrackRadLength:"
1129  <<"\n\tIn Detector: "<<thisNode->getDetector()->getName()
1130  <<"\n\t\tMaterial: "<<thisNode->getDetector()->getMaterial()
1131  <<"\n\t\tLength: "<<x1
1132  <<"\t\tGap Length: "<<x2
1133  <<"\n\tNext Detector: "<<nextNode->getDetector()->getName()
1134  <<"\n\t\tMaterial: "<<nextNode->getDetector()->getMaterial()
1135  <<"\n\t\tLength: "<<x3
1136  << endl;
1137  {
1138  if (thisNode->getX0()>0) totalR += x1/thisNode->getX0();
1139  if (nextNode->getGasX0()>0) totalR += x2/nextNode->getGasX0();
1140  if (nextNode->getX0()>0) totalR += x3/nextNode->getX0();
1141  }
1142  //cache nextNode for next iteration...
1143  thisNode = nextNode;
1144  x1 = x3;
1145  }
1146  if (totalR>200.)
1147  cout <<"StiKalmanTrack::getTrackRadLength() -W- Total Rad Length Error: "<<totalR;
1148  return totalR;
1149 }
1150 //_____________________________________________________________________________
1152 {
1153  StiKalmanTrackNode * inNode = lastNode;
1154  StThreeVectorD in(inNode->x_g(),inNode->y_g(),inNode->z_g());
1155 
1156  StPhysicalHelixD hlx(fabs(inNode->getCurvature()),
1157  inNode->getDipAngle(),
1158  inNode->getPhase(),
1159  in,
1160  inNode->getHelicity());
1161  double per = hlx.period();
1162  double len = hlx.pathLength(0.,0.);
1163 // StHelix can return negative length if -ve path is shorter then +ve one
1164 // period ia added in this case;
1165  if (fabs(len) > fabs(len+per)) len+=per;
1166  if (fabs(len) > fabs(len-per)) len-=per;
1167 
1168  hlx.moveOrigin(len);
1169  if (pnt) (*pnt) = hlx.at(0);
1170 
1171  if (dir) {
1172  double phase = hlx.phase();
1173  double dip = hlx.dipAngle();
1174  int h = hlx.h();
1175 
1176  (*dir)[0]= -sin(phase)*cos(dip)*h;
1177  (*dir)[1]= cos(phase)*cos(dip)*h;
1178  (*dir)[2]= sin(dip)*h;}
1179 
1180  return fabs(len);
1181 }
1182 
1183 //_____________________________________________________________________________
1194 //_____________________________________________________________________________
1196 {
1197  assert(firstNode && lastNode);
1198 
1199  StiKalmanTrackNode *node;
1200  StiKTNIterator it =(inot) ? begin():rbegin();
1201  for (;(node=it());it++){
1202  if (!node->isValid()) continue;
1203  StiHit *hit = node->getHit();
1204  if (qua&kKeepHit) {if (!hit) continue;}
1205  if (qua&kGoodHit) {if (!hit || node->getChi2()>10000.)continue;}
1206  return node;
1207  }
1208  cout << "StiKalmanTrack::getInnOutMostNode() -E- No requested nodes " << endl;
1209  return 0;
1210 }
1211 //_____________________________________________________________________________
1213 {
1214  return getInnOutMostNode(1,qua|1);
1215 }
1216 
1217 
1218 //_____________________________________________________________________________
1230 {
1231  return getInnOutMostNode(0,qua|1);
1232 }
1233 //_____________________________________________________________________________
1234 StiKalmanTrackNode * StiKalmanTrack::getInnerMostDetHitNode(int detId) const
1235 {
1236  assert(firstNode && lastNode);
1237  StiKalmanTrackNode *node = 0;
1238  for (auto it=begin();(node=it());++it)
1239  {
1240  if (!node->isValid()) continue;
1241  if (node->getChi2()>10000.) continue;
1242  StiHit* hit = node->getHit();
1243  if (!hit) continue;
1244  auto *det = hit->detector();
1245  if (!det) continue;
1246  if (detId!=det->getGroupId()) continue;
1247  return node;
1248  }
1249  return 0;
1250 }
1251 //_____________________________________________________________________________
1252 int StiKalmanTrack::getNNodes(int qua) const
1253 {
1254  StiKalmanTrackNode *node;
1255  StiKTNIterator it = begin();
1256  int nn=0;
1257  for (;(node=it());it++){
1258  if (!node->isValid()) continue;
1259  StiHit *hit = node->getHit();
1260  if (qua&kKeepHit) { if (!hit) continue;}
1261  if (qua&kGoodHit) { if (!hit || node->getChi2()>10000.) continue;}
1262  nn++;
1263  }
1264  return nn;
1265 }
1266 
1267 //_____________________________________________________________________________
1269 vector<StiKalmanTrackNode*> StiKalmanTrack::getNodes(int detectorId) const
1270 {
1271  StiKTNIterator it;
1272  vector<StiKalmanTrackNode*> nodeVec;
1273  for (it=begin();it!=end();++it) {
1274  StiKalmanTrackNode* node = &(*it);
1275  const StiHit* hit = node->getHit();
1276  if(!hit) continue;
1277  const StiDetector *det = hit->detector();
1278  if (!det) continue;
1279  if (node->getDedx()<=0.) continue;
1280  if (detectorId!=det->getGroupId()) continue;
1281  nodeVec.push_back(node);
1282  }
1283  return nodeVec;
1284 }
1285 
1286 //_____________________________________________________________________________
1288 vector<const StMeasuredPoint*> StiKalmanTrack::stHits() const
1289 {
1290  StiKTNIterator it;
1291  vector<const StMeasuredPoint*> hits;
1292  for (it=begin();it!=end();++it) {
1293  const StiKalmanTrackNode* node = &(*it);
1294  if (!node->isValid()) continue;
1295  if (node->getChi2()>10000.) continue;
1296  const StiHit* hit = node->getHit();
1297  if (!hit) continue;
1298  if (!hit->detector()) continue;
1299  const StMeasuredPoint *stHit = hit->stHit();
1300  if (!stHit) continue;
1301  hits.push_back(stHit);
1302  }
1303  return hits;
1304 }
1305 
1306 
1307 
1308 //_____________________________________________________________________________
1316 //_____________________________________________________________________________
1318 {
1319  if (yes) {
1320  StiKTNForwardIterator it(lastNode);
1321  for_each( it, it.end(), SetHitUsed() );
1322  } else {
1323  StiKTNForwardIterator it(lastNode);
1324  for_each( it, it.end(), SetHitUnused() );
1325  }
1326 
1327 }
1328 
1351 //_____________________________________________________________________________
1353 {
1354 static int nCall=0; nCall++;
1355  double chi2;
1356  int dcaHit = vertex->isDca();
1357  StiKalmanTrackNode * sNode=0;
1358  StiKalmanTrackNode * tNode=0;
1359  bool trackExtended = false;
1360 
1361  StiKalmanTrackNode * innerMostHitNode = getInnerMostHitNode();
1362  if (!innerMostHitNode) return 0;
1363 
1364  StiHit localVertex = *vertex;
1365  sNode = getInnerMostNode();
1366  if (sNode->isDca()) {//it is fake node. Remove it
1367  removeLastNode();
1368  sNode = getInnerMostNode();
1369  }
1370 
1371 
1372  localVertex.rotate(sNode->getAlpha());
1373  tNode = trackNodeFactory->getInstance();
1374  StiHit *myHit;
1375  //cout << "SKT::extendToVertex() -I- x,y,z:"<< localVertex.x()
1376  // << " " << localVertex.y() << " " << localVertex.z() << endl;
1377  //cout << "SKT::extendToVertex() -I- sNode->getX():"<<sNode->getX()<<endl;
1378  //cout << "SKT::extendToVertex() -I-0 tNode->getX():"<< tNode->getX()<<endl;
1379  if (tNode->propagate(sNode, &localVertex,kOutsideIn))
1380  {
1381  //cout << " on vertex plane:";
1382  double dy=0,dz=0,d=0;
1383  if (dcaHit) { //Fake DCA vertex
1384  tNode->setChi2(0);
1385  tNode->setHit(0);
1386  tNode->setDetector(0);
1387  return tNode;
1388  } else { //Normal vertex
1389  tNode->setChi2(3e33);
1390  chi2 = tNode->evaluateChi2(&localVertex);
1391  dy=tNode->getY()- localVertex.y();
1392  dz=tNode->getZ()- localVertex.z();
1393  d = ::sqrt(dy*dy+dz*dz);
1394  _vChi2= chi2; _dca = d;
1395  }
1396 
1397 
1398 // if (chi2<StiKalmanTrackFinderParameters::instance()->maxChi2Vertex && d<4.)
1399 // if ( d<4.)
1400  if (chi2<StiKalmanTrackFinderParameters::instance()->maxChi2Vertex())
1401  {
1402  myHit = StiToolkit::instance()->getHitFactory()->getInstance();
1403  *myHit = localVertex;
1404  tNode->setHit(myHit);
1405  tNode->setChi2(chi2);
1406  tNode->setDetector(0);
1407  trackExtended = (tNode->updateNode()==0);
1408 
1409  if (trackExtended) return tNode;
1410  trackNodeFactory->free(tNode);
1411  }
1412  else if (d < 4) {
1413  LOG_DEBUG <<
1414  Form("Primary(%d) not accepted BUT d = %g chi2 = %g",nCall,d,chi2)
1415  << endm;
1416  }
1417  }
1418  //else
1419  // cout <<" TRACK NOT REACHING THE VERTEX PLANE!"<<endl;
1420  return 0;
1421 }
1424 //_____________________________________________________________________________
1425 vector<StiHit*> StiKalmanTrack::getHits()
1426 {
1427  vector<StiHit*> hits;
1428  StiKalmanTrackNode* leaf = getLastNode();
1429  StiKTNForwardIterator it(leaf);
1430  StiKTNForwardIterator end = it.end();
1431  for (;it!=end;++it)
1432  {
1433  const StiKalmanTrackNode& node = *it;
1434  if (!node.isValid()) continue;
1435  if (node.getChi2()>10000.) continue;
1436  StiHit* hit = node.getHit();
1437  if (!hit) continue;
1438  hits.push_back(hit);
1439  }
1440  return hits;
1441 }
1442 
1443 //_____________________________________________________________________________
1445 double StiKalmanTrack::getDca(const StiHit * vertex) const
1446 {
1447  StiKalmanTrackNode* node;
1448 
1449  node = getInnerMostHitNode(2);
1450  StThreeVectorD originD(node->x_g(),node->y_g(),node->z_g());
1451  StThreeVectorD vxDD(vertex->x_g(), vertex->y_g(),vertex->z_g());
1452  StPhysicalHelixD physicalHelix(0.,0.,0.,originD,-1);
1453  physicalHelix.setParameters(fabs(node->getCurvature()),
1454  node->getDipAngle(),
1455  node->getPhase(),
1456  originD,
1457  node->getHelicity());
1458  double dca = physicalHelix.distance(vxDD);
1459  return dca;
1460 }
1461 //_____________________________________________________________________________
1462 ostream& operator<<(ostream& os, const StiKalmanTrack& track)
1463 {
1464  try
1465  {
1466  os << *((StiTrack *) &track);
1467  os <<"List of nodes" << endl;
1468  StiKTNIterator tNode = track.begin();
1469  StiKTNIterator eNode = track.end();
1470  //set initial conditions for tNode, the 'current' node;
1471  //will also need 'nextNode', ie node which is next
1472  while (tNode != eNode) {
1473  StiKalmanTrackNode *thisNode = &(*tNode);
1474  if (thisNode) os << *thisNode;
1475  tNode++;
1476  }
1477  }
1478  catch (runtime_error & rte)
1479  {
1480  os << " Run-time Error while accessing track parameters: " << rte.what() << endl;
1481  }
1482  catch (logic_error & le)
1483  {
1484  os << " Logic Error while accessing track parameters: " << le.what() << endl;
1485  }
1486  return os;
1487 }
1488 
1489 //_____________________________________________________________________________
1495 {
1496  StiKalmanTrackNode * innerMostNode = getInnerMostNode();
1497  //return null if there is no node to extrapolate from.
1498  if (!innerMostNode) return 0;
1499  StiKalmanTrackNode * n = trackNodeFactory->getInstance();
1500  if (n->propagateToBeam(innerMostNode,kOutsideIn)) return n;
1501  trackNodeFactory->free(n);
1502  return 0;
1503 }
1504 
1505 //_____________________________________________________________________________
1506 StiKalmanTrackNode * StiKalmanTrack::extrapolateToRadius(double radius)
1507 {
1508  StiKalmanTrackNode * outerMostNode = getOuterMostNode();
1509  //return null if there is no node to extrapolate from.
1510  if (!outerMostNode) return 0;
1511  StiKalmanTrackNode *n = trackNodeFactory->getInstance();
1512  if (n->propagateToRadius(outerMostNode,radius,kOutsideIn)) return n;
1513  trackNodeFactory->free(n);
1514  return 0;
1515 }
1516 
1517 //_____________________________________________________________________________
1518 void StiKalmanTrack::add(StiTrackNode * node,int direction,StiTrackNode *near)
1519 {
1520 
1521  StiKalmanTrackNode *Node = (StiKalmanTrackNode*)node;
1522  if (lastNode==0) {
1523  lastNode = firstNode = Node; return;
1524  }
1525  if (direction==0) {
1526  if (!near) near = lastNode;
1527  near->add(Node,direction);
1528  lastNode = Node;
1529  } else {
1530  if (!near) near = firstNode;
1531  near->add(Node,direction);
1532  firstNode = Node;
1533  }
1534 }
1535 //_____________________________________________________________________________
1536 void StiKalmanTrack::setFirstLastNode(StiKalmanTrackNode * node)
1537 {
1538  firstNode = (StiKalmanTrackNode*)node->getFirstNode();
1539  lastNode = (StiKalmanTrackNode*)node->getLastNode ();
1540 }
1541 //_____________________________________________________________________________
1542 void StiKalmanTrack::removeLastNode()
1543 {
1544  StiKalmanTrackNode *node = lastNode;
1545  lastNode = (StiKalmanTrackNode*)node->disconnect();
1546  BFactory::Free(node);
1547 }
1548 //_____________________________________________________________________________
1549 
1550 
1556 {
1557  int errType = kNoErrors;
1558 
1559  enum {kMaxIter=30,kPctLoss=10,kHitLoss=3};
1560  static double defConfidence = StiDebug::dFlag("StiConfidence",0.01);
1561  int nNBeg = getNNodes(3), nNEnd = nNBeg;
1562  if (nNBeg<=3) return 1;
1563  if (!mgMaxRefiter) return 0;
1565  int fail=0,status=0;
1566 
1567  StiNodePars pPrev;
1568  StiNodeErrs ePrev;
1569  int iter=0,igor=0;
1570  double qA;
1571  double errConfidence = defConfidence;
1572  for (int ITER=0;ITER<mgMaxRefiter;ITER++) {
1573  for (iter=0;iter<kMaxIter;iter++) {
1574  fail = 0;
1575  errType = kNoErrors;
1576  sTNH.set(StiKalmanTrackFitterParameters::instance()->getMaxChi2()*10,StiKalmanTrackFitterParameters::instance()->getMaxChi2Vtx()*100,errConfidence,iter);
1577  pPrev = inn->fitPars();
1578  ePrev = inn->fitErrs();
1579 
1580  status = refitL();
1581  if (status) {fail= 1; errType = kRefitFail; break;}
1582  nNEnd = sTNH.getUsed();
1583  if ((nNEnd <=3)) {fail= 2; errType = kNotEnoughUsed; break;}
1584  if (!inn->isValid() || inn->getChi2()>1000) {
1585  inn = getInnerMostNode(3); fail=-1; errType = kInNodeNotValid; continue;}
1586  qA = StiKalmanTrack::diff(pPrev,ePrev,inn->fitPars(),inn->fitErrs(),igor);
1587  static int oldRefit = StiDebug::iFlag("StiOldRefit");
1588  if (oldRefit) {
1589  if (qA>0.5) {fail=-2; errType = kBadQA; continue;}
1590  } else {
1591  if (qA <1 && errConfidence>0.1) errConfidence = 0.1;
1592  if (qA>0.01) {fail=-2; errType = kBadQA; continue;}
1593  if (sTNH.isCutStep()) {fail=-2; errType = kBadQA; continue;}
1594  }
1595  double info[2][8];
1596  sTNH.mCurvQa.getInfo(info[0]);
1597  sTNH.mTanlQa.getInfo(info[1]);
1598  break;
1599  }
1600  if (fail>0) break;
1601  //
1602  StiKalmanTrackNode *worstNode= sTNH.getWorst();
1603  if (worstNode && worstNode->getChi2()>StiKalmanTrackFitterParameters::instance()->getMaxChi2())
1604  { //worstNode->getHit()->subTimesUsed();
1605  worstNode->setHit(0); worstNode->setChi2(3e33); continue;}
1606  if (rejectByHitSet()) { releaseHits() ;continue;}
1607 
1608  if (!fail) break;
1609 
1610  StiKalmanTrackNode *flipFlopNode= sTNH.getFlipFlop();
1611  if (flipFlopNode && flipFlopNode->getFlipFlop()>kMaxIter/3)
1612  { //flipFlopNode->getHit()->subTimesUsed();
1613  flipFlopNode->setHit(0); flipFlopNode->setChi2(3e33); continue;}
1614  break;
1615  // The last resource
1616  // errConfidence = 0.5*(errConfidence+1);
1617  // if (errConfidence>0.99) break;
1618  }
1619  StiKalmanTrackNode *vertexNode= sTNH.getVertexNode();
1620 
1621  // Test for primary
1622  while (!fail && vertexNode) {
1623  fail = 13; //prim node invalid
1624  errType = kVertexNodeInvalid;
1625  if (!vertexNode->isValid()) break;
1626  fail = 99; //prim node Chi2 too big
1627  errType = kNodeNotValid;
1628  if ( vertexNode->getChi2()>StiKalmanTrackFitterParameters::instance()->getMaxChi2Vtx()) break;
1629  fail = 98; //too many dropped nodes
1630  errType = kTooManyDroppedNodes;
1631  if (nNBeg*kPctLoss/100 < nNBeg-nNEnd
1632  && nNEnd+kHitLoss < nNBeg) break;
1633  fail = 0;
1634  errType = kNoErrors;
1635  break;
1636  }
1637  if (!fail) { //Cleanup. Hits of bad nodes set to zero
1638  StiKalmanTrackNode *node;
1639  StiKTNIterator it = begin();
1640  for (;(node=it());it++){
1641  if (node == vertexNode) continue;
1642  StiHit *hit = node->getHit();
1643  if(!hit) continue;
1644  if (node->isValid() && node->getChi2()<10000. ) continue;
1645  node->setHit(0);
1646  }
1647  }
1648 
1649  if (fail) setFlag(-1);
1650  return errType;
1651 }
1652 //_____________________________________________________________________________
1653 int StiKalmanTrack::refitL()
1654 {
1655 static int nCall=0;nCall++;
1656  StiDebug::Break(nCall);
1657 
1658  StiKTNIterator source;
1659  StiKalmanTrackNode *pNode = 0,*targetNode;
1660  int iNode=0, status = 0;
1661  bool isStarted=false;
1662  sTNH.setDir(1);
1663  for (source=rbegin();source!=rend();source++) {
1664  iNode++;
1665  targetNode = &(*source);
1666 
1667  if (!isStarted) {
1668  if (!targetNode->getHit()) targetNode->setInvalid();
1669  if ( targetNode->getChi2()>1000) targetNode->setInvalid();
1670  if (!targetNode->isValid()) continue;
1671  }
1672  sTNH.set(pNode,targetNode);
1673  status = sTNH.makeFit(0);
1674  if (status) {targetNode->setInvalid();continue;}
1675  if (!targetNode->isValid()) continue;
1676  isStarted = true;
1677  pNode = targetNode;
1678  }//end for of nodes
1679 
1680  pNode = 0; iNode=0;isStarted=false;
1681  sTNH.setDir(0);
1682  for (source=begin();source!=end();source++) {
1683  iNode++;
1684  targetNode = &(*source);
1685  if (!isStarted) {
1686  if (!targetNode->getHit()) targetNode->setInvalid();
1687  if ( targetNode->getChi2()>1000) targetNode->setInvalid();
1688  if (!targetNode->isValid()) continue;
1689  }
1690  sTNH.set(pNode,targetNode);
1691  status = sTNH.makeFit(1);
1692  if (status) {targetNode->setInvalid();continue;}
1693  if (!targetNode->isValid()) continue;
1694  isStarted = true;
1695  pNode = targetNode;
1696  }//end for of nodes
1697  return 0;
1698 }
1699 //_____________________________________________________________________________
1700 void StiKalmanTrack::reduce()
1701 {
1702  StiKTNIterator source;
1703  for (source=begin();source!=end();source++) {(*source).reduce();}
1704 }
1705 //_____________________________________________________________________________
1706 void StiKalmanTrack::unset()
1707 {
1708  if (!lastNode) return;
1709  StiKTNIterator source;
1710  for (source=begin();source!=end();source++) {BFactory::Free(&(*source));}
1711  lastNode=0; firstNode=0;
1712 }
1713 //_____________________________________________________________________________
1714 void StiKalmanTrack::print(const char *opt) const
1715 {
1716  printf("Track %p\n",(void*)this);
1717 
1718  StiKTNIterator it;
1719  int n=0;
1720  for (it=begin();it!=end();++it) {
1721  StiKalmanTrackNode *node = &(*it);
1722  StiHit *hit = node->getHit();
1723  if (!hit && strchr(opt,'h')) continue;
1724  if (!hit && strchr(opt,'H')) continue;
1725  n++;
1726  printf("%3d - ",n);
1727  node->print(opt);
1728  }
1729 }
1730 
1731 //_____________________________________________________________________________
1732 int StiKalmanTrack::approx(int mode)
1733 {
1734  //const double BAD_XI2[2] = {70,5}, XI2_FACT = 1; // Tuned constants
1735  const double BAD_XI2[2] = {99,22}, XI2_FACT = 9;
1736  mXi2=0;
1737  StiHitErrs hr;
1738  // Loop over nodes and collect global xyz
1739 
1740  StiKTNIterator source;
1741  StiKalmanTrackNode *targetNode;
1742  int nNode=0;
1743  THelixFitter circ;
1744  THelixTrack cirl;
1745  int zeroH = -1;
1746  for (source = rbegin(); (targetNode = source()); ++source) {
1747  if (!targetNode->isValid()) continue;
1748  const StiHit * hit = targetNode->getHit();
1749  if (!hit) continue;
1750  if (targetNode->getChi2()>1000) continue;
1751  if (zeroH<0) {//What kind of mag field ?
1752  double hz = targetNode->getHz();
1753  zeroH = fabs(hz)<=kZEROHZ;
1754  }
1755  circ.Add(hit->x_g(),hit->y_g(),hit->z_g());
1756  if (mode & kAppRR) {
1757  hr = targetNode->getGlobalHitErrs(hit);
1758  circ.AddErr(hr.G(),hr.hZZ);
1759  }
1760  nNode++;
1761  }
1762  if (!nNode) return 1;
1763 
1764  mXi2 =circ.Fit();
1765  if (mXi2 > BAD_XI2[mode & kAppGud]) return 2; //Xi2 too bad, no updates
1766  if (zeroH) circ.Set(kZEROCURV);
1767  if (mode & kAppRR) circ.MakeErrs();
1768 
1769  double s=0,xyz[3];
1770  double curv = circ.GetRho();
1771  for (source = rbegin(); (targetNode = source()); ++source) {
1772  if (!targetNode->isValid()) continue;
1773  const StiHit *hit = targetNode->getHit();
1774  if (hit) {
1775  xyz[0] = hit->x_g();
1776  xyz[1] = hit->y_g();
1777  xyz[2] = hit->z_g();
1778  } else {
1779  xyz[0] = targetNode->x_g();
1780  xyz[1] = targetNode->y_g();
1781  xyz[2] = targetNode->z_g();
1782  }
1783  double ds = circ.Path(xyz[0],xyz[1]);
1784  circ.Move(ds);
1785  s+=ds;
1786  int upd = (mode & kAppUPD);
1787  upd |= ((mode & kAppUpd) && (targetNode == firstNode));
1788  if (!upd) continue;
1789  cirl = circ;
1790  double alfa = targetNode->getAlpha();
1791  cirl.Rot(-alfa);
1792  StiNodePars P = targetNode->fitPars();
1793  P.x() = cirl.Pos()[0];
1794  P.y() = cirl.Pos()[1];
1795  P.z() = cirl.Pos()[2];
1796  P.eta() = atan2(cirl.Dir()[1],cirl.Dir()[0]);
1797  P.curv() = curv;
1798  double hh = P.hz();
1799  hh = (fabs(hh)<1e-10)? 0:1./hh;
1800  P.ptin() = (hh)? curv*hh:1e-3;
1801 
1802  P.tanl() = cirl.GetSin()/cirl.GetCos();
1803  P._cosCA = cirl.Dir()[0]/cirl.GetCos();
1804  P._sinCA = cirl.Dir()[1]/cirl.GetCos();
1805  if (fabs(P._cosCA)>0.99 || fabs(P._sinCA)>0.99) P.ready();
1806 
1807  targetNode->fitPars() = P;
1808  int ians = targetNode->nudge();
1809  if(ians) {nNode--; targetNode->setInvalid();continue;}
1810  if (mode & kAppRR) {
1811  P = targetNode->fitPars();
1812  StiNodeErrs &E = targetNode->fitErrs();
1813  cirl.StiEmx(E.G());
1814  TCL::vscale(&(E._cPX),hh,&(E._cPX),5);
1815  E._cPP*=hh; E._cTP*=hh;
1816  if ((mode & kAppGud) == 0 && mXi2 > XI2_FACT) E*=mXi2/XI2_FACT;
1817  E.check("In aprox");
1818  }
1819  }
1820  return 0;
1821 }
1822 //_____________________________________________________________________________
1823 double StiKalmanTrack::diff(const StiNodePars &p1,const StiNodeErrs &e1
1824  ,const StiNodePars &p2,const StiNodeErrs &e2,int &igor)
1825 {
1826  double est=0;
1827  for (int i=0;i<kNPars;i++) {
1828  double err = 0.5*(e1(i,i)+e2(i,i));
1829  if (err<1e-10) continue;
1830  double dif = pow(p1[i]-p2[i],2)/err;
1831  if (est<dif) {est = dif; igor = i;}
1832  }
1833  return est;
1834 }
1835 //_____________________________________________________________________________
1836 StiKalmanTrack &StiKalmanTrack::operator=(const StiKalmanTrack &tk)
1837 {
1838  StiTrack::operator=(tk);
1839  firstNode=0;
1840  lastNode=0;
1841 
1842  mSeedHitCount=tk.mSeedHitCount; //number of points used to seed the track
1843  mFlag =tk.mFlag; //A flag to pack w/ topo info
1844  mMass =tk.mMass; // mass hypothesis
1845  _dca =tk._dca;
1846  _vChi2 =tk._vChi2; //
1847  mVertex =tk.mVertex;
1848  StiKTNIterator it;
1849  for (it=tk.begin();it!=tk.end();it++){
1850  const StiKalmanTrackNode *node = &(*it);
1851  if (!node->isValid()) continue;
1852  StiKalmanTrackNode *myNode=trackNodeFactory->getInstance();
1853  *myNode=*node;
1854  add(myNode,kOutsideIn);
1855  }
1856  return *this;
1857 }
1858 
1859 //_____________________________________________________________________________
1860 void StiKalmanTrack::setMaxRefiter(int maxRefiter)
1861 {
1862  mgMaxRefiter = maxRefiter;
1863 }
1864 //_____________________________________________________________________________
1865 int StiKalmanTrack::rejectByHitSet() const
1866 {
1867  StiKalmanTrackNode *node;
1868  int sum=0;
1869  for (StiKTNIterator it = rbegin();(node=it());it++){
1870  if (node->x()>50) break;
1871  if (!node->isValid()) continue;
1872  StiHit *hit = node->getHit();
1873  if (!hit) continue;
1874  if (!hit->detector()) continue;
1875  if (node->getChi2()>1000) continue;
1876  sum+= StiKalmanTrackFinderParameters::instance()->hitWeight(int(hit->x()));
1877  }
1878  if (!sum) return 0;
1879  return sum < StiKalmanTrackFinderParameters::instance()->sumWeight();
1880 }
1881 //_____________________________________________________________________________
1882 int StiKalmanTrack::releaseHits(double rMin,double rMax)
1883 {
1884  StiKalmanTrackNode *node;
1885  int sum=0;
1886  for (StiKTNIterator it = rbegin();(node=it());it++){
1887  StiHit *hit = node->getHit();
1888  if (!hit) continue;
1889  if (!hit->detector()) continue;
1890  if (hit->x()<rMin) continue;
1891  if (hit->x()>rMax) break;
1892  sum++;
1893  node->setHit(0);
1894  }
1895  return sum;
1896 }
1897 //_____________________________________________________________________________
1898 void StiKalmanTrack::test(const char *txt) const
1899 {
1900 
1901  for (auto it=begin();it!=end();it++) {
1902  StiKalmanTrackNode *node = &(*it);
1903  if (!node->isValid()) continue;
1904  const StiDetector *det = node->getDetector();
1905  if (!det) continue;
1906  const auto &P = node->fitPars();
1907  double tst = P[0]*P._cosCA+P[1]*P._sinCA;
1908  if (tst>=0) continue;
1909  tst /= sqrt(P[0]*P[0]+P[1]*P[1]);
1910 // assert (tst>=-1e-5);
1911 StiDebug::Count("OverKill",tst);
1912  }
1913 }
1914 //_____________________________________________________________________________
1915 //_____________________________________________________________________________
1916 #include "StarRoot/TIdTruUtil.h"
1917 //_____________________________________________________________________________
1918 int StiKalmanTrack::idTruth(int *qa) const
1919 {
1920  TIdTruUtil ut;
1921  for (auto it=begin();it!=end();it++) {
1922  StiKalmanTrackNode *node = &(*it);
1923  if (!node->isValid()) continue;
1924  const StiHit *hit = node->getHit();
1925  if (!hit) continue;
1926  if (!node->getDetector()) continue;
1927  if ( node->getChi2()>100) continue;
1928  ut.Add(hit->idTruth(),hit->qaTruth());
1929  }
1930  if (qa) *qa = 100*ut.GetQua();
1931  return ut.GetIdTru();
1932 }
StiKalmanTrackNode * getInnOutMostNode(int inot, int qua) const
Same for getNNodes(qua)
int propagate(StiKalmanTrackNode *p, const StiDetector *tDet, int dir)
Propagates a track encapsulated by the given node &quot;p&quot; to the given detector &quot;tDet&quot;.
double getX0() const
StiKalmanTrackNode * getInnerMostHitNode(int qua=0) const
Accessor method returns the inner most hit node associated with the track.
Definition of Kalman Track.
double getNearBeam(StThreeVectorD *pnt=0, StThreeVectorD *dir=0) const
double getTrackRadLength() const
int h() const
y-center of circle in xy-plane
Definition: StHelix.hh:174
StiKalmanTrackNode * getOuterMostHitNode(int qua=0) const
Accessor method returns the outer most hit node associated with the track.
int propagateToRadius(StiKalmanTrackNode *pNode, double radius, int dir)
int getMaxPointCount(int detectorId=0) const
Abstract definition of a Track.
Definition: StiTrack.h:59
bool moveIn(double phiCut=-1.0, double zCut=-1.0, double rMin=-1.0)
Step in radially in STAR TPC global coordinates.
StiTrackNode * extendToVertex(StiHit *vertex)
int getGapCount() const
Return the number of gaps on this track.
StiKalmanTrackNode * getLastNode() const
Accessor method returns the last node associated with the track.
bool propagateToBeam(const StiKalmanTrackNode *p, int dir)
void getAllPointCount(int count[1][3], int maxDetId) const
Returns all the PointCount far all detectors and types of nodes.
static int mgMaxRefiter
Definition: StiHit.h:51
void setToDetector(const StiDetector *layer)
Set iterators to the detector nearest to the passed StiDetector pointer.
const Float_t & x() const
Return the local x, y, z values.
Definition: StiHit.h:67
virtual void free(Abstract *obj)=0
Free an object for reuse.
StiKalmanTrackNode * getOuterMostNode(int qua=0) const
Accessor method returns the outer most node associated with the track.
virtual vector< StiHit * > getHits()
void reserveHits(int yes=1)
void rotate(double angle)
Definition: StiHit.cxx:46
const StiDetector * detector() const
Definition: StiHit.h:96
double pathLToNode(const StiKalmanTrackNode *const oNode)
Float_t x_g() const
Return the global x, y, z values.
Definition: StiHit.h:73
virtual vector< StiKalmanTrackNode * > getNodes(int detectorGroupId) const
return vector of nodes with hits
double getGasX0() const
int print(const char *opt) const
rotation angle of local coordinates wrt global coordinates
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
Definition: StHelix.cc:351
int getFitPointCount(int detectorId=0) const
Returns the number of hits associated and used in the fit of this track.
virtual Abstract * getInstance()=0
Get a pointer to instance of objects served by this factory.
StiKalmanTrackNode * getInnerMostNode(int qua=0) const
Accessor method returns the inner most node associated with the track.
double getChi2Max() const
Return the maximal node chi2.
int getPointCount(int detectorId=0) const
Return the number of hits associated with this track.
Definition of Kalman Track.
virtual int initialize(const vector< StiHit * > &)
Convenience method to initialize a track based on seed information.
StiKalmanTrackNode * extrapolateToBeam()
static void Free(void *obj)
Free an object for reuse.
Definition: Factory.h:73
Int_t isDca() const
Test for DCA. Fake hit for dca calculation.
Definition: StiHit.cxx:285
double _cosCA
sine and cosine of cross angle
Definition: StiNodePars.h:51
double getChi2() const
double getDca() const
Abstract interface for a STI toolkit.
const StiKTNBidirectionalIterator & end() const
double evaluateChi2(const StiHit *hit)
virtual vector< const StMeasuredPoint * > stHits() const
return hits;
double getTrackLength() const
double getCurvature() const
Calculates and returns the tangent of the track pitch angle at this node.
const StMeasuredPoint * stHit() const
Definition: StiHit.h:104
virtual void moveOrigin(double s)
move the origin along the helix to s which becomes then s=0
Definition: StHelix.cc:621
virtual void add(StiTrackNode *node, int direction, StiTrackNode *near=0)
double period() const
returns period length of helix
Definition: StHelix.cc:339
double Move(double step)
Move along helix.
int getCharge() const
Get the charge (sign) of the track at this node.
StiKTNBidirectionalIterator begin() const
double phase() const
1/R in xy-plane
Definition: StHelix.hh:180
static void setKalmanTrackNodeFactory(Factory< StiKalmanTrackNode > *)
Set the factory used for the creation of kalman track nodes.
void initialize(StiHit *h)
Initialize this node with the given hit information.
int getCharge() const
const string & getName() const
Get the name of the object.
Definition: Named.cxx:22