1 ////////////////////////////////////////////////////////////////////////////////
3 // Author: Artur Szostak
4 // Email: artur@alice.phy.uct.ac.za | artursz@iafrica.com
6 ////////////////////////////////////////////////////////////////////////////////
8 #include "Tracking/MansoTracker.hpp"
10 #include "Tracking/Calculations.hpp"
13 #include "RegionOfInterest.hpp"
16 #if defined(DEBUG) || (defined(USE_ALILOG) && ! defined(LOG_NO_DEBUG))
18 #include "Debug/print.hpp"
22 std::ostream& operator << (std::ostream& os, AliHLTMUONCoreMansoTracker::StatesSM4 state)
26 case AliHLTMUONCoreMansoTracker::kSM4Idle: os << "kSM4Idle"; break;
27 case AliHLTMUONCoreMansoTracker::kWaitChamber8: os << "kWaitChamber8"; break;
28 case AliHLTMUONCoreMansoTracker::kWaitMoreChamber8: os << "kWaitMoreChamber8"; break;
29 case AliHLTMUONCoreMansoTracker::kWaitChamber7: os << "kWaitChamber7"; break;
30 case AliHLTMUONCoreMansoTracker::kWaitMoreChamber7: os << "kWaitMoreChamber7"; break;
31 default: os << "FAULT!!";
36 std::ostream& operator << (std::ostream& os, AliHLTMUONCoreMansoTracker::StatesSM5 state)
40 case AliHLTMUONCoreMansoTracker::kSM5Idle: os << "kSM5Idle"; break;
41 case AliHLTMUONCoreMansoTracker::kWaitChamber10: os << "kWaitChamber10"; break;
42 case AliHLTMUONCoreMansoTracker::kWaitMoreChamber10: os << "kWaitMoreChamber10"; break;
43 case AliHLTMUONCoreMansoTracker::kWaitChamber9: os << "kWaitChamber9"; break;
44 case AliHLTMUONCoreMansoTracker::kWaitMoreChamber9: os << "kWaitMoreChamber9"; break;
45 case AliHLTMUONCoreMansoTracker::kSM5Done: os << "kSM5Done"; break;
46 default: os << "FAULT!!";
55 // Deviate from the Manso implementation by allowing a and b
56 // parameters per chamber and not just per station.
57 // The default values are derived from the work done in
58 // "A first algorithm for dimuon High Level Trigger"
59 // Ref ID: ALICE-INT-2002-04 version 1.0
60 Float AliHLTMUONCoreMansoTracker::fgA7 = 0.016f;
61 Float AliHLTMUONCoreMansoTracker::fgB7 = 2.0f;
62 Float AliHLTMUONCoreMansoTracker::fgA8 = 0.016f;
63 Float AliHLTMUONCoreMansoTracker::fgB8 = 2.0f;
64 Float AliHLTMUONCoreMansoTracker::fgA9 = 0.020f;
65 Float AliHLTMUONCoreMansoTracker::fgB9 = 3.0f;
66 Float AliHLTMUONCoreMansoTracker::fgA10 = 0.020f;
67 Float AliHLTMUONCoreMansoTracker::fgB10 = 3.0f;
68 Float AliHLTMUONCoreMansoTracker::fgZ7 = 1274.5f;
69 Float AliHLTMUONCoreMansoTracker::fgZ8 = 1305.5f;
70 Float AliHLTMUONCoreMansoTracker::fgZ9 = 1408.6f;
71 Float AliHLTMUONCoreMansoTracker::fgZ10 = 1439.6f;
72 Float AliHLTMUONCoreMansoTracker::fgZ11 = 1603.5f;
73 Float AliHLTMUONCoreMansoTracker::fgZ13 = 1703.5f;
76 void AliHLTMUONCoreMansoTracker::AliRegionOfInterest::Create(AliHLTMUONCorePoint p, Float a, Float b)
78 // Creates a region of interest specific to the Manso algorithm from a point and
79 // two Manso specific parameters.
82 // Compute the radius Rp
83 Float rp = (Float) sqrt( p.fX * p.fX + p.fY * p.fY );
85 // The radius Rs for the region of interest is computed from the
86 // specification given in the document:
87 // "A first algorithm for dimuon High Level Trigger"
88 // Ref ID: ALICE-INT-2002-04 version 1.0
91 // given on page 3 section 4.
96 bool AliHLTMUONCoreMansoTracker::AliRegionOfInterest::Contains(AliHLTMUONCorePoint p) const
98 // Compute the distance between the centre of the region of interest and
99 // the point p. This distance must be less than the radius of the region
100 // of interest for p to be contained in the region of interest.
101 register Float lx = fCentre.fX - p.fX;
102 register Float ly = fCentre.fY - p.fY;
103 register Float r = (Float) sqrt( lx * lx + ly * ly );
104 DebugMsg(4, "\tAliRegionOfInterest::Contains : p = " << p
105 << " , centre = " << fCentre << " , r = " << r << " , Rs = " << fRs
111 void AliHLTMUONCoreMansoTracker::AliRegionOfInterest::GetBoundaryBox(
112 Float& left, Float& right, Float& bottom, Float& top
115 // Works out the smallest boundary box that will contain the region of interest.
117 left = fCentre.fX - fRs;
118 right = fCentre.fX + fRs;
119 bottom = fCentre.fY - fRs;
120 top = fCentre.fY + fRs;
124 AliHLTMUONCoreMansoTracker::AliVertex::AliVertex(Float x, Float y, Float z)
126 // Constructor for vertex.
134 AliHLTMUONCoreMansoTracker::AliVertex::AliVertex(AliHLTMUONCorePoint xy, Float z)
136 // Construct vertex from a point on the XY plane and z coordinate.
144 AliHLTMUONCoreMansoTracker::AliLine::AliLine(
145 Float ax, Float ay, Float az,
146 Float bx, Float by, Float bz
149 // Construct a line defined by L = M*t + C = (A-B)*t + B
150 // where M and C are 3D vectors and t is a free parameter.
151 // A = (ax, ay, az) and B = (bx, by, bz)
162 AliHLTMUONCoreMansoTracker::AliLine::AliLine(AliVertex a, AliVertex b)
164 // Contruct a line to go through two vertices a and b.
175 AliHLTMUONCorePoint AliHLTMUONCoreMansoTracker::AliLine::FindIntersectWithXYPlain(Float z) const
177 // Find the point of intersection of the line and the XY plane at z.
179 Assert( fMz != 0.0 ); // Should not have a ray perpendicular to the beam axis.
180 Float t = (z - fCz) / fMz;
181 Float lx = fMx*t + fCx;
182 Float ly = fMy*t + fCy;
184 return AliHLTMUONCorePoint(lx, ly);
188 AliHLTMUONCoreMansoTracker::AliHLTMUONCoreMansoTracker() : AliHLTMUONCoreTracker()
190 // Default constructor
192 fSm4state = kSM4Idle;
193 fSm5state = kSM5Idle;
194 fRequestsCompleted = 0;
198 void AliHLTMUONCoreMansoTracker::FindTrack(const AliHLTMUONCoreTriggerRecord& trigger)
200 // Tries to find the track from the trigger seed.
202 DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
203 DebugMsg(1, "Processing trigger with pt = " << trigger.fPt);
204 fV1 = AliVertex( trigger.fStation1impact, fgZ11 );
205 AliVertex v2 = AliVertex( trigger.fStation2impact, fgZ13 );
207 // Form the vector line between the above two impact points and
208 // find the crossing point of the line with chamber 10 (i.e. station 5).
209 fMc1.fLine = AliLine(fV1, v2);
210 AliHLTMUONCorePoint p10 = fMc1.fLine.FindIntersectWithXYPlain( fgZ10 );
212 // Build a region of interest for tracking station 5 (chamber 10).
213 // Remember the parameters a and b are station specific.
214 fMc1.fChamber = kChamber10;
215 fMc1.fRoi.Create(p10, fgA10, fgB10);
217 // Make SM5 state transition before the call to RequestClusters since
218 // that method could call one of our methods again, so we need to be
219 // in a consistant internal state.
220 fSm5state = kWaitChamber10;
222 Float left, right, bottom, top;
223 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
224 RequestClusters(left, right, bottom, top, kChamber10, &fMc1);
228 void AliHLTMUONCoreMansoTracker::ReturnClusters(void* tag, const AliHLTMUONCoreClusterPoint* clusters, UInt count)
230 // Implementation of AliHLTMUONCoreTracker::ReturnClusters.
233 Assert( clusters != NULL );
235 AliTagData* data = (AliTagData*)tag;
236 DebugMsg(4, "Got AliHLTMUONCoreMansoTracker::ReturnClusters(tag = " << tag
237 << ", chamber = " << data->fChamber
238 << ", clusters = " << clusters << ", count = " << count << ")"
240 DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
242 switch (data->fChamber)
244 case kChamber7: ReceiveClustersChamber7(clusters, count, data); break;
245 case kChamber8: ReceiveClustersChamber8(clusters, count, data); break;
246 case kChamber9: ReceiveClustersChamber9(clusters, count); break;
247 case kChamber10: ReceiveClustersChamber10(clusters, count); break;
250 DebugMsg(1, "ERROR: Got tag with an invalid value: " << data->fChamber);
255 void AliHLTMUONCoreMansoTracker::EndOfClusters(void* tag)
257 // Implementation of AliHLTMUONCoreTracker::EndOfClusters.
259 AliTagData* data = (AliTagData*)tag;
260 DebugMsg(4, "Got AliHLTMUONCoreMansoTracker::EndOfClusters(chamber = " << data->fChamber << ")");
261 DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
263 switch (data->fChamber)
265 case kChamber7: EndOfClustersChamber7(); break;
266 case kChamber8: EndOfClustersChamber8(); break;
267 case kChamber9: EndOfClustersChamber9(); break;
268 case kChamber10: EndOfClustersChamber10(); break;
271 DebugMsg(1, "ERROR: Got tag with an invalid value: " << data->fChamber);
276 void AliHLTMUONCoreMansoTracker::FillTrackData(AliHLTMUONCoreTrack& track)
278 // Implementation of AliHLTMUONCoreTracker::FillTrackData
280 DebugMsg(4, "FillTrack: st5 = " << fSt5rec->fClusterPoint << ", st4 = " << fFoundPoint->fClusterPoint);
282 Float x1 = fFoundPoint->fClusterPoint.fX;
283 Float y1 = fFoundPoint->fClusterPoint.fY;
284 Float y2 = fSt5rec->fClusterPoint.fY;
286 Float pt = AliHLTMUONCoreCalculateSignedPt(x1, y1, y2, fSt4z, fSt5z, momentum);
287 DebugMsg(1, "Calculated Pt = " << pt);
288 DebugMsg(1, "\tusing x1 = " << x1 << " , y1 = " << y1 << " , y2 = " << y2
289 << " , z1 = " << fSt4z << " , z2 = " << fSt5z
293 track.fSign = kSignMinus;
295 track.fSign = kSignPlus;
297 track.fSign = kUnknownSign;
300 track.fPt = (Float) fabs(pt);
301 for (UInt i = 0; i < 6; i++)
303 track.fPoint[i] = AliHLTMUONCorePoint(0.0, 0.0);
304 track.fRegion[i] = kInvalidROI;
307 Float left, right, bottom, top;
309 // Have to create the ROI numbers from the internal region of interest structures.
310 fSt5rec->fTag.fRoi.GetBoundaryBox(left, right, bottom, top);
311 AliHLTMUONCoreRegionOfInterest region4(left, right, bottom, top, fSt4chamber);
312 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
313 AliHLTMUONCoreRegionOfInterest region5(left, right, bottom, top, fMc1.fChamber);
315 // Depending on the chamber we received cluster points from, fill the appropriate
316 // point and ROI number. This is done for station 4 then 5.
317 if (fSt4chamber == kChamber8)
319 track.fPoint[6] = AliHLTMUONCorePoint(0.0, 0.0);
320 track.fRegion[6] = kInvalidROI;
321 track.fPoint[7] = fFoundPoint->fClusterPoint;
322 track.fRegion[7] = region4;
326 track.fPoint[6] = fFoundPoint->fClusterPoint;
327 track.fRegion[6] = region4;
328 track.fPoint[7] = AliHLTMUONCorePoint(0.0, 0.0);
329 track.fRegion[7] = kInvalidROI;
331 if (fMc1.fChamber == kChamber10)
333 track.fPoint[8] = AliHLTMUONCorePoint(0.0, 0.0);
334 track.fRegion[8] = kInvalidROI;
335 track.fPoint[9] = fSt5rec->fClusterPoint;
336 track.fRegion[9] = region5;
340 track.fPoint[8] = fSt5rec->fClusterPoint;
341 track.fRegion[8] = region5;
342 track.fPoint[9] = AliHLTMUONCorePoint(0.0, 0.0);
343 track.fRegion[9] = kInvalidROI;
348 void AliHLTMUONCoreMansoTracker::Reset()
350 // Implementation of AliHLTMUONCoreTracker::Reset
352 DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
355 fSm4state = kSM4Idle;
356 fSm5state = kSM5Idle;
357 fRequestsCompleted = 0;
361 // Note: In the following ReceiveClustersXXX and EndOfClustersXXX methods we make
362 // the state machine transitions before calls to RequestClusters, FoundTrack,
363 // NoTrackFound or EndOfClusterRequests. This is important since the callback
364 // object will make recursive calls to the tracker's methods so we need to maintain
365 // a consistant internal state.
366 // The same would go for updating internal variables.
367 // In general one should only call the callback methods at the end of any of the
368 // following routines.
370 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber7(
371 const AliHLTMUONCoreClusterPoint* clusters, UInt count, const AliTagData* data
374 // State change method for Station 4 state machine.
379 fSm4state = kWaitMoreChamber7;
381 case kWaitMoreChamber7:
382 for (UInt j = 0; j < count; j++)
384 AliHLTMUONCoreClusterPoint cluster = clusters[j];
385 // Check that the cluster actually is in our region of interest on station 4.
386 if ( data->fRoi.Contains(cluster) )
388 DebugMsg(4, "Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 7.");
389 AliStation4Data* newdata = fSt4points.New();
390 newdata->fClusterPoint = cluster;
391 newdata->fSt5tag = data;
397 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber7!");
402 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber8(
403 const AliHLTMUONCoreClusterPoint* clusters, UInt count, const AliTagData* data
406 // State change method for Station 4 state machine.
411 fSm4state = kWaitMoreChamber8;
413 fSt4chamber = kChamber8;
415 case kWaitMoreChamber8:
416 for (UInt j = 0; j < count; j++)
418 AliHLTMUONCoreClusterPoint cluster = clusters[j];
419 // Check that the cluster actually is in our region of interest on station 4.
420 if ( data->fRoi.Contains(cluster) )
422 DebugMsg(4, "Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 8.");
423 AliStation4Data* newdata = fSt4points.New();
424 newdata->fClusterPoint = cluster;
425 newdata->fSt5tag = data;
431 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber8!");
436 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber9(const AliHLTMUONCoreClusterPoint* clusters, UInt count)
438 // State change method for Station 5 state machine.
443 fSm5state = kWaitMoreChamber9;
444 fSm4state = kWaitChamber8; // Start SM4.
446 case kWaitMoreChamber9:
447 for (UInt j = 0; j < count; j++)
449 AliHLTMUONCoreClusterPoint cluster = clusters[j];
450 // Check that the cluster actually is in our region of interest on station 5.
451 if ( fMc1.fRoi.Contains(cluster) )
453 DebugMsg(4, "Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 9.");
454 AliStation5Data* data = fSt5data.New();
455 data->fClusterPoint = cluster;
456 ProjectToStation4(data, fgZ9); // This adds a new request for station 4.
462 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber9!");
467 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber10(const AliHLTMUONCoreClusterPoint* clusters, UInt count)
469 // State change method for Station 5 state machine.
474 fSm5state = kWaitMoreChamber10;
476 fSm4state = kWaitChamber8; // Start SM4.
478 case kWaitMoreChamber10:
479 for (UInt j = 0; j < count; j++)
481 AliHLTMUONCoreClusterPoint cluster = clusters[j];
482 // Check that the cluster actually is in our region of interest on station 5.
483 if ( fMc1.fRoi.Contains(cluster) )
485 DebugMsg(4, "Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 10.");
486 AliStation5Data* data = fSt5data.New();
487 data->fClusterPoint = cluster;
488 ProjectToStation4(data, fgZ10); // This adds a new request for station 4.
494 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber10!");
499 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber7()
501 // State change method for Station 4 state machine.
503 fRequestsCompleted++; // Increment the number of requests completed for station 4.
504 DebugMsg(4, "fRequestsCompleted = " << fRequestsCompleted );
509 // If all data from station 5 is received and no data found on
510 // chambers 7 or 8 then we can not find a track.
511 if (fSm5state == kSM5Done) NoTrackFound();
514 case kWaitMoreChamber7:
515 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
520 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber7!");
525 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber8()
527 // State change method for Station 4 state machine.
529 fRequestsCompleted++; // Increment the number of requests completed for station 4.
530 DebugMsg(4, "fRequestsCompleted = " << fRequestsCompleted );
535 // Ignore. The requests for chamber 8 are already re-requested below.
540 fSm4state = kWaitChamber7;
542 fSt4chamber = kChamber7;
544 // We need to resend the requests for chamber 8, but change the request
545 // to get data for chamber 7 instead:
546 UInt reqlistsize = fSt5data.Count();
547 DebugMsg(4, "Re-requesting clusters from chamber 7... reqlistsize = " << reqlistsize);
549 Station5List::Iterator rec = fSt5data.First();
550 for (UInt i = 0; i < reqlistsize; i++, rec++)
552 // Need to create a new st5 data block for the request.
553 AliStation5Data* data = fSt5data.New();
554 data->fClusterPoint = rec->fClusterPoint;
555 data->fTag.fLine = rec->fTag.fLine;
557 // Rebuild a region of interest for chamber 7.
558 // Remember the parameters a and b are station specific.
559 AliHLTMUONCorePoint p7 = data->fTag.fLine.FindIntersectWithXYPlain( fgZ7 );
560 data->fTag.fChamber = kChamber7;
561 data->fTag.fRoi.Create(p7, fgA7, fgB7);
563 Float left, right, bottom, top;
564 data->fTag.fRoi.GetBoundaryBox(left, right, bottom, top);
565 // Make request for chamber 7 data.
566 RequestClusters(left, right, bottom, top, kChamber7, &data->fTag);
571 case kWaitMoreChamber8:
572 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
577 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber8!");
582 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber9()
584 // State change method for Station 5 state machine.
589 fSm5state = kSM5Done;
590 EndOfClusterRequests();
594 case kWaitMoreChamber9:
595 fSm5state = kSM5Done;
596 EndOfClusterRequests();
597 if (fRequestsCompleted == fSt5data.Count())
602 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber9!");
607 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber10()
609 // State change method for Station 5 state machine.
615 fSm5state = kWaitChamber9;
618 // No clusters found on chamber 10 so we need to make a request for
619 // clusters from chamber 9:
620 AliHLTMUONCorePoint p9 = fMc1.fLine.FindIntersectWithXYPlain( fgZ9 );
622 // Build a region of interest for tracking station 5 (chamber 9).
623 // Remember the parameters a and b are station specific.
624 fMc1.fChamber = kChamber9;
625 fMc1.fRoi.Create(p9, fgA9, fgB9);
627 Float left, right, bottom, top;
628 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
629 RequestClusters(left, right, bottom, top, kChamber9, &fMc1);
633 case kWaitMoreChamber10:
634 fSm5state = kSM5Done;
635 EndOfClusterRequests();
636 if (fRequestsCompleted == fSt5data.Count())
641 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber10!");
646 void AliHLTMUONCoreMansoTracker::ProjectToStation4(AliStation5Data* data, register Float station5z)
648 // Perform chamber specific operations:
649 // Since certain states of SM4 means that it is fetching for Chamber8
650 // and other states are for fetching from Chamber7. We need to make
651 // requests for the correct chamber.
652 Assert( fSm4state == kWaitChamber8
653 || fSm4state == kWaitMoreChamber8
654 || fSm4state == kWaitChamber7
655 || fSm4state == kWaitMoreChamber7
657 AliTagData* tag = &data->fTag;
658 if (fSm4state == kWaitChamber8 || fSm4state == kWaitMoreChamber8)
660 // Form the vector line between trigger station 1 and tracking station 5,
661 // and find the intersection point of the line with station 4 (chamber8).
662 AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
663 AliHLTMUONCorePoint intercept = line51.FindIntersectWithXYPlain( fgZ8 );
666 // Build a region of interest for tracking station 4.
667 tag->fChamber = kChamber8;
668 tag->fRoi.Create(intercept, fgA8, fgB8);
672 // Form the vector line between trigger station 1 and tracking station 5,
673 // and find the intersection point of the line with station 4 (chamber7).
674 AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
675 AliHLTMUONCorePoint intercept = line51.FindIntersectWithXYPlain( fgZ7 );
678 // Build a region of interest for tracking station 4.
679 tag->fChamber = kChamber7;
680 tag->fRoi.Create(intercept, fgA7, fgB7);
683 // Make the request for clusters from station 4.
684 Float left, right, bottom, top;
685 tag->fRoi.GetBoundaryBox(left, right, bottom, top);
686 RequestClusters(left, right, bottom, top, tag->fChamber, tag);
690 void AliHLTMUONCoreMansoTracker::ProcessClusters()
692 // Process clusters that have been received.
693 // This is called once all clusters have been found.
695 DebugMsg(2, "ProcessClusters...");
697 // Check if the cluster point list on station 4 is empty.
698 // If it is then we have not found any tracks.
699 fFoundPoint = fSt4points.First();
700 if (fFoundPoint == fSt4points.End())
706 fSt5rec = fSt5data.First();
707 if (fSt5rec != fSt5data.End())
709 // Only look at station 5 data records that are for the found chamber number.
710 // Note: either we only have chamber 8 data or we have chamber 7 data followed
711 // by chamber 8 data.
712 // Thus if we hit records that we are not interested in already then the list
713 // contains no interesting data and we can signal no track found.
714 if (fSt5rec->fTag.fChamber != fSt4chamber)
720 // For all combinations of cluster point pairs from station 4 and 5
721 // signal a found track:
724 DebugMsg(4, "\tfSt5rec->fTag.chamber = " << fSt5rec->fTag.fChamber
725 << " , fSt4chamber = " << fSt4chamber
728 for (fFoundPoint = fSt4points.First(); fFoundPoint != fSt4points.End(); fFoundPoint++)
730 if (fFoundPoint->fSt5tag == &fSt5rec->fTag)
734 fSt5rec++; // Get next station 5 cluster point.
735 } while (fSt5rec != fSt5data.End() && fSt5rec->fTag.fChamber == fSt4chamber);