]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/src/Tracking/MansoTracker.cxx
Coding violations in HLT/MUON
[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 #if defined(DEBUG) || (defined(USE_ALILOG) && ! defined(LOG_NO_DEBUG))
17 #include <ostream>
18 #include "Debug/print.hpp"
19 namespace
20 {
21
22 std::ostream& operator << (std::ostream& os, AliHLTMUONCoreMansoTracker::StatesSM4 state)
23 {
24         switch (state)
25         {
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!!"; 
32         }
33         return os;
34 }
35
36 std::ostream& operator << (std::ostream& os, AliHLTMUONCoreMansoTracker::StatesSM5 state)
37 {
38         switch (state)
39         {
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!!"; 
47         }
48         return os;
49 }
50
51 } // end of namespace
52 #endif // DEBUG
53
54
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;
74
75
76 void AliHLTMUONCoreMansoTracker::AliRegionOfInterest::Create(AliHLTMUONCorePoint p, Float a, Float b)
77 {
78 // Creates a region of interest specific to the Manso algorithm from a point and
79 // two Manso specific parameters.
80
81         fCentre = p;
82         // Compute the radius Rp
83         Float rp = (Float) sqrt( p.fX * p.fX + p.fY * p.fY );
84
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
89         //   equation:
90         //     Rs = a * Rp + b
91         //   given on page 3 section 4.
92         fRs = a * rp + b;
93 }
94
95
96 bool AliHLTMUONCoreMansoTracker::AliRegionOfInterest::Contains(AliHLTMUONCorePoint p) const
97 {
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
106         );
107         return r <= fRs;
108 }
109
110
111 void AliHLTMUONCoreMansoTracker::AliRegionOfInterest::GetBoundaryBox(
112                 Float& left, Float& right, Float& bottom, Float& top
113         ) const
114 {
115 // Works out the smallest boundary box that will contain the region of interest.
116
117         left = fCentre.fX - fRs;
118         right = fCentre.fX + fRs;
119         bottom = fCentre.fY - fRs;
120         top = fCentre.fY + fRs;
121 }
122
123
124 AliHLTMUONCoreMansoTracker::AliVertex::AliVertex(Float x, Float y, Float z)
125 {
126 // Constructor for vertex.
127
128         fX = x;
129         fY = y;
130         fZ = z;
131 }
132
133
134 AliHLTMUONCoreMansoTracker::AliVertex::AliVertex(AliHLTMUONCorePoint xy, Float z)
135 {
136 // Construct vertex from a point on the XY plane and z coordinate.
137
138         fX = xy.fX;
139         fY = xy.fY;
140         fZ = z;
141 }
142
143
144 AliHLTMUONCoreMansoTracker::AliLine::AliLine(
145         Float ax, Float ay, Float az,
146         Float bx, Float by, Float bz
147     )
148 {
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)
152
153         fMx = ax - bx;
154         fMy = ay - by;
155         fMz = az - bz;
156         fCx = bx;
157         fCy = by;
158         fCz = bz;
159 }
160
161
162 AliHLTMUONCoreMansoTracker::AliLine::AliLine(AliVertex a, AliVertex b)
163 {
164 // Contruct a line to go through two vertices a and b.
165
166         fMx = a.X() - b.X();
167         fMy = a.Y() - b.Y();
168         fMz = a.Z() - b.Z();
169         fCx = b.X();
170         fCy = b.Y();
171         fCz = b.Z();
172 }
173
174
175 AliHLTMUONCorePoint AliHLTMUONCoreMansoTracker::AliLine::FindIntersectWithXYPlain(Float z) const
176 {
177 // Find the point of intersection of the line and the XY plane at z.
178
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;
183
184         return AliHLTMUONCorePoint(lx, ly);
185 }
186
187
188 AliHLTMUONCoreMansoTracker::AliHLTMUONCoreMansoTracker() : AliHLTMUONCoreTracker()
189 {
190 // Default constructor 
191
192         fSm4state = kSM4Idle;
193         fSm5state = kSM5Idle;
194         fRequestsCompleted = 0;
195 }
196
197
198 void AliHLTMUONCoreMansoTracker::FindTrack(const AliHLTMUONCoreTriggerRecord& trigger)
199 {
200 // Tries to find the track from the trigger seed.
201
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 );
206
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 );
211
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);
216         
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;
221
222         Float left, right, bottom, top;
223         fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
224         RequestClusters(left, right, bottom, top, kChamber10, &fMc1);
225 }
226
227
228 void AliHLTMUONCoreMansoTracker::ReturnClusters(void* tag, const AliHLTMUONCoreClusterPoint* clusters, UInt count)
229 {
230 // Implementation of AliHLTMUONCoreTracker::ReturnClusters.
231
232         Assert( count > 0 );
233         Assert( clusters != NULL );
234         
235         AliTagData* data = (AliTagData*)tag;
236         DebugMsg(4, "Got AliHLTMUONCoreMansoTracker::ReturnClusters(tag = " << tag
237                 << ", chamber = " << data->fChamber
238                 << ", clusters = " << clusters <<  ", count = " << count << ")"
239         );
240         DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
241
242         switch (data->fChamber)
243         {
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;
248         default:
249                 // Error
250                 DebugMsg(1, "ERROR: Got tag with an invalid value: " << data->fChamber);
251         }
252 }
253
254
255 void AliHLTMUONCoreMansoTracker::EndOfClusters(void* tag)
256 {
257 // Implementation of AliHLTMUONCoreTracker::EndOfClusters.
258
259         AliTagData* data = (AliTagData*)tag;
260         DebugMsg(4, "Got AliHLTMUONCoreMansoTracker::EndOfClusters(chamber = " << data->fChamber << ")");
261         DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
262
263         switch (data->fChamber)
264         {
265         case kChamber7:  EndOfClustersChamber7(); break;
266         case kChamber8:  EndOfClustersChamber8(); break;
267         case kChamber9:  EndOfClustersChamber9(); break;
268         case kChamber10: EndOfClustersChamber10(); break;
269         default:
270                 // Error
271                 DebugMsg(1, "ERROR: Got tag with an invalid value: " << data->fChamber);
272         }
273 }
274
275
276 void AliHLTMUONCoreMansoTracker::FillTrackData(AliHLTMUONCoreTrack& track)
277 {
278 // Implementation of AliHLTMUONCoreTracker::FillTrackData
279
280         DebugMsg(4, "FillTrack: st5 = " << fSt5rec->fClusterPoint << ", st4 = " << fFoundPoint->fClusterPoint);
281         
282         Float x1 = fFoundPoint->fClusterPoint.fX;
283         Float y1 = fFoundPoint->fClusterPoint.fY;
284         Float y2 = fSt5rec->fClusterPoint.fY;
285         Float momentum;
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
290         );
291
292         if (pt < 0)
293                 track.fSign = kSignMinus;
294         else if (pt > 0)
295                 track.fSign = kSignPlus;
296         else
297                 track.fSign = kUnknownSign;
298
299         track.fP = momentum;
300         track.fPt = (Float) fabs(pt);
301         for (UInt i = 0; i < 6; i++)
302         {
303                 track.fPoint[i] = AliHLTMUONCorePoint(0.0, 0.0);
304                 track.fRegion[i] = kInvalidROI;
305         }
306
307         Float left, right, bottom, top;
308         
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);
314         
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)
318         {
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;
323         }
324         else
325         {
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;
330         }
331         if (fMc1.fChamber == kChamber10)
332         {
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;
337         }
338         else
339         {
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;
344         }
345 }
346
347
348 void AliHLTMUONCoreMansoTracker::Reset()
349 {
350 // Implementation of AliHLTMUONCoreTracker::Reset
351
352         DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
353         fSt5data.Clear();
354         fSt4points.Clear();
355         fSm4state = kSM4Idle;
356         fSm5state = kSM5Idle;
357         fRequestsCompleted = 0;
358 }
359
360
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.
369
370 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber7(
371                 const AliHLTMUONCoreClusterPoint* clusters, UInt count, const AliTagData* data
372         )
373 {
374 // State change method for Station 4 state machine.
375
376         switch (fSm4state)
377         {
378         case kWaitChamber7:
379                 fSm4state = kWaitMoreChamber7;
380         
381         case kWaitMoreChamber7:
382                 for (UInt j = 0; j < count; j++)
383                 {
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) )
387                         {
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;
392                         }
393                 }
394                 break;
395         
396         default:
397                 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber7!");
398         }
399 }
400
401
402 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber8(
403                 const AliHLTMUONCoreClusterPoint* clusters, UInt count, const AliTagData* data
404         )
405 {
406 // State change method for Station 4 state machine.
407
408         switch (fSm4state)
409         {
410         case kWaitChamber8:
411                 fSm4state = kWaitMoreChamber8;
412                 fSt4z = fgZ8;
413                 fSt4chamber = kChamber8;
414         
415         case kWaitMoreChamber8:
416                 for (UInt j = 0; j < count; j++)
417                 {
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) )
421                         {
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;
426                         }
427                 }
428                 break;
429                 
430         default:
431                 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber8!");
432         }
433 }
434
435
436 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber9(const AliHLTMUONCoreClusterPoint* clusters, UInt count)
437 {
438 // State change method for Station 5 state machine.
439
440         switch (fSm5state)
441         {
442         case kWaitChamber9:
443                 fSm5state = kWaitMoreChamber9;
444                 fSm4state = kWaitChamber8;  // Start SM4.
445         
446         case kWaitMoreChamber9:
447                 for (UInt j = 0; j < count; j++)
448                 {
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) )
452                         {
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.
457                         }
458                 }
459                 break;
460
461         default:
462                 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber9!");
463         }
464 }
465
466
467 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber10(const AliHLTMUONCoreClusterPoint* clusters, UInt count)
468 {
469 // State change method for Station 5 state machine.
470
471         switch (fSm5state)
472         {
473         case kWaitChamber10:
474                 fSm5state = kWaitMoreChamber10;
475                 fSt5z = fgZ10;
476                 fSm4state = kWaitChamber8;  // Start SM4.
477         
478         case kWaitMoreChamber10:
479                 for (UInt j = 0; j < count; j++)
480                 {
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) )
484                         {
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.
489                         }
490                 }
491                 break;
492
493         default:
494                 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber10!");
495         }
496 }
497
498
499 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber7()
500 {
501 // State change method for Station 4 state machine.
502
503         fRequestsCompleted++;  // Increment the number of requests completed for station 4.
504         DebugMsg(4, "fRequestsCompleted = " << fRequestsCompleted );
505
506         switch (fSm4state)
507         {
508         case kWaitChamber7:
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();
512                 break;
513         
514         case kWaitMoreChamber7:
515                 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
516                         ProcessClusters();
517                 break;
518         
519         default:
520                 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber7!");
521         }
522 }
523
524
525 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber8()
526 {
527 // State change method for Station 4 state machine.
528
529         fRequestsCompleted++;  // Increment the number of requests completed for station 4.
530         DebugMsg(4, "fRequestsCompleted = " << fRequestsCompleted );
531
532         switch (fSm4state)
533         {
534         case kWaitChamber7:
535                 // Ignore. The requests for chamber 8 are already re-requested below.
536                 break;
537                 
538         case kWaitChamber8:
539                 {
540                 fSm4state = kWaitChamber7;
541                 fSt4z = fgZ7;
542                 fSt4chamber = kChamber7;
543         
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);
548
549                 Station5List::Iterator rec = fSt5data.First();
550                 for (UInt i = 0; i < reqlistsize; i++, rec++)
551                 {
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;
556
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);
562                         
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);
567                 }
568                 }
569                 break;
570         
571         case kWaitMoreChamber8:
572                 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
573                         ProcessClusters();
574                 break;
575         
576         default:
577                 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber8!");
578         }
579 }
580
581
582 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber9()
583 {
584 // State change method for Station 5 state machine.
585
586         switch (fSm5state)
587         {
588         case kWaitChamber9:
589                 fSm5state = kSM5Done;
590                 EndOfClusterRequests();
591                 NoTrackFound();
592                 break;
593                 
594         case kWaitMoreChamber9:
595                 fSm5state = kSM5Done;
596                 EndOfClusterRequests();
597                 if (fRequestsCompleted == fSt5data.Count())
598                         ProcessClusters();
599                 break;
600
601         default:
602                 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber9!");
603         }
604 }
605
606
607 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber10()
608 {
609 // State change method for Station 5 state machine.
610
611         switch (fSm5state)
612         {
613         case kWaitChamber10:
614                 {
615                 fSm5state = kWaitChamber9;
616                 fSt5z = fgZ9;
617                 
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 );
621
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);
626
627                 Float left, right, bottom, top;
628                 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
629                 RequestClusters(left, right, bottom, top, kChamber9, &fMc1);
630                 }
631                 break;
632
633         case kWaitMoreChamber10:
634                 fSm5state = kSM5Done;
635                 EndOfClusterRequests();
636                 if (fRequestsCompleted == fSt5data.Count())
637                         ProcessClusters();
638                 break;
639
640         default:
641                 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber10!");
642         }
643 }
644
645
646 void AliHLTMUONCoreMansoTracker::ProjectToStation4(AliStation5Data* data, register Float station5z)
647 {
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
656         );
657         AliTagData* tag = &data->fTag;
658         if (fSm4state == kWaitChamber8 || fSm4state == kWaitMoreChamber8)
659         {
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 );
664                 tag->fLine = line51;
665                 
666                 // Build a region of interest for tracking station 4.
667                 tag->fChamber = kChamber8;
668                 tag->fRoi.Create(intercept, fgA8, fgB8);
669         }
670         else
671         {
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 );
676                 tag->fLine = line51;
677                 
678                 // Build a region of interest for tracking station 4.
679                 tag->fChamber = kChamber7;
680                 tag->fRoi.Create(intercept, fgA7, fgB7);
681         }
682
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);
687 }
688
689
690 void AliHLTMUONCoreMansoTracker::ProcessClusters()
691 {
692 // Process clusters that have been received.
693 // This is called once all clusters have been found.
694
695         DebugMsg(2, "ProcessClusters...");
696         
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())
701         {
702                 NoTrackFound();
703                 return;
704         }
705         
706         fSt5rec = fSt5data.First();
707         if (fSt5rec != fSt5data.End())
708         {
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)
715                 {
716                         NoTrackFound();
717                         return;
718                 }
719                  
720                 // For all combinations of cluster point pairs from station 4 and 5
721                 // signal a found track:
722                 do
723                 {
724                         DebugMsg(4, "\tfSt5rec->fTag.chamber = " << fSt5rec->fTag.fChamber
725                                 << " , fSt4chamber = " << fSt4chamber
726                         );
727
728                         for (fFoundPoint = fSt4points.First(); fFoundPoint != fSt4points.End(); fFoundPoint++)
729                         {
730                                 if (fFoundPoint->fSt5tag == &fSt5rec->fTag)
731                                         FoundTrack();
732                         }
733
734                         fSt5rec++;  // Get next station 5 cluster point.
735                 } while (fSt5rec != fSt5data.End() && fSt5rec->fTag.fChamber == fSt4chamber);
736         }
737         else
738                 NoTrackFound();
739 }
740