Made changes to the trigger reconstructor component algorithm to interpret raw DDL...
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONMansoTrackerFSM.cxx
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        * 
3  * All rights reserved.                                                   *
4  *                                                                        *
5  * Primary Authors:                                                       *
6  *   Artur Szostak <artursz@iafrica.com>                                  *
7  *                                                                        *
8  * Permission to use, copy, modify and distribute this software and its   *
9  * documentation strictly for non-commercial purposes is hereby granted   *
10  * without fee, provided that the above copyright notice appears in all   *
11  * copies and that both the copyright notice and this permission notice   *
12  * appear in the supporting documentation. The authors make no claims     *
13  * about the suitability of this software for any purpose. It is          * 
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16
17 /* $Id$ */
18
19 ///
20 /// @file   AliHLTMUONMansoTrackerFSM.cxx
21 /// @author Artur Szostak <artursz@iafrica.com>
22 /// @date   29 May 2007
23 /// @brief  Implementation of AliHLTMUONMansoTrackerFSM class.
24 ///
25 /// Implementation of AliHLTMUONMansoTrackerFSM class which implements the Manso
26 /// tracking algorithm as a finite state machine, which partially reconstructs
27 /// tracks in the muon spectrometer.
28
29 #include "AliHLTMUONMansoTrackerFSM.h"
30 #include "AliHLTMUONCalculations.h"
31 #include "AliHLTMUONConstants.h"
32 #include "AliHLTMUONUtils.h"
33 #include <cmath>
34
35
36 #ifdef DEBUG
37 #include <ostream>
38 namespace
39 {
40
41 std::ostream& operator << (std::ostream& os, AliHLTMUONMansoTrackerFSM::StatesSM4 state)
42 {
43         switch (state)
44         {
45         case AliHLTMUONMansoTrackerFSM::kSM4Idle:          os << "kSM4Idle"; break;
46         case AliHLTMUONMansoTrackerFSM::kWaitChamber8:     os << "kWaitChamber8"; break;
47         case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber8: os << "kWaitMoreChamber8"; break;
48         case AliHLTMUONMansoTrackerFSM::kWaitChamber7:     os << "kWaitChamber7"; break;
49         case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber7: os << "kWaitMoreChamber7"; break;
50         default:                                           os << "FAULT!!"; 
51         }
52         return os;
53 }
54
55 std::ostream& operator << (std::ostream& os, AliHLTMUONMansoTrackerFSM::StatesSM5 state)
56 {
57         switch (state)
58         {
59         case AliHLTMUONMansoTrackerFSM::kSM5Idle:           os << "kSM5Idle"; break;
60         case AliHLTMUONMansoTrackerFSM::kWaitChamber10:     os << "kWaitChamber10"; break;
61         case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber10: os << "kWaitMoreChamber10"; break;
62         case AliHLTMUONMansoTrackerFSM::kWaitChamber9:      os << "kWaitChamber9"; break;
63         case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber9:  os << "kWaitMoreChamber9"; break;
64         case AliHLTMUONMansoTrackerFSM::kSM5Done:           os << "kSM5Done"; break;
65         default:                                            os << "FAULT!!"; 
66         }
67         return os;
68 }
69
70 } // end of namespace
71 #endif // DEBUG
72
73
74 // Deviate from the Manso implementation by allowing a and b
75 // parameters per chamber and not just per station.
76 // The default values are derived from the work done in
77 //    "A first algorithm for dimuon High Level Trigger"
78 //    Ref ID:  ALICE-INT-2002-04 version 1.0
79 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA7  = 0.016f;
80 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB7  = 2.0f;
81 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA8  = 0.016f;
82 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB8  = 2.0f;
83 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA9  = 0.020f;
84 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB9  = 3.0f;
85 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA10 = 0.020f;
86 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB10 = 3.0f;
87 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ7  = -1274.5f;
88 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ8  = -1305.5f;
89 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ9  = -1408.6f;
90 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ10 = -1439.6f;
91 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ11 = -1603.5f;
92 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ13 = -1703.5f;
93
94
95 void AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::Create(
96                 AliHLTMUONRecHitStruct p, AliHLTFloat32_t a, AliHLTFloat32_t b
97         )
98 {
99 // Creates a region of interest specific to the Manso algorithm from a point and
100 // two Manso specific parameters.
101
102         fCentre = p;
103         // Compute the radius Rp
104         AliHLTFloat32_t rp = (AliHLTFloat32_t) sqrt( p.fX * p.fX + p.fY * p.fY );
105
106         // The radius Rs for the region of interest is computed from the
107         // specification given in the document:
108         //   "A first algorithm for dimuon High Level Trigger"
109         //   Ref ID:  ALICE-INT-2002-04 version 1.0
110         //   equation:
111         //     Rs = a * Rp + b
112         //   given on page 3 section 4.
113         fRs = a * rp + b;
114 }
115
116
117 bool AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::Contains(AliHLTMUONRecHitStruct p) const
118 {
119         // Compute the distance between the centre of the region of interest and
120         // the point p. This distance must be less than the radius of the region
121         // of interest for p to be contained in the region of interest.
122         register AliHLTFloat32_t lx = fCentre.fX - p.fX;
123         register AliHLTFloat32_t ly = fCentre.fY - p.fY;
124         register AliHLTFloat32_t r = (AliHLTFloat32_t) sqrt( lx * lx + ly * ly );
125         DebugTrace("\tAliRegionOfInterest::Contains : p = " << p
126                 << " , centre = " << fCentre << " , r = " << r << " , Rs = " << fRs
127         );
128         return r <= fRs;
129 }
130
131
132 void AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::GetBoundaryBox(
133                 AliHLTFloat32_t& left, AliHLTFloat32_t& right,
134                 AliHLTFloat32_t& bottom, AliHLTFloat32_t& top
135         ) const
136 {
137 // Works out the smallest boundary box that will contain the region of interest.
138
139         left = fCentre.fX - fRs;
140         right = fCentre.fX + fRs;
141         bottom = fCentre.fY - fRs;
142         top = fCentre.fY + fRs;
143 }
144
145
146 AliHLTMUONMansoTrackerFSM::AliVertex::AliVertex(
147                 AliHLTFloat32_t x, AliHLTFloat32_t y, AliHLTFloat32_t z
148         )
149         : fX(x), fY(y), fZ(z)
150 {
151 // Constructor for vertex.
152 }
153
154
155 AliHLTMUONMansoTrackerFSM::AliVertex::AliVertex(AliHLTMUONRecHitStruct xy, AliHLTFloat32_t z)
156         : fX(xy.fX), fY(xy.fY), fZ(z)
157 {
158 // Construct vertex from a point on the XY plane and z coordinate.
159 }
160
161
162 AliHLTMUONMansoTrackerFSM::AliLine::AliLine(
163                 AliHLTFloat32_t ax, AliHLTFloat32_t ay, AliHLTFloat32_t az,
164                 AliHLTFloat32_t bx, AliHLTFloat32_t by, AliHLTFloat32_t bz
165         ) :
166         fMx(ax - bx),
167         fMy(ay - by),
168         fMz(az - bz),
169         fCx(bx),
170         fCy(by),
171         fCz(bz)
172 {
173 // Construct a line defined by L = M*t + C = (A-B)*t + B
174 // where M and C are 3D vectors and t is a free parameter.
175 // A = (ax, ay, az) and B = (bx, by, bz)
176 }
177
178
179 AliHLTMUONMansoTrackerFSM::AliLine::AliLine(AliVertex a, AliVertex b) :
180         fMx(a.X() - b.X()),
181         fMy(a.Y() - b.Y()),
182         fMz(a.Z() - b.Z()),
183         fCx(b.X()),
184         fCy(b.Y()),
185         fCz(b.Z())
186 {
187 // Contruct a line to go through two vertices a and b.
188 }
189
190
191 AliHLTMUONRecHitStruct AliHLTMUONMansoTrackerFSM::AliLine::FindIntersectWithXYPlain(
192                 AliHLTFloat32_t z
193         ) const
194 {
195 // Find the point of intersection of the line and the XY plane at z.
196
197         AliHLTFloat32_t t;
198         if (fMz != 0)  // Should not have a ray perpendicular to the beam axis.
199                 t = (z - fCz) / fMz;
200         else
201                 t = 0;
202         AliHLTMUONRecHitStruct p;
203         p.fX = fMx*t + fCx;
204         p.fY = fMy*t + fCy;
205         p.fZ = z;
206         return p;
207 }
208
209
210 AliHLTMUONMansoTrackerFSM::AliHLTMUONMansoTrackerFSM() :
211         fCallback(NULL),
212         fSm4state(kSM4Idle),
213         fSm5state(kSM5Idle),
214         fRequestsCompleted(0),
215         fSt4chamber(kChamber1),
216         fV1(),
217         fMc1(),
218         fSt5data(),
219         fSt4points(),
220         fSt5rec(),
221         fFoundPoint(),
222         fTriggerId(-1),
223         fTrackId(0)
224 {
225 // Default constructor
226 }
227
228
229 void AliHLTMUONMansoTrackerFSM::FindTrack(const AliHLTMUONTriggerRecordStruct& trigger)
230 {
231 // Tries to find the track from the trigger seed.
232
233         DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
234         DebugTrace("Processing trigger with ID = " << trigger.fId);
235         
236         fTriggerId = trigger.fId;
237         
238         // Set Z coordinates of ideal point on trigger track to be nominal
239         // chamber 11 and 13 positions.
240         AliHLTMUONCalculations::IdealZ1(fgZ11);
241         AliHLTMUONCalculations::IdealZ2(fgZ13);
242         
243         if (not AliHLTMUONCalculations::FitLineToTriggerRecord(trigger))
244         {
245                 NoTrackFound();
246                 return;
247         }
248         fV1 = AliVertex(
249                         AliHLTMUONCalculations::IdealX1(),
250                         AliHLTMUONCalculations::IdealY1(),
251                         AliHLTMUONCalculations::IdealZ1()
252                 );
253         AliVertex v2 = AliVertex(
254                         AliHLTMUONCalculations::IdealX2(),
255                         AliHLTMUONCalculations::IdealY2(),
256                         AliHLTMUONCalculations::IdealZ2()
257                 );
258         
259         DebugTrace("Using fV1 = {x = " << fV1.X() << ", y = " << fV1.Y() << ", " << fV1.Z() << "}");
260         DebugTrace("Using v2 = {x = " << v2.X() << ", y = " << v2.Y() << ", " << v2.Z() << "}");
261
262         // Form the vector line between the above two impact points and
263         // find the crossing point of the line with chamber 10 (i.e. station 5).
264         fMc1.fLine = AliLine(fV1, v2);
265         AliHLTMUONRecHitStruct p10 = fMc1.fLine.FindIntersectWithXYPlain( fgZ10 );
266
267         // Build a region of interest for tracking station 5 (chamber 10).
268         // Remember the parameters a and b are station specific.
269         fMc1.fChamber = kChamber10;
270         fMc1.fRoi.Create(p10, fgA10, fgB10);
271         
272         // Make SM5 state transition before the call to RequestClusters since
273         // that method could call one of our methods again, so we need to be
274         // in a consistant internal state.
275         fSm5state = kWaitChamber10;
276
277         AliHLTFloat32_t left, right, bottom, top;
278         fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
279         RequestClusters(left, right, bottom, top, kChamber10, &fMc1);
280 }
281
282
283 void AliHLTMUONMansoTrackerFSM::ReturnClusters(
284                 void* tag, const AliHLTMUONRecHitStruct* clusters,
285                 AliHLTUInt32_t count
286         )
287 {
288 // Implementation of AliHLTMUONMansoTrackerFSM::ReturnClusters.
289
290         assert( count > 0 );
291         assert( clusters != NULL );
292         
293         AliTagData* data = (AliTagData*)tag;
294         DebugTrace("Got AliHLTMUONMansoTrackerFSM::ReturnClusters(tag = " << tag
295                 << ", chamber = " << data->fChamber
296                 << ", clusters = " << clusters <<  ", count = " << count << ")"
297         );
298         DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
299
300         switch (data->fChamber)
301         {
302         case kChamber7:  ReceiveClustersChamber7(clusters, count, data); break;
303         case kChamber8:  ReceiveClustersChamber8(clusters, count, data); break;
304         case kChamber9:  ReceiveClustersChamber9(clusters, count); break;
305         case kChamber10: ReceiveClustersChamber10(clusters, count); break;
306         default:
307                 // Error
308                 DebugTrace("ERROR: Got tag with an invalid value: " << data->fChamber);
309         }
310 }
311
312
313 void AliHLTMUONMansoTrackerFSM::EndOfClusters(void* tag)
314 {
315 // Implementation of AliHLTMUONMansoTrackerFSM::EndOfClusters.
316
317         AliTagData* data = (AliTagData*)tag;
318         DebugTrace("Got AliHLTMUONMansoTrackerFSM::EndOfClusters(chamber = " << data->fChamber << ")");
319         DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
320
321         switch (data->fChamber)
322         {
323         case kChamber7:  EndOfClustersChamber7(); break;
324         case kChamber8:  EndOfClustersChamber8(); break;
325         case kChamber9:  EndOfClustersChamber9(); break;
326         case kChamber10: EndOfClustersChamber10(); break;
327         default:
328                 // Error
329                 DebugTrace("ERROR: Got tag with an invalid value: " << data->fChamber);
330         }
331 }
332
333
334 bool AliHLTMUONMansoTrackerFSM::FillTrackData(AliHLTMUONMansoTrackStruct& track)
335 {
336 // Implementation of AliHLTMUONMansoTrackerFSM::FillTrackData
337
338         DebugTrace("FillTrack: st5 = " << fSt5rec->fClusterPoint << ", st4 = " << fFoundPoint->fClusterPoint);
339         
340         // Construct the track ID from the running counter fTrackId and the
341         // bottom 8 bits of fTriggerId which will make this unique for an event.
342         track.fId = (fTrackId << 8) | (fTriggerId & 0xFF);
343         
344         // Increment the track ID and warp it around at 0x7FFFFF since the
345         // bottom 8 bits are copied from fTriggerId and the sign bit in
346         // track.fId must be positive.
347         fTrackId = (fTrackId + 1) & 0x007FFFFF;
348         
349         track.fTrigRec = fTriggerId;
350         
351         AliHLTFloat32_t x1 = fFoundPoint->fClusterPoint.fX;
352         AliHLTFloat32_t y1 = fFoundPoint->fClusterPoint.fY;
353         AliHLTFloat32_t z1 = fFoundPoint->fClusterPoint.fZ;
354         AliHLTFloat32_t y2 = fSt5rec->fClusterPoint.fY;
355         AliHLTFloat32_t z2 = fSt5rec->fClusterPoint.fZ;
356         
357         bool calculated = AliHLTMUONCalculations::ComputeMomentum(x1, y1, y2, z1, z2);
358         
359         track.fPx = AliHLTMUONCalculations::Px();
360         track.fPy = AliHLTMUONCalculations::Py();
361         track.fPz = AliHLTMUONCalculations::Pz();
362         DebugTrace("Calculated Px = " << track.fPx << ", Py = " << track.fPy
363                 << ", Pz = " << track.fPx
364         );
365         DebugTrace("\tusing x1 = " << x1 << " , y1 = " << y1 << " , y2 = " << y2
366                 << " , z1 = " << z1 << " , z2 = " << z2
367         );
368         
369         track.fChi2 = 0;
370         
371         bool hitset[4];
372         // Depending on which chamber we found reconstructed hits, fill the hit
373         // in the appropriate location. This is done for station 4 then 5.
374         if (fSt4chamber == kChamber8)
375         {
376                 track.fHit[0] = AliHLTMUONConstants::NilRecHitStruct();
377                 hitset[0] = false;
378                 track.fHit[1] = fFoundPoint->fClusterPoint;
379                 hitset[1] = true;
380         }
381         else
382         {
383                 track.fHit[0] = fFoundPoint->fClusterPoint;
384                 hitset[0] = true;
385                 track.fHit[1] = AliHLTMUONConstants::NilRecHitStruct();
386                 hitset[1] = false;
387         }
388         if (fMc1.fChamber == kChamber10)
389         {
390                 track.fHit[2] = AliHLTMUONConstants::NilRecHitStruct();
391                 hitset[2] = false;
392                 track.fHit[3] = fSt5rec->fClusterPoint;
393                 hitset[3] = true;
394         }
395         else
396         {
397                 track.fHit[2] = fSt5rec->fClusterPoint;
398                 hitset[2] = true;
399                 track.fHit[3] = AliHLTMUONConstants::NilRecHitStruct();
400                 hitset[3] = false;
401         }
402         
403         track.fFlags = AliHLTMUONUtils::PackMansoTrackFlags(
404                         AliHLTMUONCalculations::Sign(), hitset
405                 );
406         return calculated;
407 }
408
409
410 void AliHLTMUONMansoTrackerFSM::Reset()
411 {
412 // Implementation of AliHLTMUONMansoTrackerFSM::Reset
413
414         DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
415         fSt5data.Clear();
416         fSt4points.Clear();
417         fSm4state = kSM4Idle;
418         fSm5state = kSM5Idle;
419         fRequestsCompleted = 0;
420         fTriggerId = -1;
421 }
422
423
424 // Note: In the following ReceiveClustersXXX and EndOfClustersXXX methods we make
425 // the state machine transitions before calls to RequestClusters, FoundTrack, 
426 // NoTrackFound or EndOfClusterRequests. This is important since the callback
427 // object will make recursive calls to the tracker's methods so we need to maintain
428 // a consistant internal state.
429 // The same would go for updating internal variables.
430 // In general one should only call the callback methods at the end of any of the
431 // following routines.
432
433 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7(
434                 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count,
435                 const AliTagData* data
436         )
437 {
438 // State change method for Station 4 state machine.
439
440         switch (fSm4state)
441         {
442         case kWaitChamber7:
443                 fSm4state = kWaitMoreChamber7;
444         
445         case kWaitMoreChamber7:
446                 for (AliHLTUInt32_t j = 0; j < count; j++)
447                 {
448                         AliHLTMUONRecHitStruct cluster = clusters[j];
449                         // Check that the cluster actually is in our region of interest on station 4.
450                         if ( data->fRoi.Contains(cluster) )
451                         {
452                                 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 7.");
453                                 AliStation4Data* newdata = fSt4points.Add();
454                                 newdata->fClusterPoint = cluster;
455                                 newdata->fSt5tag = data;
456                         }
457                 }
458                 break;
459         
460         default:
461                 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7!");
462         }
463 }
464
465
466 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8(
467                 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count,
468                 const AliTagData* data
469         )
470 {
471 // State change method for Station 4 state machine.
472
473         switch (fSm4state)
474         {
475         case kWaitChamber8:
476                 fSm4state = kWaitMoreChamber8;
477                 fSt4chamber = kChamber8;
478         
479         case kWaitMoreChamber8:
480                 for (AliHLTUInt32_t j = 0; j < count; j++)
481                 {
482                         AliHLTMUONRecHitStruct cluster = clusters[j];
483                         // Check that the cluster actually is in our region of interest on station 4.
484                         if ( data->fRoi.Contains(cluster) )
485                         {
486                                 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 8.");
487                                 AliStation4Data* newdata = fSt4points.Add();
488                                 newdata->fClusterPoint = cluster;
489                                 newdata->fSt5tag = data;
490                         }
491                 }
492                 break;
493                 
494         default:
495                 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8!");
496         }
497 }
498
499
500 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9(
501                 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count
502         )
503 {
504 // State change method for Station 5 state machine.
505
506         switch (fSm5state)
507         {
508         case kWaitChamber9:
509                 fSm5state = kWaitMoreChamber9;
510                 fSm4state = kWaitChamber8;  // Start SM4.
511         
512         case kWaitMoreChamber9:
513                 for (AliHLTUInt32_t j = 0; j < count; j++)
514                 {
515                         AliHLTMUONRecHitStruct cluster = clusters[j];
516                         // Check that the cluster actually is in our region of interest on station 5.
517                         if ( fMc1.fRoi.Contains(cluster) )
518                         {
519                                 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 9.");
520                                 AliStation5Data* data = fSt5data.Add();
521                                 data->fClusterPoint = cluster;
522                                 ProjectToStation4(data, fgZ9);  // This adds a new request for station 4.
523                         }
524                 }
525                 break;
526
527         default:
528                 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9!");
529         }
530 }
531
532
533 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10(
534                 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count
535         )
536 {
537 // State change method for Station 5 state machine.
538
539         switch (fSm5state)
540         {
541         case kWaitChamber10:
542                 fSm5state = kWaitMoreChamber10;
543                 fSm4state = kWaitChamber8;  // Start SM4.
544         
545         case kWaitMoreChamber10:
546                 for (AliHLTUInt32_t j = 0; j < count; j++)
547                 {
548                         AliHLTMUONRecHitStruct cluster = clusters[j];
549                         // Check that the cluster actually is in our region of interest on station 5.
550                         if ( fMc1.fRoi.Contains(cluster) )
551                         {
552                                 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 10.");
553                                 AliStation5Data* data = fSt5data.Add();
554                                 data->fClusterPoint = cluster;
555                                 ProjectToStation4(data, fgZ10);  // This adds a new request for station 4.
556                         }
557                 }
558                 break;
559
560         default:
561                 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10!");
562         }
563 }
564
565
566 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7()
567 {
568 // State change method for Station 4 state machine.
569
570         fRequestsCompleted++;  // Increment the number of requests completed for station 4.
571         DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
572
573         switch (fSm4state)
574         {
575         case kWaitChamber7:
576                 // If all data from station 5 is received and no data found on
577                 // chambers 7 or 8 then we can not find a track.
578                 if (fSm5state == kSM5Done) NoTrackFound();
579                 break;
580         
581         case kWaitMoreChamber7:
582                 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
583                         ProcessClusters();
584                 break;
585         
586         default:
587                 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7!");
588         }
589 }
590
591
592 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8()
593 {
594 // State change method for Station 4 state machine.
595
596         fRequestsCompleted++;  // Increment the number of requests completed for station 4.
597         DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
598
599         switch (fSm4state)
600         {
601         case kWaitChamber7:
602                 // Ignore. The requests for chamber 8 are already re-requested below.
603                 break;
604                 
605         case kWaitChamber8:
606                 {
607                 fSm4state = kWaitChamber7;
608                 fSt4chamber = kChamber7;
609         
610                 // We need to resend the requests for chamber 8, but change the request
611                 // to get data for chamber 7 instead:
612                 AliHLTUInt32_t reqlistsize = fSt5data.Count();
613                 DebugTrace("Re-requesting clusters from chamber 7... reqlistsize = " << reqlistsize);
614
615                 Station5List::Iterator rec = fSt5data.First();
616                 for (AliHLTUInt32_t i = 0; i < reqlistsize; i++, rec++)
617                 {
618                         // Need to create a new st5 data block for the request.
619                         AliStation5Data* data = fSt5data.Add();
620                         data->fClusterPoint = rec->fClusterPoint;
621                         data->fTag.fLine = rec->fTag.fLine;
622
623                         // Rebuild a region of interest for chamber 7.
624                         // Remember the parameters a and b are station specific.
625                         AliHLTMUONRecHitStruct p7 = data->fTag.fLine.FindIntersectWithXYPlain( fgZ7 );
626                         data->fTag.fChamber = kChamber7;
627                         data->fTag.fRoi.Create(p7, fgA7, fgB7);
628                         
629                         AliHLTFloat32_t left, right, bottom, top;
630                         data->fTag.fRoi.GetBoundaryBox(left, right, bottom, top);
631                         // Make request for chamber 7 data.
632                         RequestClusters(left, right, bottom, top, kChamber7, &data->fTag);
633                 }
634                 }
635                 break;
636         
637         case kWaitMoreChamber8:
638                 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
639                         ProcessClusters();
640                 break;
641         
642         default:
643                 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8!");
644         }
645 }
646
647
648 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9()
649 {
650 // State change method for Station 5 state machine.
651
652         switch (fSm5state)
653         {
654         case kWaitChamber9:
655                 fSm5state = kSM5Done;
656                 EndOfClusterRequests();
657                 NoTrackFound();
658                 break;
659                 
660         case kWaitMoreChamber9:
661                 fSm5state = kSM5Done;
662                 EndOfClusterRequests();
663                 if (fRequestsCompleted == fSt5data.Count())
664                         ProcessClusters();
665                 break;
666
667         default:
668                 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9!");
669         }
670 }
671
672
673 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10()
674 {
675 // State change method for Station 5 state machine.
676
677         switch (fSm5state)
678         {
679         case kWaitChamber10:
680                 {
681                 fSm5state = kWaitChamber9;
682                 
683                 // No clusters found on chamber 10 so we need to make a request for
684                 // clusters from chamber 9:
685                 AliHLTMUONRecHitStruct p9 = fMc1.fLine.FindIntersectWithXYPlain( fgZ9 );
686
687                 // Build a region of interest for tracking station 5 (chamber 9).
688                 // Remember the parameters a and b are station specific.
689                 fMc1.fChamber = kChamber9;
690                 fMc1.fRoi.Create(p9, fgA9, fgB9);
691
692                 AliHLTFloat32_t left, right, bottom, top;
693                 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
694                 RequestClusters(left, right, bottom, top, kChamber9, &fMc1);
695                 }
696                 break;
697
698         case kWaitMoreChamber10:
699                 fSm5state = kSM5Done;
700                 EndOfClusterRequests();
701                 if (fRequestsCompleted == fSt5data.Count())
702                         ProcessClusters();
703                 break;
704
705         default:
706                 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10!");
707         }
708 }
709
710
711 void AliHLTMUONMansoTrackerFSM::ProjectToStation4(
712                 AliStation5Data* data, register AliHLTFloat32_t station5z
713         )
714 {
715         // Perform chamber specific operations:
716         // Since certain states of SM4 means that it is fetching for Chamber8
717         // and other states are for fetching from Chamber7. We need to make
718         // requests for the correct chamber.
719         assert( fSm4state == kWaitChamber8 
720                 || fSm4state == kWaitMoreChamber8
721                 || fSm4state == kWaitChamber7
722                 || fSm4state == kWaitMoreChamber7
723         );
724         AliTagData* tag = &data->fTag;
725         if (fSm4state == kWaitChamber8 || fSm4state == kWaitMoreChamber8)
726         {
727                 // Form the vector line between trigger station 1 and tracking station 5,
728                 // and find the intersection point of the line with station 4 (chamber8).
729                 AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
730                 AliHLTMUONRecHitStruct intercept = line51.FindIntersectWithXYPlain( fgZ8 );
731                 tag->fLine = line51;
732                 
733                 // Build a region of interest for tracking station 4.
734                 tag->fChamber = kChamber8;
735                 tag->fRoi.Create(intercept, fgA8, fgB8);
736         }
737         else
738         {
739                 // Form the vector line between trigger station 1 and tracking station 5,
740                 // and find the intersection point of the line with station 4 (chamber7).
741                 AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
742                 AliHLTMUONRecHitStruct intercept = line51.FindIntersectWithXYPlain( fgZ7 );
743                 tag->fLine = line51;
744                 
745                 // Build a region of interest for tracking station 4.
746                 tag->fChamber = kChamber7;
747                 tag->fRoi.Create(intercept, fgA7, fgB7);
748         }
749
750         // Make the request for clusters from station 4.
751         AliHLTFloat32_t left, right, bottom, top;
752         tag->fRoi.GetBoundaryBox(left, right, bottom, top);
753         RequestClusters(left, right, bottom, top, tag->fChamber, tag);
754 }
755
756
757 void AliHLTMUONMansoTrackerFSM::ProcessClusters()
758 {
759 // Process clusters that have been received.
760 // This is called once all clusters have been found.
761
762         DebugTrace("ProcessClusters...");
763         
764         // Check if the cluster point list on station 4 is empty.
765         // If it is then we have not found any tracks.
766         fFoundPoint = fSt4points.First();
767         if (fFoundPoint == fSt4points.End())
768         {
769                 NoTrackFound();
770                 return;
771         }
772         
773         fSt5rec = fSt5data.First();
774         if (fSt5rec != fSt5data.End())
775         {
776                 // Only look at station 5 data records that are for the found chamber number.
777                 // Note: either we only have chamber 8 data or we have chamber 7 data followed
778                 // by chamber 8 data.
779                 // Thus if we hit records that we are not interested in already then the list
780                 // contains no interesting data and we can signal no track found.
781                 if (fSt5rec->fTag.fChamber != fSt4chamber)
782                 {
783                         NoTrackFound();
784                         return;
785                 }
786                  
787                 // For all combinations of cluster point pairs from station 4 and 5
788                 // signal a found track:
789                 do
790                 {
791                         DebugTrace("\tfSt5rec->fTag.chamber = " << fSt5rec->fTag.fChamber
792                                 << " , fSt4chamber = " << fSt4chamber
793                         );
794
795                         for (fFoundPoint = fSt4points.First(); fFoundPoint != fSt4points.End(); fFoundPoint++)
796                         {
797                                 if (fFoundPoint->fSt5tag == &fSt5rec->fTag)
798                                         FoundTrack();
799                         }
800
801                         fSt5rec++;  // Get next station 5 cluster point.
802                 } while (fSt5rec != fSt5data.End() && fSt5rec->fTag.fChamber == fSt4chamber);
803         }
804         else
805                 NoTrackFound();
806 }
807