StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StFtpcTracker.cc
1 // $Id: StFtpcTracker.cc,v 1.37 2007/02/06 11:42:16 jcs Exp $
2 // $Log: StFtpcTracker.cc,v $
3 // Revision 1.37 2007/02/06 11:42:16 jcs
4 // move unessential output messages from INFO to DEBUG
5 //
6 // Revision 1.36 2007/01/15 08:23:02 jcs
7 // replace printf, cout and gMesMgr with Logger commands
8 //
9 // Revision 1.35 2005/02/05 01:04:38 perev
10 // test for 1/0
11 //
12 // Revision 1.34 2004/09/03 20:36:23 perev
13 // Big LeakOff + mem optimisation
14 //
15 // Revision 1.33 2004/05/07 14:58:22 oldi
16 // Deletion of track array added again, since it doesn't go into a DataSet anymore.
17 // Minor clean-ups.
18 //
19 // Revision 1.32 2004/02/27 21:24:09 oldi
20 // Unnecessary check for number of tracks removed.
21 //
22 // Revision 1.31 2004/02/12 19:37:11 oldi
23 // *** empty log message ***
24 //
25 // Revision 1.30 2004/01/28 01:41:32 jeromel
26 // *** empty log message ***
27 //
28 // Revision 1.29 2003/12/05 04:08:49 perev
29 // technical cleanup
30 //
31 // Revision 1.28 2003/09/16 20:49:34 oldi
32 // One more pointer initialized to zero. Code clean-up.
33 //
34 // Revision 1.27 2003/09/16 16:52:48 jeromel
35 // Multiple constructor entry, zeroing mBench everywhere + doxygenized
36 //
37 // Revision 1.26 2003/09/16 15:27:02 jcs
38 // removed inline as it would leave a few undefined reference
39 //
40 // Revision 1.25 2002/11/28 09:39:33 oldi
41 // Problem in momentum fit eliminated. Negative vertex Id is not used anymore.
42 // It was used do decide for global or primary fit.
43 // Code was prepared to fill momentum values at outermost points on tracks.
44 // This feature is not used up to now.
45 // Code cleanups.
46 //
47 // Revision 1.24 2002/11/06 13:47:11 oldi
48 // Vertex handling simplifed.
49 // Global/primary fit handling simplified.
50 // Code clean ups.
51 //
52 // Revision 1.23 2002/10/31 13:41:46 oldi
53 // dE/dx parameters read from database, now.
54 // Vertex estimation for different sectors added.
55 // Vertex estimation for different areas (angle, radius) added.
56 //
57 // Revision 1.22 2002/10/11 15:45:35 oldi
58 // Get FTPC geometry and dimensions from database.
59 // No field fit activated: Returns momentum = 0 but fits a helix.
60 // Bug in TrackMaker fixed (events with z_vertex > outer_ftpc_radius were cut).
61 // QA histograms corrected (0 was supressed).
62 // Code cleanup (several lines of code changed due to *params -> Instance()).
63 // cout -> gMessMgr.
64 //
65 // Revision 1.21 2002/06/04 13:41:35 oldi
66 // Minor change: 'west' -> 'hemisphere' (just a naming convention)
67 //
68 // Revision 1.20 2002/04/29 15:50:16 oldi
69 // All tracking parameters moved to StFtpcTrackingParameters.cc/hh.
70 // In a future version the actual values should be moved to an .idl file (the
71 // interface should be kept as is in StFtpcTrackingParameters.cc/hh).
72 //
73 // Revision 1.19 2002/04/05 16:51:09 oldi
74 // Cleanup of MomentumFit (StFtpcMomentumFit is now part of StFtpcTrack).
75 // Each Track inherits from StHelix, now.
76 // Therefore it is possible to calculate, now:
77 // - residuals
78 // - vertex estimations obtained by back extrapolations of FTPC tracks
79 // Chi2 was fixed.
80 // Many additional minor (and major) changes.
81 //
82 // Revision 1.18 2002/02/21 22:57:57 oldi
83 // Fixes to avoid warnings during optimized compilation.
84 //
85 // Revision 1.17 2002/02/14 22:05:12 oldi
86 // Typo removed.
87 //
88 // Revision 1.16 2002/01/29 11:08:20 oldi
89 // Write() renamed to WriteCluster() resp. WriteTrack() to avoid compiler warnings.
90 // As a result the functions TObject::Write() are available again (directly).
91 //
92 // Revision 1.15 2001/05/04 09:21:01 oldi
93 // Changed TMath::TMath:: to TMath::
94 //
95 // Revision 1.14 2001/04/25 17:54:12 perev
96 // HPcorrs
97 //
98 // Revision 1.13 2001/04/02 14:20:15 oldi
99 // Some minor changes due to Insure++ was reporting problems.
100 // These changes do not affect the physical output of StFtpcTrackMaker!
101 //
102 // Revision 1.12 2001/01/30 13:31:48 oldi
103 // New variable mTime introduced to count total time consumption.
104 //
105 // Revision 1.11 2001/01/25 15:22:31 oldi
106 // Review of the complete code.
107 // Fix of several bugs which caused memory leaks:
108 // - Tracks were not allocated properly.
109 // - Tracks (especially split tracks) were not deleted properly.
110 // - TClonesArray seems to have a problem (it could be that I used it in a
111 // wrong way). I changed all occurences to TObjArray which makes the
112 // program slightly slower but much more save (in terms of memory usage).
113 // Speed up of HandleSplitTracks() which is now 12.5 times faster than before.
114 // Cleanup.
115 //
116 // Revision 1.10 2000/11/28 14:10:11 jcs
117 // set a_large_number frp fdepar
118 //
119 // Revision 1.9 2000/11/23 01:33:16 oldi
120 // Proper initialization of some variables to avoid Insure++ error messages.
121 //
122 // Revision 1.8 2000/11/10 18:39:09 oldi
123 // TBenchmark object 'mBech' moved from StFtpcConfMapper to here. This implied changes in the constructors.
124 // New function CalcEnergyLoss(FDE_FDEPAR_ST *fdepar) which replaces the pams/fde modul.
125 // New function FitAnddEdxAndWrite() introduced which replaces CalcEnergyLoss() and FitAndWrite().
126 //
127 // Revision 1.7 2000/07/18 21:22:17 oldi
128 // Changes due to be able to find laser tracks.
129 // Cleanup: - new functions in StFtpcConfMapper, StFtpcTrack, and StFtpcPoint
130 // to bundle often called functions
131 // - short functions inlined
132 // - formulas of StFormulary made static
133 // - avoid streaming of objects of unknown size
134 // (removes the bunch of CINT warnings during compile time)
135 // - two or three minor bugs cured
136 //
137 // Revision 1.6 2000/07/03 12:48:14 jcs
138 // use (pre)Vertex id to access vertex coordinates for unconstrained fit and
139 // for constrained fit
140 //
141 // Revision 1.5 2000/06/13 14:28:23 oldi
142 // Changed cout to gMessMgr->Message().
143 // Printed output changed (slightly).
144 //
145 // Revision 1.4 2000/05/15 14:28:13 oldi
146 // problem of preVertex solved: if no main vertex is found (z = NaN) StFtpcTrackMaker stops with kStWarn,
147 // refitting procedure completed and included in StFtpcTrackMaker (commented),
148 // new constructor of StFtpcVertex due to refitting procedure,
149 // minor cosmetic changes
150 //
151 // Revision 1.3 2000/05/12 12:59:17 oldi
152 // removed delete operator for mSegment in StFtpcConfMapper (mSegment was deleted twice),
153 // add two new constructors for StFtpcTracker to be able to refit already existing tracks,
154 // minor cosmetics
155 //
156 // Revision 1.2 2000/05/11 15:14:53 oldi
157 // Changed class names *Hit.* due to already existing class StFtpcHit.cxx in StEvent
158 //
159 // Revision 1.1 2000/05/10 13:39:31 oldi
160 // Initial version of StFtpcTrackMaker
161 //
162 
163 //----------Author: Holm G. Hümmler, Markus D. Oldenburg
164 //----------Last Modified: 10.11.2000
165 //----------Copyright: &copy MDO Production 1999
166 
167 #include <math.h>
168 #include "TArrayD.h"
169 #include "TArrayI.h"
170 #include "StFtpcTracker.hh"
171 #include "StFtpcPoint.hh"
172 #include "StFtpcTrack.hh"
173 
174 #include "StMessMgr.h"
175 
177 // //
178 // StFtpcTracker class - interface class for the different Ftpc track algorithms //
179 // //
180 // This class contains the pointers needed to do tracking in the Ftpc i.e. a //
181 // pointer to the vertex, pointers to clusters and tracks. //
182 // //
184 
185 ClassImp(StFtpcTracker)
186 
187 
188 
191 {
192  mBench = 0;
193  mTime = 0.;
194 
195  mVertex = 0;
196  mVertexEast = 0;
197  mVertexWest = 0;
198 
199  mHit = 0;
200  mTrack = 0;
201 
202  mHitsCreated = (Bool_t)kFALSE;
203  mVertexCreated = (Bool_t)kFALSE;
204  mTrackCreated = (Bool_t)kFALSE;
205 
206  mMaxDca = 100.;
207 }
208 
209 
211 StFtpcTracker::StFtpcTracker(TObjArray *hits, StFtpcVertex *vertex, Bool_t bench, Double_t max_Dca)
212 {
213  mBench = 0;
214  if (bench) {
215  mBench = new TBenchmark();
216  }
217 
218  mTime = 0.;
219 
220  mHit = hits;
221  mHitsCreated = (Bool_t)kFALSE;
222 
223  mMaxDca = max_Dca;
224  mTrack = new TObjArray(2000);
225  mTrack->SetOwner(kTRUE);
226  mTrackCreated = 1;
227  mVertex = vertex;
228  mVertexCreated = (Bool_t)kFALSE;
229 
230  mVertexEast = new StFtpcVertex();
231  mVertexWest = new StFtpcVertex();
232 }
233 
235 StFtpcTracker::StFtpcTracker(StFtpcVertex *vertex, TObjArray *hit, TObjArray *track, Bool_t bench, Double_t max_Dca)
236 {
237  mBench = 0;
238  if (bench) {
239  mBench = new TBenchmark();
240  }
241 
242  mTime = 0.;
243 
244  mVertex = vertex;
245  mHit = hit;
246  mHitsCreated = (Bool_t) kFALSE;
247  mVertexCreated = (Bool_t) kFALSE;
248  mTrackCreated = (Bool_t) kFALSE;
249  mTrack = track;
250  mMaxDca = max_Dca;
251 
252  mVertexEast = new StFtpcVertex();
253  mVertexWest = new StFtpcVertex();
254 }
255 
256 
259 {
260  // delete everything
261 
262  if (mTrack && mTrackCreated) {
263  mTrack->Delete();
264  delete mTrack; mTrack=0;
265  }
266 
267  if (mHit && mHitsCreated) {
268  mHit->Delete();
269  delete mHit; mHit=0;
270  }
271 
272  if (mVertex && mVertexCreated) {
273  delete mVertex; mVertex=0;
274  }
275 
276  if (mBench) {
277  delete mBench; mBench=0;
278  }
279 
280  delete mVertexEast;
281  delete mVertexWest;
282 
283  return;
284 }
285 
286 
289 {
290  EstimateVertex(vertex, -1, iterations);
291  EstimateVertex(vertex, +1, iterations);
292 
293  return;
294 }
295 
296 
298 void StFtpcTracker::EstimateVertex(StFtpcVertex *vertex, Char_t hemisphere, UChar_t iterations)
299 {
300  StFtpcVertex v = *vertex;
301 
302  for (Int_t i = 0; i < iterations; i++) {
303  StFtpcVertex v_new(mTrack, &v, hemisphere);
304  v = v_new;
305  }
306 
307  if (hemisphere == 1) {
308  *mVertexWest = v;
309  }
310 
311  else {
312  // hemisphere == -1
313  *mVertexEast = v;
314  }
315 
316  return;
317 }
318 
319 
322  Char_t sector, UChar_t iterations)
323 {
324  StFtpcVertex v = *vertex;
325  TObjArray tracks(GetNumberOfTracks());
326 
327  for (Int_t tt = 0; tt < GetNumberOfTracks(); tt++) {
328  // loop over all tracks
329 
330  StFtpcTrack *track = (StFtpcTrack*)mTrack->At(tt);
331 
332  if (track->GetSector() == sector) {
333  // fill matching tracks to new array
334 
335  tracks.AddLast(track);
336  }
337  }
338 
339  for (Int_t i = 0; i < iterations; i++) {
340 
341  StFtpcVertex v_new(&tracks, &v, hemisphere);
342  v = v_new;
343  }
344 
345  return v;
346 }
347 
348 
349 
352  Double_t lowAngle, Double_t highAngle,
353  Double_t lowRadius, Double_t highRadius,
354  UChar_t iterations)
355 {
356  StFtpcVertex v = *vertex;
357 
358  TObjArray tracks(GetNumberOfTracks());
359 
360  for (Int_t tt = 0; tt < GetNumberOfTracks(); tt++) {
361  // loop over all tracks
362 
363  StFtpcTrack *track = (StFtpcTrack*)mTrack->At(tt);
364 
365  if (track->GetMeanR() >= lowRadius && track->GetMeanR() < highRadius &&
366  track->GetMeanAlpha() >= lowAngle && track->GetMeanAlpha() < highAngle) {
367  // fill matching tracks to new array
368 
369  tracks.AddLast(track);
370  }
371  }
372 
373  for (Int_t i = 0; i < iterations; i++) {
374  StFtpcVertex v_new(&tracks, &v, hemisphere);
375  v = v_new;
376  }
377 
378  return v;
379 }
380 
381 
388 {
389  Int_t itrk_ok ; // number of acepted tracks
390  Double_t total_charge = 0.0 ; // total charges
391 
392  Int_t itrk; // track counter
393  Int_t icluster; // cluster counter
394  Int_t ihit; // hit counter
395  Int_t hit_p; // pointer to next hit on a track
396  Int_t all_hit; // total number of hits
397  Int_t acc_hit; // accepted number of hits
398 
399  Double_t *dedx_arr=0; // tmp array to store delta_E of hits on a track
400  TArrayD dedx_arrT;
401  Int_t *index_arr = 0;
402  TArrayI index_arrT;
403  StFtpcTrack *track; // track
404  StFtpcPoint *hit; // hit
405 
406  Double_t xx, yy, rr, px, py, pz, pp, ftmp; // local coor. + mom
407  Double_t cos_lambda, cos_alpha; // cosines of dip and cross angles
408 
409  Double_t dedx_mean;
410 
411  // variables for full chamber truncation
412  Double_t *weighted=0;
413  TArrayD weightedT;
414  Double_t average_dedx;
415  Int_t n_tracked;
416  Int_t n_untracked;
417 
418  if (StFtpcTrackingParams::Instance()->DebugLevel() < 8) {
419  LOG_DEBUG << " No track = " << GetNumberOfTracks() << endm;
420  LOG_DEBUG << " max_track = " << StFtpcTrackingParams::Instance()->MaxTrack() << endm;
421  LOG_DEBUG << " max_hit = " << StFtpcTrackingParams::Instance()->MaxHit() << endm;
422  LOG_DEBUG << " min_hit = " << StFtpcTrackingParams::Instance()->MinHit() << endm;;
423  LOG_DEBUG << " ftrunc = " << StFtpcTrackingParams::Instance()->FracTrunc() << endm;
424 
425  LOG_DEBUG << " name= (no name), nok = (" << GetNumberOfClusters()
426  << "), maxlen = (" << GetNumberOfClusters() << ")" << endm;
427  LOG_DEBUG << " name= (no mane), nok = (" << GetNumberOfTracks()
428  << "), maxlen = (" << GetNumberOfTracks() << ")" << endm;
429  //LOG_DEBUG << " name= (" << fdepar_h->name << "), nok = (" << fdepar_h->nok
430  // << "), maxlen = (" << fdepar_h->maxlen << ")" << endm;
431  }
432 
433  // initialize the dedx table counter
434  itrk_ok = 0;
435  n_tracked = 0;
436 
437  // tmp array to store delta_E of hits on a track
438  int nMaxHit = StFtpcTrackingParams::Instance()->MaxHit();
439  if (dedx_arrT.GetSize()<nMaxHit) dedx_arrT.Set(nMaxHit);
440  dedx_arrT.Reset();
441  dedx_arr = dedx_arrT.GetArray();;
442  if (index_arrT.GetSize()<nMaxHit) index_arrT.Set(nMaxHit);
443  index_arr = index_arrT.GetArray();
444 
445  // loop over all tracks inside the FTPC for each track
446  // possible to limit number of tracks for processing
447  for (itrk = 0; itrk < TMath::Min(GetNumberOfTracks(), StFtpcTrackingParams::Instance()->MaxTrack()); itrk++) {
448 
449  all_hit = 0;
450  track = (StFtpcTrack*)mTrack->At(itrk);
451 
452  // we accumulate all the charges inside the sensitive volume
453  for (icluster = 0; icluster < track->GetNumberOfPoints(); icluster++) {
454  hit = (StFtpcPoint*)((TObjArray*)track->GetHits())->At(icluster);
455  hit_p = hit->GetHitNumber();
456 
457  if(hit_p >= 0) {
458  total_charge += hit->GetCharge();
459  all_hit++;
460  n_tracked++;
461 
462  if (StFtpcTrackingParams::Instance()->DebugLevel() < 2 ) { // level=1 debugging
463  LOG_DEBUG << "total_charge = " << total_charge << ", hit_p = " << hit_p
464  << ", de = " << hit->GetCharge() << endm;
465  }
466  }
467  }
468 
469  if (all_hit < StFtpcTrackingParams::Instance()->MinHit() || all_hit > StFtpcTrackingParams::Instance()->MaxHit()) {
470 
471  if (StFtpcTrackingParams::Instance()->DebugLevel() < 5) { // level = 10 debugging
472  LOG_DEBUG << " number of hits = " << all_hit << endm;
473  }
474 
475  continue; // skip if unacceptable no. hits
476  }
477 
478  // use vertex momenta instead of local momenta,
479  // as angle to z-axis stays constant along the helix
480  // through the b-field
481  px = track->GetPx();
482  py = track->GetPy();
483  pz = track->GetPz();
484  pp = track->GetP();
485 
486  // fill the array after correcting the track length
487  for (icluster = 0, ihit = 0; icluster < track->GetNumberOfPoints(); icluster++) {
488  hit = (StFtpcPoint*)((TObjArray*)track->GetHits())->At(icluster);
489  hit_p = hit->GetHitNumber();
490 
491  if(hit_p >= 0) {
492 
493  if (StFtpcTrackingParams::Instance()->NoAngle() != 0) {
494  cos_lambda = 1.0;
495  cos_alpha = 1.0;
496  }
497 
498  else {
499  xx = hit->GetX();
500  yy = hit->GetY();
501  rr = TMath::Sqrt(xx*xx + yy*yy);
502  xx = xx/rr; // normalized
503  yy = yy/rr;
504 
505  ftmp = (xx*px + yy*py)/pp;
506  cos_lambda = TMath::Sqrt(1. - ftmp*ftmp);
507  ftmp = yy*px - xx*py;
508  cos_alpha = fabs(pz) / TMath::Sqrt(pz*pz + ftmp*ftmp);
509  }
510 
511  if (StFtpcTrackingParams::Instance()->DebugLevel() < 2 ) { // level=1 debugging
512  LOG_DEBUG << " ANGLES: dip= "<< 180./3.14159 * TMath::ACos(cos_lambda) << "("
513  << cos_lambda << "); cross= " << 180./3.14159 * TMath::ACos(cos_alpha)
514  << "(" << cos_alpha << ") [deg]; P=(" << px << ", " << py << ", "
515  << pz << endm;
516  }
517 
518  if ( cos_alpha == 0. || cos_lambda == 0. ) {
519  dedx_arr[ihit] = StFtpcTrackingParams::Instance()->ALargeNumber();
520  }
521 
522  else {
523  dedx_arr[ihit] = hit->GetCharge() * cos_alpha*cos_lambda;
524 
525  if(dedx_arr[ihit]<0) {
526  LOG_DEBUG << dedx_arr[ihit] << " " << hit->GetCharge()
527  << " " << cos_alpha << " " << cos_lambda << endm;
528  }
529  }
530 
531  ihit++;
532  }
533  }
534 
535 
536  // sort hits on this track acording to dE/dx
537  Sorter(dedx_arr, index_arr, all_hit);
538 
539  // calculate the truncated mean of dE/dx
540  acc_hit = 0;
541  dedx_mean = 0.0;
542 
543  for (ihit = 0; ihit < (Int_t)(all_hit*StFtpcTrackingParams::Instance()->FracTrunc()); ihit++) {
544  acc_hit++;
545  dedx_mean += dedx_arr[ihit];
546  }
547 
548  if (acc_hit < 1) continue;
549 
550  dedx_mean /= (Double_t)acc_hit;
551 
552  // fill the output table
553  track->SetdEdx(dedx_mean);
554  track->SetNumdEdxHits(acc_hit);
555 
556  if(track->GetdEdx() == 0) {
557  LOG_DEBUG << "track " << itrk << " dedx " << track->GetdEdx()
558  << " ndedx " << track->GetNumdEdxHits() << endm;
559  }
560 
561  itrk_ok++;
562 
563  } // end loop itrk
564 
565  if(StFtpcTrackingParams::Instance()->IdMethod() == 1) {
566  LOG_DEBUG << "Using truncated mean over whole chamber method by R. Witt." << endm;
567  int nClusters = GetNumberOfClusters();
568  if (weightedT.GetSize() <nClusters) weightedT.Set(nClusters);
569  weighted =weightedT.GetArray();
570  if (index_arrT.GetSize()<nClusters) index_arrT.Set(nClusters);
571  index_arr = index_arrT.GetArray();
572 
573  weightedT.Reset();index_arrT.Reset(-2);
574 
575  average_dedx=0;
576 
577  for (itrk = 0; itrk < TMath::Min(GetNumberOfTracks(), StFtpcTrackingParams::Instance()->MaxTrack()); itrk++) {
578  track = (StFtpcTrack*)mTrack->At(itrk);
579  px = track->GetPx();
580  py = track->GetPy();
581  pz = track->GetPz();
582  pp = track->GetP();
583 
584  average_dedx += track->GetdEdx();
585 
586  for (icluster = 0; icluster < track->GetNumberOfPoints(); icluster++) {
587  hit = (StFtpcPoint*)((TObjArray*)track->GetHits())->At(icluster);
588  hit_p = hit->GetHitNumber();
589 
590  if (hit_p >= 0) {
591 
592  if (StFtpcTrackingParams::Instance()->NoAngle() != 0) {
593  cos_lambda = 1.0;
594  cos_alpha = 1.0;
595  }
596 
597  else {
598  xx = hit->GetX();
599  yy = hit->GetY();
600  rr = TMath::Sqrt(xx*xx + yy*yy);
601  xx = xx/rr; // normalized
602  yy = yy/rr;
603 
604  ftmp = (xx*px + yy*py)/pp;
605  cos_lambda = TMath::Sqrt(1. - ftmp*ftmp);
606  ftmp = yy*px - xx*py;
607  cos_alpha = fabs(pz) / TMath::Sqrt(pz*pz + ftmp*ftmp);
608  }
609 
610  if (cos_alpha == 0. || cos_lambda == 0.) {
611  weighted[hit_p] = StFtpcTrackingParams::Instance()->ALargeNumber();
612  }
613 
614  else {
615  weighted[hit_p] = hit->GetCharge() * cos_alpha*cos_lambda / track->GetdEdx();
616  }
617 
618  index_arr[hit_p] = hit_p;
619  }
620  }
621  }
622 
623  average_dedx /= TMath::Min(GetNumberOfTracks(), StFtpcTrackingParams::Instance()->MaxTrack());
624 
625  Sorter(weighted, index_arr, GetNumberOfClusters());
626 
627  // remove all hits over truncation threshold
628  n_untracked = GetNumberOfClusters() - n_tracked;
629 
630  for(ihit = 0; ihit < GetNumberOfClusters(); ihit++) {
631 
632  if(index_arr[ihit]>=0) {
633 
634  if(ihit >= (n_untracked +(Int_t)(StFtpcTrackingParams::Instance()->FracTrunc()*(Double_t) n_tracked))) {
635  index_arr[ihit]=-1;
636  }
637  }
638  }
639 
640  for (itrk = 0; itrk < TMath::Min(GetNumberOfTracks(), StFtpcTrackingParams::Instance()->MaxTrack()); itrk++) {
641  acc_hit = 0;
642  dedx_mean = 0;
643 
644  track = (StFtpcTrack*)mTrack->At(itrk);
645 
646  for (icluster=0; icluster<track->GetNumberOfPoints(); icluster++) {
647  // use vertex momenta instead of local momenta,
648  // as angle to z-axis stays constant along the helix
649  // through the b-field
650  px = track->GetPx();
651  py = track->GetPy();
652  pz = track->GetPz();
653  pp = track->GetP();
654 
655  hit = (StFtpcPoint*)((TObjArray*)track->GetHits())->At(icluster);
656  hit_p = hit->GetHitNumber();
657 
658  if(hit_p>=0) {
659 
660  for(ihit=n_untracked; ihit<GetNumberOfClusters(); ihit++) {
661 
662  if(hit_p == index_arr[ihit]) {
663  acc_hit++;
664 
665  if (StFtpcTrackingParams::Instance()->NoAngle() != 0) {
666  cos_lambda = 1.0;
667  cos_alpha = 1.0;
668  }
669 
670  else {
671  xx = hit->GetX();
672  yy = hit->GetY();
673  rr = TMath::Sqrt(xx*xx + yy*yy);
674  xx = xx/rr; // normalized
675  yy = yy/rr;
676 
677  ftmp = (xx*px+yy*py)/pp;
678  cos_lambda = TMath::Sqrt(1. - ftmp*ftmp);
679  ftmp = yy*px-xx*py;
680  cos_alpha = fabs(pz) / TMath::Sqrt(pz*pz + ftmp*ftmp);
681  }
682 
683  if (cos_alpha == 0. || cos_lambda == 0.) {
684  acc_hit--;
685  }
686 
687  else {
688  dedx_mean += hit->GetCharge() * cos_alpha*cos_lambda;
689  }
690  }
691  }
692  }
693  }
694 
695  if (acc_hit < 1) continue;
696 
697  dedx_mean /= (Double_t)acc_hit;
698  track->SetdEdx(dedx_mean);
699  track->SetNumdEdxHits(acc_hit);
700  }
701 
702  }
703 
704  if (StFtpcTrackingParams::Instance()->DebugLevel() < 11) {
705  LOG_DEBUG << " total charges in 2 FTPCs " << total_charge << endm;
706  LOG_DEBUG << " processed tracks = " << itrk_ok << endm;
707  }
708 
709  return;
710 }
711 
712 
713 
718 void StFtpcTracker::Sorter(Double_t *arr, Int_t *index, Int_t len)
719 {
720  Int_t i, j;
721  Double_t temp;
722  Int_t itemp;
723 
724  for (i=0; i<len-2; ++i) {
725 
726  for (j = len-1; j > i; --j) {
727 
728  if (arr[i] > arr[j]) {
729  temp = arr[i]; // swap
730  arr[i] = arr[j];
731  arr[j]= temp;
732  itemp = index[i];
733  index[i] = index[j];
734  index[j] = itemp;
735  }
736  }
737  }
738 }
739 
740 
744 Int_t StFtpcTracker::Fit(Bool_t primary_fit)
745 {
746  if (mTrack) {
747  StFtpcTrack *track=0;
748 
749  for (Int_t i=0; i<mTrack->GetEntriesFast(); i++) {
750  track = (StFtpcTrack *)mTrack->At(i);
751  track->Fit(mVertex, mMaxDca, primary_fit);
752  }
753 
754  return -1;
755  }
756 
757  return 0;
758  }
759 
760 
761 // Calculates the momentum fit and dE/dx (no writing!).
762 Int_t StFtpcTracker::FitAnddEdx(Bool_t primary_fit)
763 {
764  if (mBench) {
765  mBench->Start("fit");
766  }
767 
768  if (mTrack) {
769 
770  Int_t itrk_ok ; // number of acepted tracks
771  Double_t total_charge = 0.0 ; // total charges
772 
773  Int_t itrk; // track counter
774  Int_t icluster; // cluster counter
775  Int_t ihit; // hit counter
776  Int_t hit_p; // pointer to next hit on a track
777  Int_t all_hit; // total number of hits
778  Int_t acc_hit; // accepted number of hits
779 
780  Double_t *dedx_arr=0; // tmp array to store delta_E of hits on a track
781  TArrayD dedx_arrT;
782  Int_t *index_arr;
783  TArrayI index_arrT;
784  StFtpcTrack *track; // track
785  StFtpcPoint *hit; // hit
786 
787  Double_t xx, yy, rr, px, py, pz, pp, ftmp; // local coor. + mom
788  Double_t cos_lambda, cos_alpha; // cosines of dip and cross angles
789 
790  Double_t dedx_mean;
791 
792  // variables for full chamber truncation
793  TArrayD weightedT;
794  Double_t *weighted=0;
795  Double_t average_dedx;
796  Int_t n_tracked;
797  Int_t n_untracked;
798 
799  // initialize the dedx table counter
800  itrk_ok = 0;
801  n_tracked = 0;
802 
803  // tmp array to store delta_E of hits on a track
804  int nMaxHit = StFtpcTrackingParams::Instance()->MaxHit();
805  if (dedx_arrT.GetSize()<nMaxHit) dedx_arrT.Set(nMaxHit);
806  dedx_arrT.Reset();
807  dedx_arr = dedx_arrT.GetArray();;
808  if (index_arrT.GetSize()<nMaxHit) index_arrT.Set(nMaxHit);
809  index_arr = index_arrT.GetArray();
810 
811  // loop over all tracks inside the FTPC for each track
812  // possible to limit number of tracks for processing
813  for (itrk = 0; itrk < TMath::Min(GetNumberOfTracks(), StFtpcTrackingParams::Instance()->MaxTrack()); itrk++) {
814  all_hit = 0;
815  track = (StFtpcTrack*)mTrack->At(itrk);
816  track->Fit(mVertex, mMaxDca, primary_fit);
817 
818  // we accumulate all the charges inside the sensitive volume
819  for (icluster = 0; icluster < track->GetNumberOfPoints(); icluster++) {
820  hit = (StFtpcPoint*)((TObjArray*)track->GetHits())->At(icluster);
821  hit_p = hit->GetHitNumber();
822 
823  if (hit_p >= 0) {
824  total_charge += hit->GetCharge();
825  all_hit++;
826  n_tracked++;
827  }
828  }
829 
830  if (all_hit < StFtpcTrackingParams::Instance()->MinHit() || all_hit > StFtpcTrackingParams::Instance()->MaxHit()) {
831  continue; // skip if unacceptable no. hits
832  }
833 
834  // use vertex momenta instead of local momenta,
835  // as angle to z-axis stays constant along the helix
836  // through the b-field
837  px = track->GetPx();
838  py = track->GetPy();
839  pz = track->GetPz();
840  pp = track->GetP();
841  if (pp<1.e-3) continue;
842 
843  // fill the array after correcting the track length
844  for (icluster = 0, ihit = 0; icluster < track->GetNumberOfPoints(); icluster++) {
845  hit = (StFtpcPoint*)((TObjArray*)track->GetHits())->At(icluster);
846  hit_p = hit->GetHitNumber();
847 
848  if(hit_p >= 0) {
849 
850  if (StFtpcTrackingParams::Instance()->NoAngle() != 0) {
851  cos_lambda = 1.0;
852  cos_alpha = 1.0;
853  }
854 
855  else {
856  xx = hit->GetX();
857  yy = hit->GetY();
858  rr = TMath::Sqrt(xx*xx + yy*yy);
859  xx = xx/rr; // normalized
860  yy = yy/rr;
861 
862  ftmp = (xx*px + yy*py)/pp;
863  cos_lambda = TMath::Sqrt(1. - ftmp*ftmp);
864  ftmp = yy*px - xx*py;
865  cos_alpha = fabs(pz) / TMath::Sqrt(pz*pz + ftmp*ftmp);
866  }
867 
868  if ( cos_alpha == 0. || cos_lambda == 0. ) {
869  dedx_arr[ihit] = StFtpcTrackingParams::Instance()->ALargeNumber();
870  }
871 
872  else {
873  dedx_arr[ihit] = hit->GetCharge() * cos_alpha*cos_lambda;
874  }
875 
876  ihit++;
877  }
878  }
879 
880 
881  // sort hits on this track acording to dE/dx
882  Sorter(dedx_arr, index_arr, all_hit);
883 
884  // calculate the truncated mean of dE/dx
885  acc_hit = 0;
886  dedx_mean = 0.0;
887 
888  for (ihit = 0; ihit < (Int_t)(all_hit*StFtpcTrackingParams::Instance()->FracTrunc()); ihit++) {
889  acc_hit++;
890  dedx_mean += dedx_arr[ihit];
891  }
892 
893  if (acc_hit < 1) continue;
894 
895  dedx_mean /= (Double_t)acc_hit;
896 
897  // fill the output table
898  track->SetdEdx(dedx_mean);
899  track->SetNumdEdxHits(acc_hit);
900 
901  itrk_ok++;
902 
903  if (itrk > GetNumberOfTracks()) {
904  break;
905  }
906 
907  } // end loop itrk
908 
909  if(StFtpcTrackingParams::Instance()->IdMethod() == 1) {
910  LOG_DEBUG << "Using truncated mean over whole chamber method by R. Witt." << endm;
911  int nClusters=GetNumberOfClusters();
912  if (weightedT.GetSize()<nClusters) weightedT.Set(nClusters);
913  weighted = weightedT.GetArray();
914  if (index_arrT.GetSize()<nClusters) index_arrT.Set(nClusters);
915  index_arr = index_arrT.GetArray();
916 
917  for(ihit=0; ihit<GetNumberOfClusters(); ihit++) {
918  weighted[ihit] = 0;
919  index_arr[ihit] = -2;
920  }
921 
922  average_dedx=0;
923 
924  for (itrk = 0; itrk < TMath::Min(GetNumberOfTracks(), StFtpcTrackingParams::Instance()->MaxTrack()); itrk++) {
925  track = (StFtpcTrack*)mTrack->At(itrk);
926  px = track->GetPx();
927  py = track->GetPy();
928  pz = track->GetPz();
929  pp = track->GetP();
930  if (pp <1.e-3) continue;
931  average_dedx += track->GetdEdx();
932 
933  for (icluster = 0; icluster < track->GetNumberOfPoints(); icluster++) {
934  hit = (StFtpcPoint*)((TObjArray*)track->GetHits())->At(icluster);
935  hit_p = hit->GetHitNumber();
936 
937  if (hit_p >= 0) {
938 
939  if (StFtpcTrackingParams::Instance()->NoAngle() != 0) {
940  cos_lambda = 1.0;
941  cos_alpha = 1.0;
942  }
943 
944  else {
945  xx = hit->GetX();
946  yy = hit->GetY();
947  rr = TMath::Sqrt(xx*xx + yy*yy);
948  xx = xx/rr; // normalized
949  yy = yy/rr;
950 
951  ftmp = (xx*px + yy*py)/pp;
952  cos_lambda = TMath::Sqrt(1. - ftmp*ftmp);
953  ftmp = yy*px - xx*py;
954  cos_alpha = fabs(pz) / TMath::Sqrt(pz*pz + ftmp*ftmp);
955  }
956 
957  if (cos_alpha == 0. || cos_lambda == 0.) {
958  weighted[hit_p] = StFtpcTrackingParams::Instance()->ALargeNumber();
959  }
960 
961  else {
962  weighted[hit_p] = hit->GetCharge() * cos_alpha*cos_lambda / track->GetdEdx();
963  }
964 
965  index_arr[hit_p] = hit_p;
966  }
967  }
968  }
969 
970  if (average_dedx) average_dedx /= TMath::Min(GetNumberOfTracks(), StFtpcTrackingParams::Instance()->MaxTrack());
971 
972  Sorter(weighted, index_arr, GetNumberOfClusters());
973 
974  // remove all hits over truncation threshold
975  n_untracked = GetNumberOfClusters() - n_tracked;
976 
977  for(ihit = 0; ihit < GetNumberOfClusters(); ihit++) {
978 
979  if(index_arr[ihit]>=0) {
980 
981  if(ihit >= (n_untracked +(Int_t)(StFtpcTrackingParams::Instance()->FracTrunc()*(Double_t) n_tracked))) {
982  index_arr[ihit]=-1;
983  }
984  }
985  }
986 
987  for (itrk = 0; itrk < TMath::Min(GetNumberOfTracks(), StFtpcTrackingParams::Instance()->MaxTrack()); itrk++) {
988  acc_hit = 0;
989  dedx_mean = 0;
990 
991  track = (StFtpcTrack*)mTrack->At(itrk);
992 
993  for (icluster=0; icluster<track->GetNumberOfPoints(); icluster++) {
994  // use vertex momenta instead of local momenta,
995  // as angle to z-axis stays constant along the helix
996  // through the b-field
997  px = track->GetPx();
998  py = track->GetPy();
999  pz = track->GetPz();
1000  pp = track->GetP();
1001  if (pp <1.E-3) continue;
1002  hit = (StFtpcPoint*)((TObjArray*)track->GetHits())->At(icluster);
1003  hit_p = hit->GetHitNumber();
1004 
1005  if(hit_p>=0) {
1006 
1007  for(ihit=n_untracked; ihit<GetNumberOfClusters(); ihit++) {
1008 
1009  if(hit_p == index_arr[ihit]) {
1010  acc_hit++;
1011 
1012  if (StFtpcTrackingParams::Instance()->NoAngle() != 0) {
1013  cos_lambda = 1.0;
1014  cos_alpha = 1.0;
1015  }
1016 
1017  else {
1018  xx = hit->GetX();
1019  yy = hit->GetY();
1020  rr = TMath::Sqrt(xx*xx + yy*yy);
1021  xx = xx/rr; // normalized
1022  yy = yy/rr;
1023 
1024  ftmp = (xx*px+yy*py)/pp;
1025  cos_lambda = TMath::Sqrt(1. - ftmp*ftmp);
1026  ftmp = yy*px-xx*py;
1027  cos_alpha = fabs(pz) / TMath::Sqrt(pz*pz + ftmp*ftmp);
1028  }
1029 
1030  if (cos_alpha == 0. || cos_lambda == 0.) {
1031  acc_hit--;
1032  }
1033 
1034  else {
1035  dedx_mean += hit->GetCharge() * cos_alpha*cos_lambda;
1036  }
1037  }
1038  }
1039  }
1040  }
1041 
1042  if (acc_hit < 1) {
1043  continue;
1044  }
1045 
1046  dedx_mean /= (Double_t)acc_hit;
1047  track->SetdEdx(dedx_mean);
1048  track->SetNumdEdxHits(acc_hit);
1049  }
1050 
1051  }
1052 
1053 
1054  if(mBench) {
1055  mBench->Stop("fit");
1056  LOG_DEBUG << "Fit and dE/dx calc. finished (" << mBench->GetCpuTime("fit") << " s)." << endm;
1057  mTime += mBench->GetCpuTime("fit");
1058  }
1059 
1060  return 0;
1061  }
1062 
1063  else {
1064 
1065  if(mBench) {
1066  mBench->Stop("fit");
1067  LOG_DEBUG << "Fit, dE/dx, writing finished (" << mBench->GetCpuTime("fit") << " s)." << endm;
1068  mTime += mBench->GetCpuTime("fit");
1069  }
1070 
1071  LOG_WARN << "Tracks not written (No tracks found!)." << endm;
1072  return -1;
1073  }
1074 }
Int_t Fit(Bool_t primary_fit)
StFtpcTracker()
Default constructor. Sets the pointers to 0 an cut for momentum fit loosely.
void CalcEnergyLoss()
virtual ~StFtpcTracker()
Destructor.
void EstimateVertex(StFtpcVertex *vertex, UChar_t iterations=1)
Vertex estimation with fit tracks for FTPC east and west.
void Sorter(Double_t *arr, Int_t *index, Int_t len)