184 #include "StFtpcConfMapper.hh"
185 #include "StFtpcTrackingParams.hh"
186 #include "StFtpcConfMapPoint.hh"
187 #include "StFtpcTrack.hh"
188 #include "StFormulary.hh"
189 #include "MIntArray.h"
192 #include "TBenchmark.h"
197 #include "TPolyMarker.h"
202 #include "TPolyLine3D.h"
203 #include "TPolyMarker3D.h"
207 #include "StMessMgr.h"
223 mLaser = (Bool_t)kFALSE;
227 mVertexConstraint = (Bool_t)kTRUE;
232 Int_t phi_segments, Int_t eta_segments)
238 mBench->Start(
"init");
241 mLaser = (Bool_t)kFALSE;
243 mNumRowSegment = StFtpcTrackingParams::Instance()->RowSegments();
244 mNumPhiSegment = StFtpcTrackingParams::Instance()->PhiSegments();
245 mNumEtaSegment = StFtpcTrackingParams::Instance()->EtaSegments();
246 mBounds = mNumRowSegment * mNumPhiSegment * mNumEtaSegment;
247 mMaxFtpcRow = StFtpcTrackingParams::Instance()->NumberOfPadRowsPerSide();
251 mMainVertexTracks = 0;
253 mMergedTracklets = 0;
260 Int_t n_clusters = inputHits->GetEntriesFast();
261 Int_t n_goodclusters = good_hits->CountAppearance(1);
262 mClustersUnused = n_goodclusters;
266 mHit =
new TObjArray(n_goodclusters);
267 mHitsCreated = (Bool_t)kTRUE;
268 Int_t good_hits_counted = 0;
270 {
for (Int_t i = 0; i < n_clusters; i++) {
273 if (good_hits->At(i) == 1) {
275 mHit->AddAt(hit, good_hits_counted);
276 hit->SetHitNumber(i);
277 if (hit->GetUnusableForTrackingFlag()) mBadClusters++;
282 mVolume =
new TObjArray(mBounds+1);
284 {
for (Int_t i = 0; i <= mBounds; i++) {
285 mVolume->AddAt(
new TObjArray(0), i);
290 {
for (Int_t i = 0; i < mHit->GetEntriesFast(); i++) {
293 ((TObjArray *)mVolume->At(GetSegm(hit)))->AddLast(hit);
297 mBench->Stop(
"init");
298 LOG_DEBUG <<
"Setup finished (" << mBench->GetCpuTime(
"init") <<
" s)." << endm;
299 mTime += mBench->GetCpuTime(
"init");
304 StFtpcConfMapper::StFtpcConfMapper(TObjArray *hits,
StFtpcVertex *vertex, Bool_t bench,
305 Int_t phi_segments, Int_t eta_segments)
311 mBench->Start(
"init");
314 mLaser = (Bool_t)kFALSE;
316 mNumRowSegment = StFtpcTrackingParams::Instance()->RowSegments();
317 mNumPhiSegment = StFtpcTrackingParams::Instance()->PhiSegments();
318 mNumEtaSegment = StFtpcTrackingParams::Instance()->EtaSegments();
319 mBounds = mNumRowSegment * mNumPhiSegment * mNumEtaSegment;
320 mMaxFtpcRow = StFtpcTrackingParams::Instance()->NumberOfPadRowsPerSide();
324 mMainVertexTracks = 0;
326 mMergedTracklets = 0;
333 mClustersUnused = mHit->GetEntriesFast();
336 mVolume =
new TObjArray(mBounds+1);
338 {
for (Int_t i = 0; i <= mBounds; i++) {
339 mVolume->AddAt(
new TObjArray(0), i);
344 {
for (Int_t i = 0; i < mHit->GetEntriesFast(); i++) {
346 hit->SetHitNumber(i);
347 if (hit->GetUnusableForTrackingFlag()) mBadClusters++;
349 ((TObjArray *)mVolume->At(GetSegm(hit)))->AddLast(hit);
353 mBench->Stop(
"init");
354 LOG_DEBUG <<
"Setup finished (" << mBench->GetCpuTime(
"init") <<
" s)." << endm;
355 mTime += mBench->GetCpuTime(
"init");
360 StFtpcConfMapper::~StFtpcConfMapper()
366 delete mVolume; mVolume=0;
376 track->SetPointDependencies();
377 track->ComesFromMainVertex(mVertexConstraint);
378 track->CalculateNMax();
380 mClustersUnused -= track->GetNumberOfPoints();
381 if (mVertexConstraint) mMainVertexTracks++;
387 void StFtpcConfMapper::MainVertexTracking()
392 mBench->Start(
"main_vertex");
395 Settings(
"main_vertex");
401 mBench->Stop(
"main_vertex");
402 LOG_DEBUG <<
"Main vertex tracking finished (" << mBench->GetCpuTime(
"main_vertex") <<
" s)." << endm;
403 mTime += mBench->GetCpuTime(
"main_vertex");
405 mBench->Start(
"extend");
411 mBench->Stop(
"extend");
412 LOG_DEBUG <<
"Track extension finished (" << mBench->GetCpuTime(
"extend") <<
" s)." << endm;
413 mTime += mBench->GetCpuTime(
"extend");
415 mBench->Start(
"splits");
421 mBench->Stop(
"splits");
422 LOG_DEBUG <<
"Split track merging finished (" << mBench->GetCpuTime(
"splits") <<
" s)." << endm;
423 mTime += mBench->GetCpuTime(
"splits");
430 void StFtpcConfMapper::FreeTracking()
435 mBench->Start(
"non_vertex");
438 Settings(
"non_vertex");
444 mBench->Stop(
"non_vertex");
445 LOG_DEBUG <<
"Non vertex tracking finished (" << mBench->GetCpuTime(
"non_vertex") <<
" s)." << endm;
446 mTime += mBench->GetCpuTime(
"non_vertex");
453 void StFtpcConfMapper::LaserTracking()
459 mBench->Start(
"laser");
468 mBench->Stop(
"laser");
469 LOG_DEBUG <<
"Laser tracking finished (" << mBench->GetCpuTime(
"laser") <<
" s)." << endm;
470 mTime += mBench->GetCpuTime(
"laser");
471 mBench->GetCpuTime(
"nofield");
473 mBench->Start(
"extend");
479 mBench->Stop(
"extend");
480 LOG_DEBUG <<
"Track extension finished (" << mBench->GetCpuTime(
"extend") <<
" s)." << endm;
481 mTime += mBench->GetCpuTime(
"extend");
483 mBench->Start(
"splits");
489 mBench->Stop(
"splits");
490 LOG_DEBUG <<
"Split track merging finished (" << mBench->GetCpuTime(
"splits") <<
" s)." << endm;
491 mTime += mBench->GetCpuTime(
"splits");
498 void StFtpcConfMapper::NoFieldTracking()
504 mBench->Start(
"no_field");
507 Settings(
"no_field");
513 mBench->Stop(
"no_field");
514 LOG_DEBUG <<
"No field tracking finished (" << mBench->GetCpuTime(
"no_field") <<
" s)." << endm;
515 mBench->GetCpuTime(
"no_field");
517 mBench->Start(
"extend");
523 mBench->Stop(
"extend");
524 LOG_DEBUG <<
"Track extension finished (" << mBench->GetCpuTime(
"extend") <<
" s)." << endm;
525 mTime += mBench->GetCpuTime(
"extend");
527 mBench->Start(
"splits");
533 mBench->Stop(
"splits");
534 LOG_DEBUG <<
"Split track merging finished (" << mBench->GetCpuTime(
"splits") <<
" s)." << endm;
535 mTime += mBench->GetCpuTime(
"splits");
541 void StFtpcConfMapper::Settings(TString method) {
546 if (method ==
"main_vertex") {
550 else if (method ==
"non_vertex") {
554 else if (method ==
"no_field") {
558 else if (method ==
"laser") {
568 void StFtpcConfMapper::Settings(Int_t method_id) {
571 SetLaser(StFtpcTrackingParams::Instance()->Laser(method_id));
572 SetMaxDca(StFtpcTrackingParams::Instance()->MaxDca(method_id));
573 SetVertexConstraint(StFtpcTrackingParams::Instance()->VertexConstraint(method_id));
574 SetTrackletLength(StFtpcTrackingParams::Instance()->MaxTrackletLength(method_id));
575 SetRowScopeTracklet(StFtpcTrackingParams::Instance()->RowScopeTracklet(method_id));
576 SetMinPoints(StFtpcTrackingParams::Instance()->MinTrackLength(method_id));
577 SetRowScopeTrack(StFtpcTrackingParams::Instance()->RowScopeTrack(method_id));
578 SetPhiScope(StFtpcTrackingParams::Instance()->PhiScope(method_id));
579 SetEtaScope(StFtpcTrackingParams::Instance()->EtaScope(method_id));
585 void StFtpcConfMapper::Cuts(TString method) {
590 if (method ==
"main_vertex") {
594 else if (method ==
"non_vertex") {
598 else if (method ==
"no_field") {
602 else if (method ==
"laser") {
612 void StFtpcConfMapper::Cuts(Int_t method_id) {
615 SetMaxAngleTracklet(StFtpcTrackingParams::Instance()->MaxAngleTracklet(method_id));
616 SetMaxAngleTrack(StFtpcTrackingParams::Instance()->MaxAngleTrack(method_id));
617 SetMaxCircleDistTrack(StFtpcTrackingParams::Instance()->MaxCircleDist(method_id));
618 SetMaxLengthDistTrack(StFtpcTrackingParams::Instance()->MaxLengthDist(method_id));
624 void StFtpcConfMapper::Settings(Int_t trackletlength1, Int_t trackletlength2, Int_t tracklength1, Int_t tracklength2, Int_t rowscopetracklet1, Int_t rowscopetracklet2, Int_t rowscopetrack1, Int_t rowscopetrack2, Int_t phiscope1, Int_t phiscope2, Int_t etascope1, Int_t etascope2)
666 SetTrackletLength(trackletlength1, trackletlength2);
667 SetRowScopeTracklet(rowscopetracklet1, rowscopetracklet2);
668 SetRowScopeTrack(rowscopetrack1, rowscopetrack2);
669 SetPhiScope(phiscope1, phiscope2);
670 SetEtaScope(etascope1, etascope2);
671 SetMinPoints(tracklength1, tracklength2);
675 void StFtpcConfMapper::Cuts(Double_t maxangletracklet1, Double_t maxangletracklet2, Double_t maxangletrack1, Double_t maxangletrack2, Double_t maxcircletrack1, Double_t maxcircletrack2, Double_t maxlengthtrack1, Double_t maxlengthtrack2)
690 SetMaxAngleTracklet(maxangletracklet1, maxangletracklet2);
691 SetMaxAngleTrack(maxangletrack1, maxangletrack2);
692 SetMaxCircleDistTrack(maxcircletrack1, maxcircletrack2);
693 SetMaxLengthDistTrack(maxlengthtrack1, maxlengthtrack2);
697 void StFtpcConfMapper::LoopUpdate(Int_t *sub_row_segm, Bool_t backward)
711 Bool_t
const StFtpcConfMapper::TestExpression(Int_t sub_row_segm, Int_t end_row, Bool_t backward)
717 if (sub_row_segm >= end_row) {
718 return (Bool_t)kTRUE;
722 return (Bool_t) kFALSE;
728 if (sub_row_segm <= end_row) {
729 return (Bool_t)kTRUE;
733 return (Bool_t) kFALSE;
737 return (Bool_t) kFALSE;
749 Double_t phi_diff = TMath::Abs( hit1->GetPhi() - hit2->GetPhi() );
750 if (phi_diff > TMath::Pi()) phi_diff = 2*TMath::Pi() - phi_diff;
752 return TMath::Abs(hit1->GetPadRow() - hit2->GetPadRow()) * (phi_diff + TMath::Abs( hit1->GetEta() - hit2->GetEta() ));
756 return TMath::Sqrt(TMath::Power(hit1->GetX() - hit2->GetX(), 2.) + TMath::Power(hit1->GetY() - hit2->GetY(), 2.) + TMath::Power(hit1->GetZ() - hit2->GetZ(), 2.));
761 Double_t
const StFtpcConfMapper::CalcDistance(
const StFtpcConfMapPoint *hit, Double_t *coeff)
767 Double_t x = (coeff[0] / (1 + coeff[0]*coeff[0])) * (1/coeff[0] * hit->GetXprime() + hit->GetYprime() - coeff[1]);
769 return TMath::Sqrt(TMath::Power(x - hit->GetXprime(), 2) + TMath::Power(coeff[0]*x + coeff[1] - hit->GetYprime(), 2));
777 if (newhit->GetCircleDist() < mMaxCircleDist[mVertexConstraint] &&
778 newhit->GetLengthDist() < mMaxLengthDist[mVertexConstraint] &&
779 TrackAngle(lasttrackhit, newhit, backward) < mMaxAngleTrack[mVertexConstraint]) {
789 Double_t
const StFtpcConfMapper::TrackAngle(
const StFtpcPoint *lasthitoftrack,
const StFtpcPoint *hit, Bool_t backward = (Bool_t)kTRUE)
797 StFtpcTrack *track = lasthitoftrack->GetTrack(mTrack);
798 TObjArray *hits = track->GetHits();
799 Int_t n = track->GetNumberOfPoints();
802 LOG_ERROR <<
"StFtpcConfMapper::TrackAngle(StFtpcPoint *lasthitoftrack, StFtpcPoint *hit)" << endm;
803 LOG_ERROR <<
" - Call this function only if you are sure to have at least two points on the track already!" << endm;
813 x2[0] = hit->GetX() - ((
StFtpcPoint *)hits->At(n-1))->GetX();
814 x2[1] = hit->GetY() - ((
StFtpcPoint *)hits->At(n-1))->GetY();
815 x2[2] = hit->GetZ() - ((
StFtpcPoint *)hits->At(n-1))->GetZ();
823 x2[0] = hit->GetX() - ((
StFtpcPoint *)hits->At(0))->GetX();
824 x2[1] = hit->GetY() - ((
StFtpcPoint *)hits->At(0))->GetY();
825 x2[2] = hit->GetZ() - ((
StFtpcPoint *)hits->At(0))->GetZ();
828 return StFormulary::Angle(x1, x2, 3);
832 Double_t
const StFtpcConfMapper::TrackletAngle(
StFtpcTrack *track, Int_t n)
839 TObjArray *hits = track->GetHits();
840 if (n > track->GetNumberOfPoints() || n == 0) {
841 n = track->GetNumberOfPoints();
845 LOG_ERROR <<
"StFtpcConfMapper::TrackletAngle(StFtpcTrack *track, Int_t n)" << endm;
846 LOG_ERROR <<
" - Call this function only if you are sure to have at least three points on this track already!" << endm;
859 return StFormulary::Angle(x1, x2, 3);
868 TObjArray *trackpoint = track->GetHits();
871 if (!mVertexConstraint) {
872 point->SetAllCoord(last_point);
875 trackpoint->AddLast(point);
878 StraightLineFit(track, a);
882 trackpoint->Remove(point);
960 void StFtpcConfMapper::StraightLineFit(
StFtpcTrack *track, Double_t *a, Int_t n)
971 TObjArray *trackpoints = track->GetHits();
975 if (n > trackpoints->GetEntriesFast()) {
976 n = trackpoints->GetEntriesFast();
981 n = trackpoints->GetEntriesFast();
990 Double_t asin_arg, asin_arg2;
991 Int_t start_counter = 0;
993 if (!mVertexConstraint) {
1000 {
for (Int_t i = start_counter; i < n; i++) {
1004 L12 += trackpoint->GetXprime();
1005 L22 += (trackpoint->GetXprime() * trackpoint->GetXprime());
1006 g1 += trackpoint->GetYprime();
1007 g2 += (trackpoint->GetXprime() * trackpoint->GetYprime());
1010 Double_t D = L11*L22 - L12*L12;
1012 a[0] = (g2*L11 - g1*L12)/D;
1013 a[1] = (g1*L22 - g2*L12)/D;
1016 track->SetCenterX(- a[0] / (2. * a[1]) + trackpoint->GetXt());
1017 track->SetCenterY(- 1. / (2. * a[1]) + trackpoint->GetYt());
1018 track->SetRadius(TMath::Sqrt(a[0]*a[0] + 1.) / (2. * TMath::Abs(a[1])));
1019 track->CalcAndSetAlpha0();
1025 Double_t angle = 0.;
1026 Double_t angle_diff = 0.;
1031 L12 = L22 = g1 = g2 = 0.;
1033 {
for (Int_t i = start_counter; i < n; i++ ) {
1041 asin_arg = StFormulary::CheckASinArg(asin_arg2 = (trackpoint->GetY() - track->GetCenterY()) / track->GetRadius());
1042 if (asin_arg != asin_arg2) mLengthFitNaN++;
1044 if (trackpoint->GetX() >= track->GetCenterX() && trackpoint->GetY() > track->GetCenterY()) {
1045 angle = TMath::ASin(asin_arg);
1048 else if (trackpoint->GetX() < track->GetCenterX() && trackpoint->GetY() >= track->GetCenterY()) {
1049 angle = TMath::ASin(-asin_arg) + TMath::Pi();
1052 else if (trackpoint->GetX() <= track->GetCenterX() && trackpoint->GetY() < track->GetCenterY()) {
1053 angle = TMath::ASin(-asin_arg) + TMath::Pi();
1056 else if (trackpoint->GetX() > track->GetCenterX() && trackpoint->GetY() <= track->GetCenterY()) {
1057 angle = TMath::ASin(asin_arg) + 2 * TMath::Pi();
1060 angle_diff = angle - track->GetAlpha0();
1062 if (TMath::Abs(angle_diff) > TMath::Pi()) {
1063 if (angle_diff > 0.) {
1064 angle_diff -= 2*TMath::Pi();
1068 angle_diff += 2*TMath::Pi();
1072 s = TMath::Sqrt(TMath::Power(track->GetRadius() * angle_diff, 2.)
1073 + TMath::Power(trackpoint->GetZv() , 2.));
1078 L12 += trackpoint->GetZv();
1079 L22 += (trackpoint->GetZv() * trackpoint->GetZv());
1081 g2 += (s * trackpoint->GetZv());
1084 D = L11*L22 - L12*L12;
1088 a[2] = (g2*L11 - g1*L12)/D;
1089 a[3] = (g1*L22 - g2*L12)/D;
1092 Double_t chi2circle = 0.;
1093 Double_t chi2length = 0.;
1095 {
for (Int_t i = start_counter; i < n; i++) {
1097 asin_arg = StFormulary::CheckASinArg((trackpoint->GetYv() - track->GetCenterY()) / track->GetRadius());
1104 double x = trackpoint->GetXprime();
1105 double y = trackpoint->GetYprime();
1106 double z = trackpoint->GetZv();
1107 double yf = a[0]*x + a[1];
1108 double sf = a[2]*z + a[3];
1109 chi2circle += TMath::Power((y - yf)/yf,2);
1110 chi2length += TMath::Power((s - sf)/sf,2);
1114 if (mVertexConstraint) {
1119 a[4] = chi2circle/(n-2.);
1120 a[5] = chi2length/(n-2.);
1129 void StFtpcConfMapper::HandleSplitTracks() {
1132 HandleSplitTracks(StFtpcTrackingParams::Instance()->MaxDist(),
1133 StFtpcTrackingParams::Instance()->MinPointRatio(),
1134 StFtpcTrackingParams::Instance()->MaxPointRatio());
1141 void StFtpcConfMapper::HandleSplitTracks(Double_t max_dist, Double_t ratio_min, Double_t ratio_max)
1156 Int_t first_split = -1;
1161 Int_t entries = mTrack->GetEntriesFast();
1163 for (Int_t i = 0; i < entries; i++) {
1171 for (Int_t j = i+1; j < entries; j++) {
1184 if (!(t1->GetRowsWithPoints() & t2->GetRowsWithPoints()) &&
1185 (t1->GetHemisphere() == t2->GetHemisphere())) {
1187 r1 = t1->GetRLast();
1188 r2 = t2->GetRLast();
1189 phi1 = t1->GetAlphaLast();
1190 phi2 = t2->GetAlphaLast();
1191 R1 = t1->GetRFirst();
1192 R2 = t2->GetRFirst();
1193 Phi1 = t1->GetAlphaFirst();
1194 Phi2 = t2->GetAlphaFirst();
1196 dist = (TMath::Sqrt(r2*r2+r1*r1-2*r1*r2*(TMath::Cos(phi1)*TMath::Cos(phi2)+TMath::Sin(phi1)*TMath::Sin(phi2))) +
1197 TMath::Sqrt(R2*R2+R1*R1-2*R1*R2*(TMath::Cos(Phi1)*TMath::Cos(Phi2)+TMath::Sin(Phi1)*TMath::Sin(Phi2)))) / 2.;
1198 ratio = (Double_t)(t1->GetNumberOfPoints() + t2->GetNumberOfPoints()) / (Double_t)(t1->GetNMax() + t2->GetNMax());
1200 if (dist <= max_dist && ratio <= ratio_max && ratio >= ratio_min) {
1202 if (first_split == -1) {
1206 MergeSplitTracks(t1, t2);
1213 if (first_split != -1) {
1215 AdjustTrackNumbers(first_split);
1226 Int_t new_track_number = mTrack->GetEntriesFast();
1227 Int_t num_t1_points = t1->GetNumberOfPoints();
1228 Int_t num_t2_points = t2->GetNumberOfPoints();
1229 TObjArray *t1_points = t1->GetHits();
1230 TObjArray *t2_points = t2->GetHits();
1233 mTrack->AddAt(track, new_track_number);
1235 TObjArray *trackpoint = track->GetHits();
1236 trackpoint->Expand(mMaxFtpcRow);
1238 MIntArray *trackhitnumber = track->GetHitNumbers();
1240 {
for (Int_t i = 0; i < mMaxFtpcRow; i++) {
1242 if (i < num_t1_points) {
1243 trackpoint->AddAt(t1_points->At(i), mMaxFtpcRow - 1 -(((
StFtpcPoint *)t1_points->At(i))->GetPadRow()-1)%mMaxFtpcRow);
1246 if (i < num_t2_points) {
1247 trackpoint->AddAt(t2_points->At(i), mMaxFtpcRow - 1 -(((
StFtpcPoint *)t2_points->At(i))->GetPadRow()-1)%mMaxFtpcRow);
1251 trackpoint->Compress();
1252 trackpoint->Expand(trackpoint->GetLast()+1);
1254 {
for (Int_t i = 0; i < trackpoint->GetEntriesFast(); i++) {
1255 trackhitnumber->AddLast(((
StFtpcPoint *)trackpoint->At(i))->GetHitNumber());
1258 track->SetProperties(kTRUE, new_track_number);
1259 track->ComesFromMainVertex(mVertexConstraint);
1260 track->CalculateNMax();
1262 if (mVertexConstraint) mMainVertexTracks++;
1263 if (t1->ComesFromMainVertex()) mMainVertexTracks--;
1264 if (t2->ComesFromMainVertex()) mMainVertexTracks--;
1278 void StFtpcConfMapper::ClusterLoop()
1293 for (mFtpc = 1; mFtpc <= 2; mFtpc++) {
1297 for (row_segm = mFtpc * mMaxFtpcRow - 1; row_segm >= (mFtpc-1) * mMaxFtpcRow + mMinPoints[mVertexConstraint] - 1; row_segm--) {
1300 for (Int_t phi_segm_counter = 0; phi_segm_counter < mNumPhiSegment; phi_segm_counter++) {
1303 if(phi_segm_counter%2) {
1304 phi_segm = mNumPhiSegment - phi_segm_counter - mNumPhiSegment%2;
1308 phi_segm = phi_segm_counter;
1312 for(eta_segm = 0; eta_segm < mNumEtaSegment; eta_segm++) {
1315 if ((entries = (segment = (TObjArray *)mVolume->At(GetSegm(row_segm, phi_segm, eta_segm)))->GetEntriesFast())) {
1317 for (hit_num = 0; hit_num < entries; hit_num++) {
1320 if (hit->IsUnusable()) {
1345 Double_t *coeff = 0,coeffT[6];
1352 Int_t tracks = GetNumberOfTracks();
1353 if (tracks >= mTrack->GetSize()) mTrack->Expand(mTrack->GetSize()+1000);
1355 mTrack->AddAt(track, tracks);
1356 TObjArray *trackpoint = track->GetHits();
1358 track->AddPoint(hit);
1361 if (!mVertexConstraint) {
1362 hit->SetAllCoord(hit);
1366 for (point = 1; point < mTrackletLength[mVertexConstraint]; point++) {
1368 if ((closest_hit = GetNextNeighbor(hit, coeff, (Bool_t)kTRUE))) {
1370 track->AddPoint(closest_hit);
1374 if (GetLaser() && track->GetNumberOfPoints() == mTrackletLength[mVertexConstraint]) {
1376 CompleteTrack(track);
1391 if (track->GetNumberOfPoints() < mMinPoints[mVertexConstraint]) {
1398 CompleteTrack(track);
1407 if (trackpoint->GetEntriesFast() == mTrackletLength[mVertexConstraint]) {
1409 if (TrackletAngle(track) > mMaxAngleTracklet[mVertexConstraint]) {
1417 for (point = mTrackletLength[mVertexConstraint]; point < mMaxFtpcRow; point++) {
1419 if (!coeff) coeff = coeffT;
1423 StraightLineFit(track, coeff);
1424 closest_hit = GetNextNeighbor((
StFtpcConfMapPoint *)trackpoint->Last(), coeff, (Bool_t)kTRUE);
1428 track->AddPoint(closest_hit);
1433 point = mMaxFtpcRow;
1438 if (track->GetNumberOfPoints() < mMinPoints[mVertexConstraint]) {
1445 CompleteTrack(track);
1461 Double_t dist, closest_dist = 1.e7;
1462 Double_t closest_circle_dist = 1.e7;
1463 Double_t closest_length_dist = 1.e7;
1470 TObjArray *sub_segment;
1482 start_row = GetRowSegm(start_hit) - 1;
1485 end_row = GetRowSegm(start_hit) - mRowScopeTrack[mVertexConstraint];
1489 end_row = GetRowSegm(start_hit) - mRowScopeTracklet[mVertexConstraint];
1492 while (end_row < (mFtpc-1) * mMaxFtpcRow) {
1496 if (start_row < end_row)
return 0;
1500 start_row = GetRowSegm(start_hit) + 1;
1503 end_row = GetRowSegm(start_hit) + mRowScopeTrack[mVertexConstraint];
1507 end_row = GetRowSegm(start_hit) + mRowScopeTracklet[mVertexConstraint];
1510 while (end_row > mFtpc * mMaxFtpcRow - 1) {
1514 if (start_row > end_row)
return 0;
1518 for (sub_row_segm = start_row; TestExpression(sub_row_segm, end_row, backward); LoopUpdate(&sub_row_segm, backward)) {
1521 for (Int_t i = -(mPhiScope[mVertexConstraint]); i <= mPhiScope[mVertexConstraint]; i++) {
1522 sub_phi_segm = GetPhiSegm(start_hit) + i;
1524 if (sub_phi_segm < 0) {
1525 sub_phi_segm += mNumPhiSegment;
1528 else if (sub_phi_segm >= mNumPhiSegment) {
1529 sub_phi_segm -= mNumPhiSegment;
1533 for (Int_t j = -(mEtaScope[mVertexConstraint]); j <= mEtaScope[mVertexConstraint]; j++) {
1534 sub_eta_segm = GetEtaSegm(start_hit) + j;
1536 if (sub_eta_segm < 0 || sub_eta_segm >= mNumEtaSegment) {
1541 if ((sub_entries = ((sub_segment = (TObjArray *)mVolume->At(GetSegm(sub_row_segm, sub_phi_segm, sub_eta_segm)))->GetEntriesFast()))) {
1543 for (sub_hit_num = 0; sub_hit_num < sub_entries; sub_hit_num++) {
1550 if (!mVertexConstraint) {
1551 hit->SetAllCoord(start_hit);
1557 hit->SetDist(CalcDistance(hit, coeff+0), CalcDistance(hit, coeff+2));
1559 if (hit->GetCircleDist() < closest_circle_dist) {
1560 closest_circle_dist = hit->GetCircleDist();
1561 closest_circle_hit = hit;
1564 if (hit->GetLengthDist() < closest_length_dist) {
1565 closest_length_dist = hit->GetLengthDist();
1566 closest_length_hit = hit;
1574 if ((dist = CalcDistance(start_hit, hit, GetLaser())) < closest_dist) {
1576 if (GetLaser() && ((
StFtpcTrack*)start_hit->GetTrack(mTrack))->GetNumberOfPoints() > 1) {
1578 if (TrackAngle(start_hit, hit, backward) <= mMaxAngleTracklet[mVertexConstraint]) {
1580 closest_dist = dist;
1590 closest_dist = dist;
1610 if ((coeff && (closest_circle_hit || closest_length_hit)) || ((!coeff) && closest_hit)) {
1612 if ((start_row - sub_row_segm) >= 1) {
1635 if (closest_circle_hit && closest_length_hit) {
1637 if (closest_circle_hit == closest_length_hit) {
1639 if (VerifyCuts(start_hit, closest_circle_hit, backward)) {
1642 return closest_circle_hit;
1653 Bool_t cut_circle = VerifyCuts(start_hit, closest_circle_hit, backward);
1654 Bool_t cut_length = VerifyCuts(start_hit, closest_length_hit, backward);
1656 if (cut_circle && cut_length) {
1658 if (GetDistanceFromFit(closest_circle_hit) < GetDistanceFromFit(closest_length_hit)) {
1659 return closest_circle_hit;
1663 return closest_length_hit;
1667 else if (!(cut_circle || cut_length)) {
1671 else if (cut_circle) {
1672 return closest_circle_hit;
1676 return closest_length_hit;
1700 void StFtpcConfMapper::ExtendTracks()
1704 for (Int_t t = 0; t < mTrack->GetEntriesFast(); t++) {
1708 if (track->GetHemisphere() == 1) {
1716 if (TrackExtension(track)) {
1725 Bool_t StFtpcConfMapper::TrackExtension(
StFtpcTrack *track)
1730 Int_t number_of_points = track->GetNumberOfPoints();
1731 Double_t *coeff = 0,coeffT[6];
1735 TObjArray *trackpoint = track->GetHits();
1737 for (Int_t direction = 0; direction < 2; direction ++) {
1739 for (point = number_of_points; point < mMaxFtpcRow; point++) {
1741 if (direction == 1) {
1749 Int_t padrow = hit->GetPadRow()%StFtpcTrackingParams::Instance()->NumberOfPadRowsPerSide();
1751 if ((padrow != 1 && direction == 1) ||
1752 (padrow != 0 && direction == 0)) {
1756 if ((closest_hit = GetNextNeighbor(hit, coeff, (Bool_t)direction))) {
1759 if(direction == 1) {
1760 track->AddPoint(closest_hit);
1764 track->AddForwardPoint(closest_hit);
1771 if (!coeff) coeff = coeffT;
1772 StraightLineFit(track, coeff);
1774 if ((closest_hit = GetNextNeighbor(hit, coeff, (Bool_t)direction))) {
1777 if(direction == 1) {
1778 track->AddPoint(closest_hit);
1782 track->AddForwardPoint(closest_hit);
1787 point = mMaxFtpcRow;
1797 if (track->GetNumberOfPoints() - number_of_points) {
1799 track->SetPointDependencies();
1800 track->ComesFromMainVertex(mVertexConstraint);
1801 track->CalculateNMax();
1803 mClustersUnused -= (track->GetNumberOfPoints() - number_of_points);
1805 return (Bool_t)kTRUE;
1809 return (Bool_t)kFALSE;
1814 void StFtpcConfMapper::CalcEtaMinMax()
1823 Double_t vertex_rad_squared = TMath::Power(mVertex->GetRadius2(), 2);
1824 Double_t ftpc_inner_rad_squared = TMath::Power(StFtpcTrackingParams::Instance()->InnerRadius(), 2);
1825 Double_t ftpc_outer_rad_squared = TMath::Power(StFtpcTrackingParams::Instance()->OuterRadius(), 2);
1827 mEtaMin = -TMath::Log(TMath::Tan( TMath::ASin(TMath::Sqrt(ftpc_outer_rad_squared + vertex_rad_squared)/ (StFtpcTrackingParams::Instance()->PadRowPosZ(0) - TMath::Abs(mVertex->GetZ()) ) ) /2.) ) - 0.01;
1828 mEtaMax = -TMath::Log(TMath::Tan( TMath::ASin(TMath::Sqrt(ftpc_inner_rad_squared - vertex_rad_squared)/ (StFtpcTrackingParams::Instance()->PadRowPosZ(9) + TMath::Abs(mVertex->GetZ()) ) ) /2.) ) + 0.01;
1834 void StFtpcConfMapper::TrackingInfo()
1839 LOG_INFO <<
"Tracking information" << endm;
1840 LOG_INFO <<
"--------------------" << endm;
1842 LOG_INFO << Form(
"%5d (%5d/%5d) tracks (main vertex/non vertex) found.",
1843 GetNumberOfTracks(), GetNumMainVertexTracks(), GetNumberOfTracks() - GetNumMainVertexTracks()) << endm;
1845 LOG_INFO << Form(
"%5d (%5d/%5d) clusters (used/unused, of which %d were flagged 'bad').",
1846 GetNumberOfClusters(), GetNumberOfClusters() - GetNumClustersUnused(),
1847 GetNumClustersUnused(), GetNumBadClusters()) << endm;
1849 LOG_INFO << Form(
" %5d/%5d tracks/tracklets merged.",
1850 GetNumMergedTracks(), GetNumMergedTracklets()) << endm;
1852 LOG_INFO << Form(
"%18d times different hits for circle and length fit found.",
1853 GetNumDiffHits()) << endm;
1855 LOG_INFO << Form(
"%18d times argument of arcsin set to +/-1.",
1856 GetNumLengthFitNaN()) << endm;
1858 LOG_INFO << Form(
"%18d tracks extended.", GetNumExtendedTracks()) << endm;
1860 LOG_INFO << Form(
"%18d split tracks merged.", GetNumMergedSplits()) << endm;
1866 void StFtpcConfMapper::CutInfo()
1871 LOG_INFO <<
"Cuts for main vertex constraint on / off" << endm;
1872 LOG_INFO <<
"----------------------------------------" << endm;
1873 LOG_INFO << Form(
"Max. angle between last three points of tracklets: %6f / %6f",mMaxAngleTracklet[1],mMaxAngleTracklet[0]) << endm;
1874 LOG_INFO << Form(
"Max. angle between last three points of tracks: %6f / %6f",mMaxAngleTrack[1],mMaxAngleTrack[0]) << endm;
1875 LOG_INFO << Form(
"Max. distance between circle fit and trackpoint: %6f / %6f",mMaxCircleDist[1],mMaxCircleDist[0]) << endm;
1876 LOG_INFO << Form(
"Max. distance between length fit and trackpoint: %6f / %6f",mMaxLengthDist[1],mMaxLengthDist[0])<< endm;
1882 void StFtpcConfMapper::SettingInfo()
1887 LOG_INFO <<
"Settings for main vertex constraint on / off" << endm;
1888 LOG_INFO <<
"--------------------------------------------" << endm;
1889 LOG_INFO <<
"Points required to create a tracklet: " << mTrackletLength[1] <<
" / " << mTrackletLength[0] << endm;
1890 LOG_INFO <<
"Points required for a track: " << mMinPoints[1] <<
" / " << mMinPoints[0] << endm;
1891 LOG_INFO <<
"Subsequent padrows to look for next tracklet point: " << mRowScopeTracklet[1] <<
" / " << mRowScopeTracklet[0] << endm;
1892 LOG_INFO <<
"Subsequent padrows to look for next track point: " << mRowScopeTrack[1] <<
" / " << mRowScopeTrack[0] << endm;
1893 LOG_INFO <<
"Adjacent phi segments to look for next point: " << mPhiScope[1] <<
" / " << mPhiScope[0] << endm;
1894 LOG_INFO <<
"Adjacent eta segments to look for next point: " << mEtaScope[1] <<
" / " << mEtaScope[0] << endm;
1900 void StFtpcConfMapper::TwoCycleTracking()
1906 MainVertexTracking();
1912 void StFtpcConfMapper::NonVertexTracking()
1920 void StFtpcConfMapper::RemoveTrack(
StFtpcTrack *track)
1924 track->SetProperties(kFALSE, -1);
1925 mTrack->Remove(track);
1936 return hit->GetPadRow() - 1;
1940 Int_t StFtpcConfMapper::GetRow(Int_t segm)
1952 return (Int_t)(hit->GetPhi() * mNumPhiSegment / (2.*TMath::Pi()));
1956 Double_t StFtpcConfMapper::GetPhi(Int_t segm)
1960 return 2 * TMath::Pi() * segm / (Double_t)mNumPhiSegment;
1972 if ((eta = hit->GetEta()) > 0.) {
1973 eta_segm = (Int_t)((eta - mEtaMin) * mNumEtaSegment/(mEtaMax - mEtaMin) /2.);
1977 eta_segm = (Int_t)((-eta - mEtaMin) * mNumEtaSegment/(mEtaMax - mEtaMin) /2. + mNumEtaSegment/2.);
1984 Double_t StFtpcConfMapper::GetEta(Int_t segm)
1988 Bool_t minus_sign = (Bool_t)kFALSE;
1990 if (segm >= mNumEtaSegment/2.) {
1991 minus_sign = (Bool_t)kTRUE;
1992 segm -= mNumEtaSegment/2;
1996 return -segm * (mEtaMax - mEtaMin)/ (2. * mNumEtaSegment) + mEtaMin;
2000 return +segm * (mEtaMax - mEtaMin)/ (2. * mNumEtaSegment) + mEtaMin;
2009 return GetSegm(GetRowSegm(hit), GetPhiSegm(hit), GetEtaSegm(hit));
2013 Int_t StFtpcConfMapper::GetSegm(Int_t row_segm, Int_t phi_segm, Int_t eta_segm)
2017 Int_t segm = row_segm * (mNumPhiSegment * mNumEtaSegment) + phi_segm * (mNumEtaSegment) + eta_segm;
2019 if (segm < 0 || segm >= mBounds) {
2020 LOG_WARN <<
"Segment calculation out of bounds (row = " << GetRow(row_segm) <<
", phi = " << GetPhi(phi_segm) <<
", eta = " << GetEta(eta_segm) <<
")! Garbage segment returned." << endm;
2028 Int_t StFtpcConfMapper::GetRowSegm(Int_t segm)
2031 return (segm - GetEtaSegm(segm) - GetPhiSegm(segm)) / (mNumPhiSegment * mNumEtaSegment);
2035 Int_t StFtpcConfMapper::GetPhiSegm(Int_t segm)
2038 return (segm - GetEtaSegm(segm)) % (mNumPhiSegment * mNumEtaSegment) / (mNumEtaSegment);
2042 Int_t StFtpcConfMapper::GetEtaSegm(Int_t segm)
2046 return (segm % (mNumPhiSegment * mNumEtaSegment)) % (mNumEtaSegment);
2055 Double_t angle = TMath::Abs(hit1->GetPhi() - hit2->GetPhi());
2057 if (angle > TMath::Pi()) {
2058 angle = 2*TMath::Pi() - angle;
2061 return angle / (TMath::Abs(hit1->GetPadRow() - hit2->GetPadRow()));
2070 return (TMath::Abs(hit1->GetEta() - hit2->GetEta())) / (TMath::Abs(hit1->GetPadRow() - hit2->GetPadRow()));
2079 return TMath::Sqrt(TMath::Power(GetPhiDiff(hit1, hit2)/mMaxCircleDist[mVertexConstraint], 2) + TMath::Power(GetEtaDiff(hit1, hit2)/mMaxLengthDist[mVertexConstraint], 2));
2089 return TMath::Sqrt(TMath::Power((hit->GetCircleDist() / mMaxCircleDist[mVertexConstraint]), 2) + TMath::Power((hit->GetLengthDist() / mMaxLengthDist[mVertexConstraint]), 2));
2093 void StFtpcConfMapper::AdjustTrackNumbers(Int_t first_split)
2099 mTrack->Expand(mTrack->GetLast()+1);
2101 for (Int_t i = first_split; i < mTrack->GetEntriesFast(); ((
StFtpcTrack*)mTrack->At(i))->SetTrackNumber(i), i++);