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