]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/src/Tracking/MansoTracker.cxx
654c88f0e83ac46adc66e97e81ef89865d982e91
[u/mrichter/AliRoot.git] / HLT / MUON / src / Tracking / MansoTracker.cxx
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Author: Artur Szostak
4 // Email:  artur@alice.phy.uct.ac.za | artursz@iafrica.com
5 //
6 ////////////////////////////////////////////////////////////////////////////////
7
8 #include "Tracking/MansoTracker.hpp"
9 #include <math.h>
10 #include "Tracking/Calculations.hpp"
11 #include "Utils.hpp"
12 #include "Error.hpp"
13 #include "RegionOfInterest.hpp"
14
15
16 #ifdef DEBUG
17 #include <ostream>
18 #include "Debug/print.hpp"
19 namespace
20 {
21
22 using dHLT::Tracking::MansoTracker;
23
24 std::ostream& operator << (std::ostream& os, MansoTracker::StatesSM4 state)
25 {
26         switch (state)
27         {
28         case MansoTracker::SM4Idle:          os << "SM4Idle"; break;
29         case MansoTracker::WaitChamber8:     os << "WaitChamber8"; break;
30         case MansoTracker::WaitMoreChamber8: os << "WaitMoreChamber8"; break;
31         case MansoTracker::WaitChamber7:     os << "WaitChamber7"; break;
32         case MansoTracker::WaitMoreChamber7: os << "WaitMoreChamber7"; break;
33         default:                             os << "FAULT!!"; 
34         };
35         return os;
36 };
37
38 std::ostream& operator << (std::ostream& os, MansoTracker::StatesSM5 state)
39 {
40         switch (state)
41         {
42         case MansoTracker::SM5Idle:           os << "SM5Idle"; break;
43         case MansoTracker::WaitChamber10:     os << "WaitChamber10"; break;
44         case MansoTracker::WaitMoreChamber10: os << "WaitMoreChamber10"; break;
45         case MansoTracker::WaitChamber9:      os << "WaitChamber9"; break;
46         case MansoTracker::WaitMoreChamber9:  os << "WaitMoreChamber9"; break;
47         case MansoTracker::SM5Done:           os << "SM5Done"; break;
48         default:                              os << "FAULT!!"; 
49         };
50         return os;
51 };
52
53 }; // end of namespace
54 #endif // DEBUG
55
56
57 namespace dHLT
58 {
59 namespace Tracking
60 {
61
62
63 // Deviate from the Manso implementation by allowing a and b
64 // parameters per chamber and not just per station.
65 // The default values are derived from the work done in
66 //    "A first algorithm for dimuon High Level Trigger"
67 //    Ref ID:  ALICE-INT-2002-04 version 1.0
68 Float MansoTracker::a7  = 0.016f;
69 Float MansoTracker::b7  = 2.0f;
70 Float MansoTracker::a8  = 0.016f;
71 Float MansoTracker::b8  = 2.0f;
72 Float MansoTracker::a9  = 0.020f;
73 Float MansoTracker::b9  = 3.0f;
74 Float MansoTracker::a10 = 0.020f;
75 Float MansoTracker::b10 = 3.0f;
76 Float MansoTracker::z7  = 1251.5f;
77 Float MansoTracker::z8  = 1278.5f;
78 Float MansoTracker::z9  = 1416.5f;
79 Float MansoTracker::z10 = 1443.5f;
80 Float MansoTracker::z11 = 1603.5f;
81 Float MansoTracker::z13 = 1703.5f;
82
83
84 void MansoTracker::RegionOfInterest::Create(Point p, Float a, Float b)
85 {
86         centre = p;
87         // Compute the radius Rp
88         Float Rp = (Float) sqrt( p.x * p.x + p.y * p.y );
89
90         // The radius Rs for the region of interest is computed from the
91         // specification given in the document:
92         //   "A first algorithm for dimuon High Level Trigger"
93         //   Ref ID:  ALICE-INT-2002-04 version 1.0
94         //   equation:
95         //     Rs = a * Rp + b
96         //   given on page 3 section 4.
97         Rs = a * Rp + b;
98 };
99
100
101 bool MansoTracker::RegionOfInterest::Contains(Point p) const
102 {
103         // Compute the distance between the centre of the region of interest and
104         // the point p. This distance must be less than the radius of the region
105         // of interest for p to be contained in the region of interest.
106         register Float lx = centre.x - p.x;
107         register Float ly = centre.y - p.y;
108         register Float r = (Float) sqrt( lx * lx + ly * ly );
109         DebugMsg(4, "\tRegionOfInterest::Contains : p = " << p
110                 << " , centre = " << centre << " , r = " << r << " , Rs = " << Rs
111         );
112         return r <= Rs;
113 };
114
115
116 void MansoTracker::RegionOfInterest::GetBoundaryBox(Float& left, Float& right, Float& bottom, Float& top)
117 {
118         left = centre.x - Rs;
119         right = centre.x + Rs;
120         bottom = centre.y - Rs;
121         top = centre.y + Rs;
122 };
123
124
125 MansoTracker::Vertex::Vertex(Float x, Float y, Float z)
126 {
127         this->x = x;
128         this->y = y;
129         this->z = z;
130 };
131
132
133 MansoTracker::Vertex::Vertex(Point xy, Float z)
134 {
135         x = xy.x;
136         y = xy.y;
137         this->z = z;
138 };
139
140
141 MansoTracker::Line::Line(
142         Float Ax, Float Ay, Float Az,
143         Float Bx, Float By, Float Bz
144     )
145 {
146         Mx = Ax - Bx;
147         My = Ay - By;
148         Mz = Az - Bz;
149         Cx = Bx;
150         Cy = By;
151         Cz = Bz;
152 };
153
154
155 MansoTracker::Line::Line(Vertex A, Vertex B)
156 {
157         Mx = A.x - B.x;
158         My = A.y - B.y;
159         Mz = A.z - B.z;
160         Cx = B.x;
161         Cy = B.y;
162         Cz = B.z;
163 };
164
165
166 Point MansoTracker::Line::FindIntersectWithXYPlain(Float z) const
167 {
168         Assert( Mz != 0.0 );    // Should not have a ray perpendicular to the beam axis.
169         Float t = (z - Cz) / Mz;
170         Float Lx = Mx*t + Cx;
171         Float Ly = My*t + Cy;
172
173         return Point(Lx, Ly);
174 };
175
176
177 MansoTracker::MansoTracker() : Tracker()
178 {
179         sm4state = SM4Idle;
180         sm5state = SM5Idle;
181         requests_completed = 0;
182 };
183
184
185 void MansoTracker::FindTrack(const TriggerRecord& trigger)
186 {
187         DebugMsg(4, "SM5 state = " << sm5state << " , SM4 state = " << sm4state);
188         DebugMsg(1, "Processing trigger with pt = " << trigger.pt);
189         v1 = Vertex( trigger.station1impact, z11 );
190         Vertex v2 = Vertex( trigger.station2impact, z13 );
191
192         // Form the vector line between the above two impact points and
193         // find the crossing point of the line with chamber 10 (i.e. station 5).
194         mc1.line = Line(v1, v2);
195         Point p10 = mc1.line.FindIntersectWithXYPlain( z10 );
196
197         // Build a region of interest for tracking station 5 (chamber 10).
198         // Remember the parameters a and b are station specific.
199         mc1.chamber = Chamber10;
200         mc1.roi.Create(p10, a10, b10);
201         
202         // Make SM5 state transition before the call to RequestClusters since
203         // that method could call one of our methods again, so we need to be
204         // in a consistant internal state.
205         sm5state = WaitChamber10;
206
207         Float left, right, bottom, top;
208         mc1.roi.GetBoundaryBox(left, right, bottom, top);
209         RequestClusters(left, right, bottom, top, Chamber10, &mc1);
210 };
211
212
213 void MansoTracker::ReturnClusters(void* tag, const ClusterPoint* clusters, UInt count)
214 {
215         Assert( count > 0 );
216         Assert( clusters != NULL );
217         
218         TagData* data = (TagData*)tag;
219         DebugMsg(4, "Got MansoTracker::ReturnClusters(tag = " << tag
220                 << ", chamber = " << data->chamber
221                 << ", clusters = " << clusters <<  ", count = " << count << ")"
222         );
223         DebugMsg(4, "SM5 state = " << sm5state << " , SM4 state = " << sm4state);
224
225         switch (data->chamber)
226         {
227         case Chamber7:  ReceiveClustersChamber7(clusters, count, data); break;
228         case Chamber8:  ReceiveClustersChamber8(clusters, count, data); break;
229         case Chamber9:  ReceiveClustersChamber9(clusters, count); break;
230         case Chamber10: ReceiveClustersChamber10(clusters, count); break;
231         default:
232                 // Error
233                 DebugMsg(1, "ERROR: Got tag with an invalid value: " << data->chamber);
234         };
235 };
236
237
238 void MansoTracker::EndOfClusters(void* tag)
239 {
240         TagData* data = (TagData*)tag;
241         DebugMsg(4, "Got MansoTracker::EndOfClusters(chamber = " << data->chamber << ")");
242         DebugMsg(4, "SM5 state = " << sm5state << " , SM4 state = " << sm4state);
243
244         switch (data->chamber)
245         {
246         case Chamber7:  EndOfClustersChamber7(); break;
247         case Chamber8:  EndOfClustersChamber8(); break;
248         case Chamber9:  EndOfClustersChamber9(); break;
249         case Chamber10: EndOfClustersChamber10(); break;
250         default:
251                 // Error
252                 DebugMsg(1, "ERROR: Got tag with an invalid value: " << data->chamber);
253         };
254 };
255
256
257 void MansoTracker::FillTrackData(Track& track)
258 {
259         DebugMsg(4, "FillTrack: st5 = " << st5rec->clusterpoint << ", st4 = " << *foundpoint);
260         
261         Float x1 = foundpoint->x;
262         Float y1 = foundpoint->y;
263         Float y2 = st5rec->clusterpoint.y;
264         Float momentum;
265         Float pt = CalculateSignedPt(x1, y1, y2, st4z, st5z, momentum);
266         DebugMsg(1, "Calculated Pt = " << pt);
267         DebugMsg(1, "\tusing x1 = " << x1 << " , y1 = " << y1 << " , y2 = " << y2
268                 << " , z1 = " << st4z << " , z2 = " << st5z
269         );
270
271         if (pt < 0)
272                 track.sign = Minus;
273         else if (pt > 0)
274                 track.sign = Plus;
275         else
276                 track.sign = UnknownSign;
277
278         track.p = momentum;
279         track.pt = (Float) fabs(pt);
280         for (UInt i = 0; i < 6; i++)
281         {
282                 track.point[i] = Point(0.0, 0.0);
283                 track.region[i] = INVALID_ROI;
284         };
285
286         Float left, right, bottom, top;
287         
288         // Have to create the ROI numbers from the internal region of interest structures.
289         st5rec->tag.roi.GetBoundaryBox(left, right, bottom, top);
290         dHLT::RegionOfInterest region4(left, right, bottom, top, st4chamber);
291         mc1.roi.GetBoundaryBox(left, right, bottom, top);
292         dHLT::RegionOfInterest region5(left, right, bottom, top, mc1.chamber);
293         
294         // Depending on the chamber we received cluster points from, fill the appropriate
295         // point and ROI number. This is done for station 4 then 5.
296         if (st4chamber == Chamber8)
297         {
298                 track.point[6] = Point(0.0, 0.0);
299                 track.region[6] = INVALID_ROI;
300                 track.point[7] = *foundpoint;
301                 track.region[7] = region4;
302         }
303         else
304         {
305                 track.point[6] = *foundpoint;
306                 track.region[6] = region4;
307                 track.point[7] = Point(0.0, 0.0);
308                 track.region[7] = INVALID_ROI;
309         };
310         if (mc1.chamber == Chamber10)
311         {
312                 track.point[8] = Point(0.0, 0.0);
313                 track.region[8] = INVALID_ROI;
314                 track.point[9] = st5rec->clusterpoint;
315                 track.region[9] = region5;
316         }
317         else
318         {
319                 track.point[8] = st5rec->clusterpoint;
320                 track.region[8] = region5;
321                 track.point[9] = Point(0.0, 0.0);
322                 track.region[9] = INVALID_ROI;
323         };
324 };
325
326
327 void MansoTracker::Reset()
328 {
329         DebugMsg(4, "SM5 state = " << sm5state << " , SM4 state = " << sm4state);
330         st5data.Clear();
331         st4points.Clear();
332         sm4state = SM4Idle;
333         sm5state = SM5Idle;
334         requests_completed = 0;
335 };
336
337
338 // Note: In the following ReceiveClustersXXX and EndOfClustersXXX methods we make
339 // the state machine transitions before calls to RequestClusters, FoundTrack, 
340 // NoTrackFound or EndOfClusterRequests. This is important since the callback
341 // object will make recursive calls the trackers methods so we need to maintain
342 // a consistant internal state.
343 // The same would go for updating internal variables.
344 // In general one should only call the callback methods at the end of any of the
345 // following routines.
346
347 void MansoTracker::ReceiveClustersChamber7(const ClusterPoint* clusters, UInt count, const TagData* data)
348 {
349         switch (sm4state)
350         {
351         case WaitChamber7:
352                 sm4state = WaitMoreChamber7;
353         
354         case WaitMoreChamber7:
355                 for (UInt j = 0; j < count; j++)
356                 {
357                         ClusterPoint cluster = clusters[j];
358                         // Check that the cluster actually is in our region of interest on station 4.
359                         if ( data->roi.Contains(cluster) )
360                         {
361                                 DebugMsg(4, "Adding cluster [" << cluster.x << ", " << cluster.y << "] from chamber 7.");
362                                 st4points.Add(cluster);
363                         };
364                 };
365                 break;
366         
367         default:
368                 DebugMsg(1, "ERROR: Unexpected state for SM4 in MansoTracker::ReceiveClustersChamber7!");
369         };
370 };
371
372
373 void MansoTracker::ReceiveClustersChamber8(const ClusterPoint* clusters, UInt count, const TagData* data)
374 {
375         switch (sm4state)
376         {
377         case WaitChamber8:
378                 sm4state = WaitMoreChamber8;
379                 st4z = z8;
380                 st4chamber = Chamber8;
381         
382         case WaitMoreChamber8:
383                 for (UInt j = 0; j < count; j++)
384                 {
385                         ClusterPoint cluster = clusters[j];
386                         // Check that the cluster actually is in our region of interest on station 4.
387                         if ( data->roi.Contains(cluster) )
388                         {
389                                 DebugMsg(4, "Adding cluster [" << cluster.x << ", " << cluster.y << "] from chamber 8.");
390                                 st4points.Add(cluster);
391                         };
392                 };
393                 break;
394                 
395         default:
396                 DebugMsg(1, "ERROR: Unexpected state for SM4 in MansoTracker::ReceiveClustersChamber8!");
397         };
398 };
399
400
401 void MansoTracker::ReceiveClustersChamber9(const ClusterPoint* clusters, UInt count)
402 {
403         switch (sm5state)
404         {
405         case WaitChamber9:
406                 sm5state = WaitMoreChamber9;
407                 sm4state = WaitChamber8;  // Start SM4.
408         
409         case WaitMoreChamber9:
410                 for (UInt j = 0; j < count; j++)
411                 {
412                         ClusterPoint cluster = clusters[j];
413                         // Check that the cluster actually is in our region of interest on station 5.
414                         if ( mc1.roi.Contains(cluster) )
415                         {
416                                 DebugMsg(4, "Adding cluster [" << cluster.x << ", " << cluster.y << "] from chamber 9.");
417                                 Station5Data* data = st5data.New();
418                                 data->clusterpoint = cluster;
419                                 ProjectToStation4(data, z9);  // This adds a new request for station 4.
420                         };
421                 };
422                 break;
423
424         default:
425                 DebugMsg(1, "ERROR: Unexpected state for SM5 in MansoTracker::ReceiveClustersChamber9!");
426         };
427 };
428
429
430 void MansoTracker::ReceiveClustersChamber10(const ClusterPoint* clusters, UInt count)
431 {
432         switch (sm5state)
433         {
434         case WaitChamber10:
435                 sm5state = WaitMoreChamber10;
436                 st5z = z10;
437                 sm4state = WaitChamber8;  // Start SM4.
438         
439         case WaitMoreChamber10:
440                 for (UInt j = 0; j < count; j++)
441                 {
442                         ClusterPoint cluster = clusters[j];
443                         // Check that the cluster actually is in our region of interest on station 5.
444                         if ( mc1.roi.Contains(cluster) )
445                         {
446                                 DebugMsg(4, "Adding cluster [" << cluster.x << ", " << cluster.y << "] from chamber 10.");
447                                 Station5Data* data = st5data.New();
448                                 data->clusterpoint = cluster;
449                                 ProjectToStation4(data, z10);  // This adds a new request for station 4.
450                         };
451                 };
452                 break;
453
454         default:
455                 DebugMsg(1, "ERROR: Unexpected state for SM5 in MansoTracker::ReceiveClustersChamber10!");
456         };
457 };
458
459
460 void MansoTracker::EndOfClustersChamber7()
461 {
462         requests_completed++;  // Increment the number of requests completed for station 4.
463         DebugMsg(4, "requests_completed = " << requests_completed );
464
465         switch (sm4state)
466         {
467         case WaitChamber7:
468                 // If all data from station 5 is received and no data found on
469                 // chambers 7 or 8 then we can not find a track.
470                 if (sm5state == SM5Done) NoTrackFound();
471                 break;
472         
473         case WaitMoreChamber7:
474                 if (requests_completed == st5data.Count() and sm5state == SM5Done)
475                         ProcessClusters();
476                 break;
477         
478         default:
479                 DebugMsg(1, "ERROR: Unexpected state for SM4 in MansoTracker::EndOfClustersChamber7!");
480         };
481 };
482
483
484 void MansoTracker::EndOfClustersChamber8()
485 {
486         requests_completed++;  // Increment the number of requests completed for station 4.
487         DebugMsg(4, "requests_completed = " << requests_completed );
488
489         switch (sm4state)
490         {
491         case WaitChamber7:
492                 // Ignore. The requests for chamber 8 are already re-requested below.
493                 break;
494                 
495         case WaitChamber8:
496                 {
497                 sm4state = WaitChamber7;
498                 st4z = z7;
499                 st4chamber = Chamber7;
500         
501                 // We need to resend the requests for chamber 8, but change the request
502                 // to get data for chamber 7 instead:
503                 UInt reqlistsize = st5data.Count();
504                 DebugMsg(4, "Re-requesting clusters from chamber 7... reqlistsize = " << reqlistsize);
505
506                 Station5List::Iterator rec = st5data.First();
507                 for (UInt i = 0; i < reqlistsize; i++, rec++)
508                 {
509                         // Need to create a new st5 data block for the request.
510                         Station5Data* data = st5data.New();
511                         data->clusterpoint = rec->clusterpoint;
512                         data->tag.line = rec->tag.line;
513
514                         // Rebuild a region of interest for chamber 7.
515                         // Remember the parameters a and b are station specific.
516                         Point p7 = data->tag.line.FindIntersectWithXYPlain( z7 );
517                         data->tag.chamber = Chamber7;
518                         data->tag.roi.Create(p7, a7, b7);
519                         
520                         Float left, right, bottom, top;
521                         data->tag.roi.GetBoundaryBox(left, right, bottom, top);
522                         // Make request for chamber 7 data.
523                         RequestClusters(left, right, bottom, top, Chamber7, &data->tag);
524                 };
525                 }
526                 break;
527         
528         case WaitMoreChamber8:
529                 if (requests_completed == st5data.Count() and sm5state == SM5Done)
530                         ProcessClusters();
531                 break;
532         
533         default:
534                 DebugMsg(1, "ERROR: Unexpected state for SM4 in MansoTracker::EndOfClustersChamber8!");
535         };
536 };
537
538
539 void MansoTracker::EndOfClustersChamber9()
540 {
541         switch (sm5state)
542         {
543         case WaitChamber9:
544                 sm5state = SM5Done;
545                 EndOfClusterRequests();
546                 NoTrackFound();
547                 break;
548                 
549         case WaitMoreChamber9:
550                 sm5state = SM5Done;
551                 EndOfClusterRequests();
552                 if (requests_completed == st5data.Count())
553                         ProcessClusters();
554                 break;
555
556         default:
557                 DebugMsg(1, "ERROR: Unexpected state for SM5 in MansoTracker::EndOfClustersChamber9!");
558         };
559 };
560
561
562 void MansoTracker::EndOfClustersChamber10()
563 {
564         switch (sm5state)
565         {
566         case WaitChamber10:
567                 {
568                 sm5state = WaitChamber9;
569                 st5z = z9;
570                 
571                 // No clusters found on chamber 10 so we need to make a request for
572                 // clusters from chamber 9:
573                 Point p9 = mc1.line.FindIntersectWithXYPlain( z9 );
574
575                 // Build a region of interest for tracking station 5 (chamber 9).
576                 // Remember the parameters a and b are station specific.
577                 mc1.chamber = Chamber9;
578                 mc1.roi.Create(p9, a9, b9);
579
580                 Float left, right, bottom, top;
581                 mc1.roi.GetBoundaryBox(left, right, bottom, top);
582                 RequestClusters(left, right, bottom, top, Chamber9, &mc1);
583                 }
584                 break;
585
586         case WaitMoreChamber10:
587                 sm5state = SM5Done;
588                 EndOfClusterRequests();
589                 if (requests_completed == st5data.Count())
590                         ProcessClusters();
591                 break;
592
593         default:
594                 DebugMsg(1, "ERROR: Unexpected state for SM5 in MansoTracker::EndOfClustersChamber10!");
595         };
596 };
597
598
599 void MansoTracker::ProjectToStation4(Station5Data* data, register Float station5z)
600 {
601         // Perform chamber specific operations:
602         // Since certain states of SM4 means that it is fetching for Chamber8
603         // and other states are for fetching from Chamber7. We need to make
604         // requests for the correct chamber.
605         Assert( sm4state == WaitChamber8 or sm4state == WaitMoreChamber8 or
606                 sm4state == WaitChamber7 or sm4state == WaitMoreChamber7
607         );
608         TagData* tag = &data->tag;
609         if (sm4state == WaitChamber8 or sm4state == WaitMoreChamber8)
610         {
611                 // Form the vector line between trigger station 1 and tracking station 5,
612                 // and find the intersection point of the line with station 4 (chamber8).
613                 Line line51( Vertex(data->clusterpoint, station5z), v1 );
614                 Point intercept = line51.FindIntersectWithXYPlain(z8);
615                 tag->line = line51;
616                 
617                 // Build a region of interest for tracking station 4.
618                 tag->chamber = Chamber8;
619                 tag->roi.Create(intercept, a8, b8);
620         }
621         else
622         {
623                 // Form the vector line between trigger station 1 and tracking station 5,
624                 // and find the intersection point of the line with station 4 (chamber7).
625                 Line line51( Vertex(data->clusterpoint, station5z), v1 );
626                 Point intercept = line51.FindIntersectWithXYPlain(z7);
627                 tag->line = line51;
628                 
629                 // Build a region of interest for tracking station 4.
630                 tag->chamber = Chamber7;
631                 tag->roi.Create(intercept, a7, b7);
632         };
633
634         // Make the request for clusters from station 4.
635         Float left, right, bottom, top;
636         tag->roi.GetBoundaryBox(left, right, bottom, top);
637         RequestClusters(left, right, bottom, top, tag->chamber, tag);
638 };
639
640
641 void MansoTracker::ProcessClusters()
642 {
643         DebugMsg(2, "ProcessClusters...");
644         
645         // Check if the cluster point list on station 4 is empty.
646         // If it is then we have not found any tracks.
647         foundpoint = st4points.First();
648         if (foundpoint == st4points.End())
649         {
650                 NoTrackFound();
651                 return;
652         };
653         
654         st5rec = st5data.First();
655         if (st5rec != st5data.End())
656         {
657                 // Only look at station 5 data records that are for the found chamber number.
658                 // Note: either we only have chamber 8 data or we have chamber 7 data followed
659                 // by chamber 8 data.
660                 // Thus if we hit records that we are not interested in already then the list
661                 // contains no interesting data and we can signal no track found.
662                 if (st5rec->tag.chamber != st4chamber)
663                 {
664                         NoTrackFound();
665                         return;
666                 };
667                  
668                 // For all combinations of cluster point pairs from station 4 and 5
669                 // signal a found track:
670                 do
671                 {
672                         DebugMsg(4, "\tst5rec->tag.chamber = " << st5rec->tag.chamber
673                                 << " , st4chamber = " << st4chamber
674                         );
675
676                         for (foundpoint = st4points.First(); foundpoint != st4points.End(); foundpoint++)
677                                 FoundTrack();
678
679                         st5rec++;  // Get next station 5 cluster point.
680                 } while (st5rec != st5data.End() and st5rec->tag.chamber == st4chamber);
681         }
682         else
683                 NoTrackFound();
684 };
685
686
687 } // Tracking
688 } // dHLT