Line data Source code
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 "AliHLTMUONTriggerRecordsBlockStruct.h"
34 : #include "AliHLTMUONMansoTracksBlockStruct.h"
35 : #include "AliHLTMUONMansoCandidatesBlockStruct.h"
36 : #include <cmath>
37 :
38 :
39 : #ifdef DEBUG
40 : #include <ostream>
41 : namespace
42 : {
43 :
44 : std::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;
53 : default: os << "FAULT!!";
54 : }
55 : return os;
56 : }
57 :
58 : std::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;
68 : default: os << "FAULT!!";
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
82 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA7 = 0.016f;
83 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB7 = 2.0f;
84 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA8 = 0.016f;
85 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB8 = 2.0f;
86 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA9 = 0.020f;
87 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB9 = 3.0f;
88 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA10 = 0.020f;
89 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB10 = 3.0f;
90 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ7 = -1274.5f;
91 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ8 = -1305.5f;
92 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ9 = -1408.6f;
93 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ10 = -1439.6f;
94 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ11 = -1603.5f;
95 : AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ13 = -1703.5f;
96 :
97 :
98 : void AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::Create(
99 : AliHLTMUONRecHitStruct p, AliHLTFloat32_t a, AliHLTFloat32_t b
100 : )
101 : {
102 : // Creates a region of interest specific to the Manso algorithm from a point and
103 : // two Manso specific parameters.
104 :
105 0 : fCentre = p;
106 : // Compute the radius Rp
107 0 : AliHLTFloat32_t rp = (AliHLTFloat32_t) sqrt( p.fX * p.fX + p.fY * p.fY );
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 0 : fRs = a * rp + b;
117 0 : }
118 :
119 :
120 : bool AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::Contains(AliHLTMUONRecHitStruct p) const
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.
125 0 : register AliHLTFloat32_t lx = fCentre.fX - p.fX;
126 0 : register AliHLTFloat32_t ly = fCentre.fY - p.fY;
127 0 : 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 0 : return r <= fRs;
132 : }
133 :
134 :
135 : void AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::GetBoundaryBox(
136 : AliHLTFloat32_t& left, AliHLTFloat32_t& right,
137 : AliHLTFloat32_t& bottom, AliHLTFloat32_t& top
138 : ) const
139 : {
140 : // Works out the smallest boundary box that will contain the region of interest.
141 :
142 0 : left = fCentre.fX - fRs;
143 0 : right = fCentre.fX + fRs;
144 0 : bottom = fCentre.fY - fRs;
145 0 : top = fCentre.fY + fRs;
146 0 : }
147 :
148 :
149 : AliHLTMUONMansoTrackerFSM::AliVertex::AliVertex(
150 : AliHLTFloat32_t x, AliHLTFloat32_t y, AliHLTFloat32_t z
151 : )
152 0 : : fX(x), fY(y), fZ(z)
153 0 : {
154 : // Constructor for vertex.
155 0 : }
156 :
157 :
158 : AliHLTMUONMansoTrackerFSM::AliVertex::AliVertex(AliHLTMUONRecHitStruct xy, AliHLTFloat32_t z)
159 0 : : fX(xy.fX), fY(xy.fY), fZ(z)
160 0 : {
161 : // Construct vertex from a point on the XY plane and z coordinate.
162 0 : }
163 :
164 :
165 : AliHLTMUONMansoTrackerFSM::AliLine::AliLine(
166 : AliHLTFloat32_t ax, AliHLTFloat32_t ay, AliHLTFloat32_t az,
167 : AliHLTFloat32_t bx, AliHLTFloat32_t by, AliHLTFloat32_t bz
168 : ) :
169 0 : fMx(ax - bx),
170 0 : fMy(ay - by),
171 0 : fMz(az - bz),
172 0 : fCx(bx),
173 0 : fCy(by),
174 0 : fCz(bz)
175 0 : {
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)
179 0 : }
180 :
181 :
182 : AliHLTMUONMansoTrackerFSM::AliLine::AliLine(AliVertex a, AliVertex b) :
183 0 : fMx(a.X() - b.X()),
184 0 : fMy(a.Y() - b.Y()),
185 0 : fMz(a.Z() - b.Z()),
186 0 : fCx(b.X()),
187 0 : fCy(b.Y()),
188 0 : fCz(b.Z())
189 0 : {
190 : // Contruct a line to go through two vertices a and b.
191 0 : }
192 :
193 :
194 : AliHLTMUONRecHitStruct AliHLTMUONMansoTrackerFSM::AliLine::FindIntersectWithXYPlain(
195 : AliHLTFloat32_t z
196 : ) const
197 : {
198 : // Find the point of intersection of the line and the XY plane at z.
199 :
200 : AliHLTFloat32_t t;
201 0 : if (fMz != 0) // Should not have a ray perpendicular to the beam axis.
202 0 : t = (z - fCz) / fMz;
203 : else
204 : t = 0;
205 : AliHLTMUONRecHitStruct p;
206 : p.fFlags = 0;
207 0 : p.fX = fMx*t + fCx;
208 0 : p.fY = fMy*t + fCy;
209 0 : p.fZ = z;
210 : return p;
211 0 : }
212 :
213 :
214 : AliHLTMUONMansoTrackerFSM::AliHLTMUONMansoTrackerFSM() :
215 0 : AliHLTLogging(),
216 0 : fCallback(NULL),
217 0 : fSm4state(kSM4Idle),
218 0 : fSm5state(kSM5Idle),
219 0 : fRequestsCompleted(0),
220 0 : fSt4chamber(kChamber1),
221 0 : fV1(),
222 0 : fMc1(),
223 0 : fSt5data(),
224 0 : fSt4points(),
225 0 : fSt5rec(),
226 0 : fFoundPoint(),
227 0 : fTriggerId(-1),
228 0 : fTrackId(0),
229 0 : fMakeCandidates(false),
230 0 : fCandidatesCount(0),
231 0 : fCandidatesSize(0),
232 0 : fCandidates(NULL)
233 0 : {
234 : // Default constructor
235 0 : }
236 :
237 :
238 : AliHLTMUONMansoTrackerFSM::~AliHLTMUONMansoTrackerFSM()
239 0 : {
240 : // Default destructor cleans up any allocated memory.
241 :
242 0 : if (fCandidates != NULL) delete [] fCandidates;
243 0 : }
244 :
245 :
246 : void 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 0 : fTriggerId = trigger.fId;
254 :
255 : // Set Z coordinates of ideal point on trigger track to be nominal
256 : // chamber 11 and 13 positions.
257 0 : AliHLTMUONCalculations::IdealZ1(fgZ11);
258 0 : AliHLTMUONCalculations::IdealZ2(fgZ13);
259 :
260 0 : if (not AliHLTMUONCalculations::FitLineToTriggerRecord(trigger))
261 : {
262 0 : NoTrackFound();
263 0 : return;
264 : }
265 0 : fV1 = AliVertex(
266 0 : AliHLTMUONCalculations::IdealX1(),
267 0 : AliHLTMUONCalculations::IdealY1(),
268 0 : AliHLTMUONCalculations::IdealZ1()
269 : );
270 0 : AliVertex v2 = AliVertex(
271 0 : AliHLTMUONCalculations::IdealX2(),
272 0 : AliHLTMUONCalculations::IdealY2(),
273 0 : AliHLTMUONCalculations::IdealZ2()
274 : );
275 :
276 : DebugTrace("Using fV1 = {x = " << fV1.X() << ", y = " << fV1.Y() << ", " << fV1.Z() << "}");
277 : DebugTrace("Using v2 = {x = " << v2.X() << ", y = " << v2.Y() << ", " << v2.Z() << "}");
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 0 : fMc1.fLine = AliLine(fV1, v2);
282 0 : AliHLTMUONRecHitStruct p10 = fMc1.fLine.FindIntersectWithXYPlain( fgZ10 );
283 :
284 : // Build a region of interest for tracking station 5 (chamber 10).
285 : // Remember the parameters a and b are station specific.
286 0 : fMc1.fChamber = kChamber10;
287 0 : 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 0 : fSm5state = kWaitChamber10;
293 :
294 0 : if (fMakeCandidates)
295 : {
296 0 : fMc1.fCandidate = AddTrackCandidate();
297 0 : if (fMc1.fCandidate != NULL)
298 : {
299 0 : *fMc1.fCandidate = AliHLTMUONConstants::NilMansoCandidateStruct();
300 0 : fMc1.fCandidate->fTrack.fId = -1;
301 0 : fMc1.fCandidate->fTrack.fTrigRec = fTriggerId;
302 0 : fMc1.fCandidate->fTrack.fChi2 = -1;
303 0 : fMc1.fCandidate->fZmiddle = AliHLTMUONCalculations::Zf();
304 0 : fMc1.fCandidate->fBl = AliHLTMUONCalculations::QBL();
305 0 : fMc1.fCandidate->fRoI[3].fX = fMc1.fRoi.Centre().fX;
306 0 : fMc1.fCandidate->fRoI[3].fY = fMc1.fRoi.Centre().fY;
307 0 : fMc1.fCandidate->fRoI[3].fZ = fMc1.fRoi.Centre().fZ;
308 0 : fMc1.fCandidate->fRoI[3].fRadius = fMc1.fRoi.Radius();
309 0 : }
310 : }
311 :
312 0 : AliHLTFloat32_t left, right, bottom, top;
313 0 : fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
314 0 : RequestClusters(left, right, bottom, top, kChamber10, &fMc1);
315 0 : }
316 :
317 :
318 : void AliHLTMUONMansoTrackerFSM::ReturnClusters(
319 : void* tag, const AliHLTMUONRecHitStruct* clusters,
320 : AliHLTUInt32_t count
321 : )
322 : {
323 : // Implementation of AliHLTMUONMansoTrackerFSM::ReturnClusters.
324 :
325 0 : assert( count > 0 );
326 0 : assert( clusters != NULL );
327 :
328 0 : 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 0 : switch (data->fChamber)
336 : {
337 0 : case kChamber7: ReceiveClustersChamber7(clusters, count, data); break;
338 0 : case kChamber8: ReceiveClustersChamber8(clusters, count, data); break;
339 0 : case kChamber9: ReceiveClustersChamber9(clusters, count); break;
340 0 : case kChamber10: ReceiveClustersChamber10(clusters, count); break;
341 : default:
342 : // Error
343 : DebugTrace("ERROR: Got tag with an invalid value: " << data->fChamber);
344 : }
345 0 : }
346 :
347 :
348 : void AliHLTMUONMansoTrackerFSM::EndOfClusters(void* tag)
349 : {
350 : // Implementation of AliHLTMUONMansoTrackerFSM::EndOfClusters.
351 :
352 0 : AliTagData* data = (AliTagData*)tag;
353 : DebugTrace("Got AliHLTMUONMansoTrackerFSM::EndOfClusters(chamber = " << data->fChamber << ")");
354 : DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
355 :
356 0 : switch (data->fChamber)
357 : {
358 0 : case kChamber7: EndOfClustersChamber7(); break;
359 0 : case kChamber8: EndOfClustersChamber8(); break;
360 0 : case kChamber9: EndOfClustersChamber9(); break;
361 0 : case kChamber10: EndOfClustersChamber10(); break;
362 : default:
363 : // Error
364 : DebugTrace("ERROR: Got tag with an invalid value: " << data->fChamber);
365 : }
366 0 : }
367 :
368 :
369 : bool AliHLTMUONMansoTrackerFSM::FillTrackData(AliHLTMUONMansoTrackStruct& track)
370 : {
371 : // Implementation of AliHLTMUONMansoTrackerFSM::FillTrackData
372 :
373 : DebugTrace("FillTrack: st5 = " << fSt5rec->fClusterPoint << ", st4 = " << fFoundPoint->fClusterPoint);
374 :
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.
377 : // 0x100 is forced for the Manso component.
378 0 : track.fId = (fTrackId << 10) | 0x100 | (fTriggerId & 0xFF);
379 :
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 0 : fTrackId = (fTrackId + 1) & 0x001FFFFF;
384 :
385 0 : track.fTrigRec = fTriggerId;
386 :
387 0 : AliHLTFloat32_t x1 = fFoundPoint->fClusterPoint.fX;
388 0 : AliHLTFloat32_t y1 = fFoundPoint->fClusterPoint.fY;
389 0 : AliHLTFloat32_t z1 = fFoundPoint->fClusterPoint.fZ;
390 0 : AliHLTFloat32_t y2 = fSt5rec->fClusterPoint.fY;
391 0 : AliHLTFloat32_t z2 = fSt5rec->fClusterPoint.fZ;
392 :
393 0 : bool calculated = AliHLTMUONCalculations::ComputeMomentum(x1, y1, y2, z1, z2);
394 :
395 0 : track.fPx = AliHLTMUONCalculations::Px();
396 0 : track.fPy = AliHLTMUONCalculations::Py();
397 0 : track.fPz = AliHLTMUONCalculations::Pz();
398 : DebugTrace("Calculated Px = " << track.fPx << ", Py = " << track.fPy
399 : << ", Pz = " << track.fPx
400 : );
401 : DebugTrace("\tusing x1 = " << x1 << " , y1 = " << y1 << " , y2 = " << y2
402 : << " , z1 = " << z1 << " , z2 = " << z2
403 : );
404 :
405 0 : track.fChi2 = 0;
406 :
407 0 : 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.
410 0 : if (fSt4chamber == kChamber8)
411 : {
412 0 : track.fHit[0] = AliHLTMUONConstants::NilRecHitStruct();
413 0 : hitset[0] = false;
414 0 : track.fHit[1] = fFoundPoint->fClusterPoint;
415 0 : hitset[1] = true;
416 0 : }
417 : else
418 : {
419 0 : track.fHit[0] = fFoundPoint->fClusterPoint;
420 0 : hitset[0] = true;
421 0 : track.fHit[1] = AliHLTMUONConstants::NilRecHitStruct();
422 0 : hitset[1] = false;
423 : }
424 0 : if (fMc1.fChamber == kChamber10)
425 : {
426 0 : track.fHit[2] = AliHLTMUONConstants::NilRecHitStruct();
427 0 : hitset[2] = false;
428 0 : track.fHit[3] = fSt5rec->fClusterPoint;
429 0 : hitset[3] = true;
430 0 : }
431 : else
432 : {
433 0 : track.fHit[2] = fSt5rec->fClusterPoint;
434 0 : hitset[2] = true;
435 0 : track.fHit[3] = AliHLTMUONConstants::NilRecHitStruct();
436 0 : hitset[3] = false;
437 : }
438 :
439 0 : track.fFlags = AliHLTMUONUtils::PackMansoTrackFlags(
440 0 : AliHLTMUONCalculations::Sign(), hitset
441 : );
442 :
443 0 : if (fMakeCandidates)
444 : {
445 0 : AliHLTMUONMansoCandidateStruct* candidate = fSt5rec->fTag.fCandidate;
446 0 : if (candidate != NULL)
447 : {
448 0 : candidate->fTrack = track;
449 0 : }
450 0 : }
451 :
452 0 : return calculated;
453 0 : }
454 :
455 :
456 : void AliHLTMUONMansoTrackerFSM::Reset()
457 : {
458 : // Implementation of AliHLTMUONMansoTrackerFSM::Reset
459 :
460 : DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
461 0 : fSt5data.Clear();
462 0 : fSt4points.Clear();
463 0 : fSm4state = kSM4Idle;
464 0 : fSm5state = kSM5Idle;
465 0 : fRequestsCompleted = 0;
466 0 : fTriggerId = -1;
467 0 : }
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 :
479 : void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7(
480 : const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count,
481 : const AliTagData* data
482 : )
483 : {
484 : // State change method for Station 4 state machine.
485 :
486 0 : switch (fSm4state)
487 : {
488 : case kWaitChamber7:
489 : // We switch state below.
490 :
491 : case kWaitMoreChamber7:
492 0 : for (AliHLTUInt32_t j = 0; j < count; j++)
493 : {
494 0 : AliHLTMUONRecHitStruct cluster = clusters[j];
495 : // Check that the cluster actually is in our region of interest on station 4.
496 0 : if ( data->fRoi.Contains(cluster) )
497 : {
498 : // Go to next wait state only if we actually found anything in the RoI.
499 0 : fSm4state = kWaitMoreChamber7;
500 :
501 : DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 7.");
502 0 : AliStation4Data* newdata = fSt4points.Add();
503 0 : newdata->fClusterPoint = cluster;
504 0 : newdata->fSt5tag = data;
505 0 : }
506 : }
507 0 : break;
508 :
509 : default:
510 : DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7!");
511 : }
512 0 : }
513 :
514 :
515 : void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8(
516 : const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count,
517 : const AliTagData* data
518 : )
519 : {
520 : // State change method for Station 4 state machine.
521 :
522 0 : switch (fSm4state)
523 : {
524 : case kWaitChamber8:
525 0 : fSt4chamber = kChamber8;
526 :
527 : case kWaitMoreChamber8:
528 0 : for (AliHLTUInt32_t j = 0; j < count; j++)
529 : {
530 0 : AliHLTMUONRecHitStruct cluster = clusters[j];
531 : // Check that the cluster actually is in our region of interest on station 4.
532 0 : if ( data->fRoi.Contains(cluster) )
533 : {
534 : // Go to next wait state only if we actually found anything in the RoI.
535 0 : fSm4state = kWaitMoreChamber8;
536 :
537 : DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 8.");
538 0 : AliStation4Data* newdata = fSt4points.Add();
539 0 : newdata->fClusterPoint = cluster;
540 0 : newdata->fSt5tag = data;
541 0 : }
542 : }
543 0 : break;
544 :
545 : default:
546 : DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8!");
547 : }
548 0 : }
549 :
550 :
551 : void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9(
552 : const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count
553 : )
554 : {
555 : // State change method for Station 5 state machine.
556 :
557 0 : switch (fSm5state)
558 : {
559 : case kWaitChamber9:
560 0 : fSm4state = kWaitChamber8; // Start SM4.
561 :
562 : case kWaitMoreChamber9:
563 0 : for (AliHLTUInt32_t j = 0; j < count; j++)
564 : {
565 0 : AliHLTMUONRecHitStruct cluster = clusters[j];
566 : // Check that the cluster actually is in our region of interest on station 5.
567 0 : if ( fMc1.fRoi.Contains(cluster) )
568 : {
569 : // Go to next wait state only if we actually found anything in the RoI.
570 0 : fSm5state = kWaitMoreChamber9;
571 :
572 : DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 9.");
573 0 : AliStation5Data* data = fSt5data.Add();
574 0 : data->fClusterPoint = cluster;
575 0 : ProjectToStation4(data, fgZ9, 2); // This adds a new request for station 4.
576 0 : }
577 : }
578 0 : break;
579 :
580 : default:
581 : DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9!");
582 : }
583 0 : }
584 :
585 :
586 : void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10(
587 : const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count
588 : )
589 : {
590 : // State change method for Station 5 state machine.
591 :
592 0 : switch (fSm5state)
593 : {
594 : case kWaitChamber10:
595 0 : fSm4state = kWaitChamber8; // Start SM4.
596 :
597 : case kWaitMoreChamber10:
598 0 : for (AliHLTUInt32_t j = 0; j < count; j++)
599 : {
600 0 : AliHLTMUONRecHitStruct cluster = clusters[j];
601 : // Check that the cluster actually is in our region of interest on station 5.
602 0 : if ( fMc1.fRoi.Contains(cluster) )
603 : {
604 : // Go to next wait state only if we actually found anything in the RoI.
605 0 : fSm5state = kWaitMoreChamber10;
606 :
607 : DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 10.");
608 0 : AliStation5Data* data = fSt5data.Add();
609 0 : data->fClusterPoint = cluster;
610 0 : ProjectToStation4(data, fgZ10, 3); // This adds a new request for station 4.
611 0 : }
612 : }
613 0 : break;
614 :
615 : default:
616 : DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10!");
617 : }
618 0 : }
619 :
620 :
621 : void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7()
622 : {
623 : // State change method for Station 4 state machine.
624 :
625 0 : fRequestsCompleted++; // Increment the number of requests completed for station 4.
626 : DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
627 :
628 0 : 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 0 : if (fSm5state == kSM5Done) NoTrackFound();
634 : break;
635 :
636 : case kWaitMoreChamber7:
637 0 : if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
638 0 : ProcessClusters();
639 : break;
640 :
641 : default:
642 : DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7!");
643 : }
644 0 : }
645 :
646 :
647 : void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8()
648 : {
649 : // State change method for Station 4 state machine.
650 :
651 0 : fRequestsCompleted++; // Increment the number of requests completed for station 4.
652 : DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
653 :
654 0 : 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 0 : fSm4state = kWaitChamber7;
663 0 : 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:
667 0 : AliHLTUInt32_t reqlistsize = fSt5data.Count();
668 : DebugTrace("Re-requesting clusters from chamber 7... reqlistsize = " << reqlistsize);
669 :
670 0 : Station5List::Iterator rec = fSt5data.First();
671 0 : for (AliHLTUInt32_t i = 0; i < reqlistsize; i++, rec++)
672 : {
673 : // Need to create a new st5 data block for the request.
674 0 : AliStation5Data* data = fSt5data.Add();
675 0 : data->fClusterPoint = rec->fClusterPoint;
676 0 : data->fTag.fLine = rec->fTag.fLine;
677 0 : data->fTag.fCandidate = rec->fTag.fCandidate;
678 :
679 : // Rebuild a region of interest for chamber 7.
680 : // Remember the parameters a and b are station specific.
681 0 : AliHLTMUONRecHitStruct p7 = data->fTag.fLine.FindIntersectWithXYPlain( fgZ7 );
682 0 : data->fTag.fChamber = kChamber7;
683 0 : data->fTag.fRoi.Create(p7, fgA7, fgB7);
684 :
685 0 : if (fMakeCandidates and data->fTag.fCandidate != NULL)
686 : {
687 0 : data->fTag.fCandidate->fRoI[0].fX = data->fTag.fRoi.Centre().fX;
688 0 : data->fTag.fCandidate->fRoI[0].fY = data->fTag.fRoi.Centre().fY;
689 0 : data->fTag.fCandidate->fRoI[0].fZ = data->fTag.fRoi.Centre().fZ;
690 0 : data->fTag.fCandidate->fRoI[0].fRadius = data->fTag.fRoi.Radius();
691 0 : }
692 :
693 0 : AliHLTFloat32_t left, right, bottom, top;
694 0 : data->fTag.fRoi.GetBoundaryBox(left, right, bottom, top);
695 : // Make request for chamber 7 data.
696 0 : RequestClusters(left, right, bottom, top, kChamber7, &data->fTag);
697 0 : }
698 0 : }
699 0 : break;
700 :
701 : case kWaitMoreChamber8:
702 0 : if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
703 0 : ProcessClusters();
704 : break;
705 :
706 : default:
707 : DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8!");
708 : }
709 0 : }
710 :
711 :
712 : void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9()
713 : {
714 : // State change method for Station 5 state machine.
715 :
716 0 : switch (fSm5state)
717 : {
718 : case kWaitChamber9:
719 0 : fSm5state = kSM5Done;
720 0 : EndOfClusterRequests();
721 0 : NoTrackFound();
722 0 : break;
723 :
724 : case kWaitMoreChamber9:
725 0 : fSm5state = kSM5Done;
726 0 : EndOfClusterRequests();
727 0 : if (fRequestsCompleted == fSt5data.Count())
728 0 : ProcessClusters();
729 : break;
730 :
731 : default:
732 : DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9!");
733 : }
734 0 : }
735 :
736 :
737 : void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10()
738 : {
739 : // State change method for Station 5 state machine.
740 :
741 0 : switch (fSm5state)
742 : {
743 : case kWaitChamber10:
744 : {
745 0 : fSm5state = kWaitChamber9;
746 :
747 : // No clusters found on chamber 10 so we need to make a request for
748 : // clusters from chamber 9:
749 0 : AliHLTMUONRecHitStruct p9 = fMc1.fLine.FindIntersectWithXYPlain( fgZ9 );
750 :
751 : // Build a region of interest for tracking station 5 (chamber 9).
752 : // Remember the parameters a and b are station specific.
753 0 : fMc1.fChamber = kChamber9;
754 0 : fMc1.fRoi.Create(p9, fgA9, fgB9);
755 :
756 0 : if (fMakeCandidates and fMc1.fCandidate != NULL)
757 : {
758 0 : fMc1.fCandidate->fRoI[2].fX = fMc1.fRoi.Centre().fX;
759 0 : fMc1.fCandidate->fRoI[2].fY = fMc1.fRoi.Centre().fY;
760 0 : fMc1.fCandidate->fRoI[2].fZ = fMc1.fRoi.Centre().fZ;
761 0 : fMc1.fCandidate->fRoI[2].fRadius = fMc1.fRoi.Radius();
762 0 : }
763 :
764 0 : AliHLTFloat32_t left, right, bottom, top;
765 0 : fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
766 0 : RequestClusters(left, right, bottom, top, kChamber9, &fMc1);
767 0 : }
768 0 : break;
769 :
770 : case kWaitMoreChamber10:
771 0 : fSm5state = kSM5Done;
772 0 : EndOfClusterRequests();
773 0 : if (fRequestsCompleted == fSt5data.Count())
774 0 : ProcessClusters();
775 : break;
776 :
777 : default:
778 : DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10!");
779 : }
780 0 : }
781 :
782 :
783 : void AliHLTMUONMansoTrackerFSM::ProjectToStation4(
784 : AliStation5Data* data, AliHLTFloat32_t station5z, AliHLTUInt32_t chamberSt5
785 : )
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.
791 0 : assert( fSm4state == kWaitChamber8
792 : || fSm4state == kWaitMoreChamber8
793 : || fSm4state == kWaitChamber7
794 : || fSm4state == kWaitMoreChamber7
795 : );
796 0 : assert( chamberSt5 == 2 or chamberSt5 == 3 );
797 0 : AliTagData* tag = &data->fTag;
798 : int chamber = 0;
799 0 : 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 0 : AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
804 0 : AliHLTMUONRecHitStruct intercept = line51.FindIntersectWithXYPlain( fgZ8 );
805 0 : tag->fLine = line51;
806 :
807 : // Build a region of interest for tracking station 4.
808 0 : tag->fChamber = kChamber8;
809 0 : tag->fRoi.Create(intercept, fgA8, fgB8);
810 : chamber = 1;
811 0 : }
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 0 : AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
817 0 : AliHLTMUONRecHitStruct intercept = line51.FindIntersectWithXYPlain( fgZ7 );
818 0 : tag->fLine = line51;
819 :
820 : // Build a region of interest for tracking station 4.
821 0 : tag->fChamber = kChamber7;
822 0 : tag->fRoi.Create(intercept, fgA7, fgB7);
823 : chamber = 0;
824 0 : }
825 :
826 0 : 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 0 : if (fMc1.fCandidate != NULL and
831 0 : fMc1.fCandidate->fTrack.fHit[chamberSt5] == AliHLTMUONConstants::NilRecHitStruct()
832 : )
833 : {
834 0 : tag->fCandidate = fMc1.fCandidate;
835 0 : }
836 : else
837 : {
838 0 : tag->fCandidate = AddTrackCandidate();
839 0 : if (tag->fCandidate != NULL and fMc1.fCandidate != NULL) *tag->fCandidate = *fMc1.fCandidate;
840 : }
841 : // Now fill the cluster point found on station 5 and RoI on station 4.
842 0 : if (tag->fCandidate != NULL)
843 : {
844 0 : tag->fCandidate->fTrack.fHit[chamberSt5] = data->fClusterPoint;
845 0 : tag->fCandidate->fRoI[chamber].fX = tag->fRoi.Centre().fX;
846 0 : tag->fCandidate->fRoI[chamber].fY = tag->fRoi.Centre().fY;
847 0 : tag->fCandidate->fRoI[chamber].fZ = tag->fRoi.Centre().fZ;
848 0 : tag->fCandidate->fRoI[chamber].fRadius = tag->fRoi.Radius();
849 0 : }
850 : }
851 :
852 : // Make the request for clusters from station 4.
853 0 : AliHLTFloat32_t left, right, bottom, top;
854 0 : tag->fRoi.GetBoundaryBox(left, right, bottom, top);
855 0 : RequestClusters(left, right, bottom, top, tag->fChamber, tag);
856 0 : }
857 :
858 :
859 : void 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 0 : fFoundPoint = fSt4points.First();
869 0 : if (fFoundPoint == fSt4points.End())
870 : {
871 0 : NoTrackFound();
872 0 : return;
873 : }
874 :
875 0 : fSt5rec = fSt5data.First();
876 0 : 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 0 : if (fSt5rec->fTag.fChamber != fSt4chamber)
884 : {
885 0 : NoTrackFound();
886 0 : 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 0 : for (fFoundPoint = fSt4points.First(); fFoundPoint != fSt4points.End(); fFoundPoint++)
898 : {
899 0 : if (fFoundPoint->fSt5tag == &fSt5rec->fTag)
900 0 : FoundTrack();
901 : }
902 :
903 0 : fSt5rec++; // Get next station 5 cluster point.
904 0 : } while (fSt5rec != fSt5data.End() && fSt5rec->fTag.fChamber == fSt4chamber);
905 : }
906 : else
907 0 : NoTrackFound();
908 0 : }
909 :
910 :
911 : AliHLTMUONMansoCandidateStruct* 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 0 : if (fCandidates == NULL)
918 : {
919 : try
920 : {
921 0 : fCandidates = new AliHLTMUONMansoCandidateStruct[1024];
922 0 : }
923 : catch (...)
924 : {
925 0 : HLTError("Could not allocate buffer space for Manso track candidates.");
926 : return NULL;
927 0 : }
928 0 : fCandidatesSize = 1024;
929 0 : }
930 0 : else if (fCandidatesCount >= fCandidatesSize)
931 : {
932 : AliHLTMUONMansoCandidateStruct* newbuf = NULL;
933 : try
934 : {
935 0 : newbuf = new AliHLTMUONMansoCandidateStruct[fCandidatesSize*2];
936 0 : }
937 : catch (...)
938 : {
939 0 : HLTError("Could not allocate more buffer space for Manso track candidates.");
940 : return NULL;
941 0 : }
942 0 : for (AliHLTUInt32_t i = 0; i < fCandidatesSize; ++i) newbuf[i] = fCandidates[i];
943 0 : delete [] fCandidates;
944 0 : fCandidates = newbuf;
945 0 : fCandidatesSize = fCandidatesSize*2;
946 0 : }
947 :
948 0 : return &fCandidates[fCandidatesCount++];
949 0 : }
|