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