1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Artur Szostak <artursz@iafrica.com> *
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 **************************************************************************/
20 /// @file AliHLTMUONMansoTrackerFSM.cxx
21 /// @author Artur Szostak <artursz@iafrica.com>
23 /// @brief Implementation of AliHLTMUONMansoTrackerFSM class.
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.
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"
44 std::ostream& operator << (std::ostream& os, AliHLTMUONMansoTrackerFSM::StatesSM4 state)
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!!";
58 std::ostream& operator << (std::ostream& os, AliHLTMUONMansoTrackerFSM::StatesSM5 state)
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!!";
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;
98 void AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::Create(
99 AliHLTMUONRecHitStruct p, AliHLTFloat32_t a, AliHLTFloat32_t b
102 // Creates a region of interest specific to the Manso algorithm from a point and
103 // two Manso specific parameters.
106 // Compute the radius Rp
107 AliHLTFloat32_t rp = (AliHLTFloat32_t) sqrt( p.fX * p.fX + p.fY * p.fY );
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
115 // given on page 3 section 4.
120 bool AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::Contains(AliHLTMUONRecHitStruct p) const
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 register AliHLTFloat32_t lx = fCentre.fX - p.fX;
126 register AliHLTFloat32_t ly = fCentre.fY - p.fY;
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
135 void AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::GetBoundaryBox(
136 AliHLTFloat32_t& left, AliHLTFloat32_t& right,
137 AliHLTFloat32_t& bottom, AliHLTFloat32_t& top
140 // Works out the smallest boundary box that will contain the region of interest.
142 left = fCentre.fX - fRs;
143 right = fCentre.fX + fRs;
144 bottom = fCentre.fY - fRs;
145 top = fCentre.fY + fRs;
149 AliHLTMUONMansoTrackerFSM::AliVertex::AliVertex(
150 AliHLTFloat32_t x, AliHLTFloat32_t y, AliHLTFloat32_t z
152 : fX(x), fY(y), fZ(z)
154 // Constructor for vertex.
158 AliHLTMUONMansoTrackerFSM::AliVertex::AliVertex(AliHLTMUONRecHitStruct xy, AliHLTFloat32_t z)
159 : fX(xy.fX), fY(xy.fY), fZ(z)
161 // Construct vertex from a point on the XY plane and z coordinate.
165 AliHLTMUONMansoTrackerFSM::AliLine::AliLine(
166 AliHLTFloat32_t ax, AliHLTFloat32_t ay, AliHLTFloat32_t az,
167 AliHLTFloat32_t bx, AliHLTFloat32_t by, AliHLTFloat32_t bz
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)
182 AliHLTMUONMansoTrackerFSM::AliLine::AliLine(AliVertex a, AliVertex b) :
190 // Contruct a line to go through two vertices a and b.
194 AliHLTMUONRecHitStruct AliHLTMUONMansoTrackerFSM::AliLine::FindIntersectWithXYPlain(
198 // Find the point of intersection of the line and the XY plane at z.
201 if (fMz != 0) // Should not have a ray perpendicular to the beam axis.
205 AliHLTMUONRecHitStruct p;
214 AliHLTMUONMansoTrackerFSM::AliHLTMUONMansoTrackerFSM() :
219 fRequestsCompleted(0),
220 fSt4chamber(kChamber1),
229 fMakeCandidates(false),
234 // Default constructor
238 AliHLTMUONMansoTrackerFSM::~AliHLTMUONMansoTrackerFSM()
240 // Default destructor cleans up any allocated memory.
242 if (fCandidates != NULL) delete [] fCandidates;
246 void AliHLTMUONMansoTrackerFSM::FindTrack(const AliHLTMUONTriggerRecordStruct& trigger)
248 // Tries to find the track from the trigger seed.
250 DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
251 DebugTrace("Processing trigger with ID = " << trigger.fId);
253 fTriggerId = trigger.fId;
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);
260 if (not AliHLTMUONCalculations::FitLineToTriggerRecord(trigger))
266 AliHLTMUONCalculations::IdealX1(),
267 AliHLTMUONCalculations::IdealY1(),
268 AliHLTMUONCalculations::IdealZ1()
270 AliVertex v2 = AliVertex(
271 AliHLTMUONCalculations::IdealX2(),
272 AliHLTMUONCalculations::IdealY2(),
273 AliHLTMUONCalculations::IdealZ2()
276 DebugTrace("Using fV1 = {x = " << fV1.X() << ", y = " << fV1.Y() << ", " << fV1.Z() << "}");
277 DebugTrace("Using v2 = {x = " << v2.X() << ", y = " << v2.Y() << ", " << v2.Z() << "}");
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);
282 AliHLTMUONRecHitStruct p10 = fMc1.fLine.FindIntersectWithXYPlain( fgZ10 );
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);
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;
296 fMc1.fCandidate = AddTrackCandidate();
297 if (fMc1.fCandidate != NULL)
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();
312 AliHLTFloat32_t left, right, bottom, top;
313 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
314 RequestClusters(left, right, bottom, top, kChamber10, &fMc1);
318 void AliHLTMUONMansoTrackerFSM::ReturnClusters(
319 void* tag, const AliHLTMUONRecHitStruct* clusters,
323 // Implementation of AliHLTMUONMansoTrackerFSM::ReturnClusters.
326 assert( clusters != NULL );
328 AliTagData* data = (AliTagData*)tag;
329 DebugTrace("Got AliHLTMUONMansoTrackerFSM::ReturnClusters(tag = " << tag
330 << ", chamber = " << data->fChamber
331 << ", clusters = " << clusters << ", count = " << count << ")"
333 DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
335 switch (data->fChamber)
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;
343 DebugTrace("ERROR: Got tag with an invalid value: " << data->fChamber);
348 void AliHLTMUONMansoTrackerFSM::EndOfClusters(void* tag)
350 // Implementation of AliHLTMUONMansoTrackerFSM::EndOfClusters.
352 AliTagData* data = (AliTagData*)tag;
353 DebugTrace("Got AliHLTMUONMansoTrackerFSM::EndOfClusters(chamber = " << data->fChamber << ")");
354 DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
356 switch (data->fChamber)
358 case kChamber7: EndOfClustersChamber7(); break;
359 case kChamber8: EndOfClustersChamber8(); break;
360 case kChamber9: EndOfClustersChamber9(); break;
361 case kChamber10: EndOfClustersChamber10(); break;
364 DebugTrace("ERROR: Got tag with an invalid value: " << data->fChamber);
369 bool AliHLTMUONMansoTrackerFSM::FillTrackData(AliHLTMUONMansoTrackStruct& track)
371 // Implementation of AliHLTMUONMansoTrackerFSM::FillTrackData
373 DebugTrace("FillTrack: st5 = " << fSt5rec->fClusterPoint << ", st4 = " << fFoundPoint->fClusterPoint);
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 track.fId = (fTrackId << 10) | 0x100 | (fTriggerId & 0xFF);
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;
385 track.fTrigRec = fTriggerId;
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;
393 bool calculated = AliHLTMUONCalculations::ComputeMomentum(x1, y1, y2, z1, z2);
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
401 DebugTrace("\tusing x1 = " << x1 << " , y1 = " << y1 << " , y2 = " << y2
402 << " , z1 = " << z1 << " , z2 = " << z2
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 if (fSt4chamber == kChamber8)
412 track.fHit[0] = AliHLTMUONConstants::NilRecHitStruct();
414 track.fHit[1] = fFoundPoint->fClusterPoint;
419 track.fHit[0] = fFoundPoint->fClusterPoint;
421 track.fHit[1] = AliHLTMUONConstants::NilRecHitStruct();
424 if (fMc1.fChamber == kChamber10)
426 track.fHit[2] = AliHLTMUONConstants::NilRecHitStruct();
428 track.fHit[3] = fSt5rec->fClusterPoint;
433 track.fHit[2] = fSt5rec->fClusterPoint;
435 track.fHit[3] = AliHLTMUONConstants::NilRecHitStruct();
439 track.fFlags = AliHLTMUONUtils::PackMansoTrackFlags(
440 AliHLTMUONCalculations::Sign(), hitset
445 AliHLTMUONMansoCandidateStruct* candidate = fSt5rec->fTag.fCandidate;
446 if (candidate != NULL)
448 candidate->fTrack = track;
456 void AliHLTMUONMansoTrackerFSM::Reset()
458 // Implementation of AliHLTMUONMansoTrackerFSM::Reset
460 DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
463 fSm4state = kSM4Idle;
464 fSm5state = kSM5Idle;
465 fRequestsCompleted = 0;
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.
479 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7(
480 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count,
481 const AliTagData* data
484 // State change method for Station 4 state machine.
489 // We switch state below.
491 case kWaitMoreChamber7:
492 for (AliHLTUInt32_t j = 0; j < count; j++)
494 AliHLTMUONRecHitStruct cluster = clusters[j];
495 // Check that the cluster actually is in our region of interest on station 4.
496 if ( data->fRoi.Contains(cluster) )
498 // Go to next wait state only if we actually found anything in the RoI.
499 fSm4state = kWaitMoreChamber7;
501 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 7.");
502 AliStation4Data* newdata = fSt4points.Add();
503 newdata->fClusterPoint = cluster;
504 newdata->fSt5tag = data;
510 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7!");
515 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8(
516 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count,
517 const AliTagData* data
520 // State change method for Station 4 state machine.
525 fSt4chamber = kChamber8;
527 case kWaitMoreChamber8:
528 for (AliHLTUInt32_t j = 0; j < count; j++)
530 AliHLTMUONRecHitStruct cluster = clusters[j];
531 // Check that the cluster actually is in our region of interest on station 4.
532 if ( data->fRoi.Contains(cluster) )
534 // Go to next wait state only if we actually found anything in the RoI.
535 fSm4state = kWaitMoreChamber8;
537 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 8.");
538 AliStation4Data* newdata = fSt4points.Add();
539 newdata->fClusterPoint = cluster;
540 newdata->fSt5tag = data;
546 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8!");
551 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9(
552 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count
555 // State change method for Station 5 state machine.
560 fSm4state = kWaitChamber8; // Start SM4.
562 case kWaitMoreChamber9:
563 for (AliHLTUInt32_t j = 0; j < count; j++)
565 AliHLTMUONRecHitStruct cluster = clusters[j];
566 // Check that the cluster actually is in our region of interest on station 5.
567 if ( fMc1.fRoi.Contains(cluster) )
569 // Go to next wait state only if we actually found anything in the RoI.
570 fSm5state = kWaitMoreChamber9;
572 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 9.");
573 AliStation5Data* data = fSt5data.Add();
574 data->fClusterPoint = cluster;
575 ProjectToStation4(data, fgZ9, 2); // This adds a new request for station 4.
581 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9!");
586 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10(
587 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count
590 // State change method for Station 5 state machine.
595 fSm4state = kWaitChamber8; // Start SM4.
597 case kWaitMoreChamber10:
598 for (AliHLTUInt32_t j = 0; j < count; j++)
600 AliHLTMUONRecHitStruct cluster = clusters[j];
601 // Check that the cluster actually is in our region of interest on station 5.
602 if ( fMc1.fRoi.Contains(cluster) )
604 // Go to next wait state only if we actually found anything in the RoI.
605 fSm5state = kWaitMoreChamber10;
607 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 10.");
608 AliStation5Data* data = fSt5data.Add();
609 data->fClusterPoint = cluster;
610 ProjectToStation4(data, fgZ10, 3); // This adds a new request for station 4.
616 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10!");
621 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7()
623 // State change method for Station 4 state machine.
625 fRequestsCompleted++; // Increment the number of requests completed for station 4.
626 DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
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();
636 case kWaitMoreChamber7:
637 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
642 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7!");
647 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8()
649 // State change method for Station 4 state machine.
651 fRequestsCompleted++; // Increment the number of requests completed for station 4.
652 DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
657 // Ignore. The requests for chamber 8 are already re-requested below.
662 fSm4state = kWaitChamber7;
663 fSt4chamber = kChamber7;
665 // We need to resend the requests for chamber 8, but change the request
666 // to get data for chamber 7 instead:
667 AliHLTUInt32_t reqlistsize = fSt5data.Count();
668 DebugTrace("Re-requesting clusters from chamber 7... reqlistsize = " << reqlistsize);
670 Station5List::Iterator rec = fSt5data.First();
671 for (AliHLTUInt32_t i = 0; i < reqlistsize; i++, rec++)
673 // Need to create a new st5 data block for the request.
674 AliStation5Data* data = fSt5data.Add();
675 data->fClusterPoint = rec->fClusterPoint;
676 data->fTag.fLine = rec->fTag.fLine;
677 data->fTag.fCandidate = rec->fTag.fCandidate;
679 // Rebuild a region of interest for chamber 7.
680 // Remember the parameters a and b are station specific.
681 AliHLTMUONRecHitStruct p7 = data->fTag.fLine.FindIntersectWithXYPlain( fgZ7 );
682 data->fTag.fChamber = kChamber7;
683 data->fTag.fRoi.Create(p7, fgA7, fgB7);
685 if (fMakeCandidates and data->fTag.fCandidate != NULL)
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();
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);
701 case kWaitMoreChamber8:
702 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
707 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8!");
712 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9()
714 // State change method for Station 5 state machine.
719 fSm5state = kSM5Done;
720 EndOfClusterRequests();
724 case kWaitMoreChamber9:
725 fSm5state = kSM5Done;
726 EndOfClusterRequests();
727 if (fRequestsCompleted == fSt5data.Count())
732 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9!");
737 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10()
739 // State change method for Station 5 state machine.
745 fSm5state = kWaitChamber9;
747 // No clusters found on chamber 10 so we need to make a request for
748 // clusters from chamber 9:
749 AliHLTMUONRecHitStruct p9 = fMc1.fLine.FindIntersectWithXYPlain( fgZ9 );
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);
756 if (fMakeCandidates and fMc1.fCandidate != NULL)
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();
764 AliHLTFloat32_t left, right, bottom, top;
765 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
766 RequestClusters(left, right, bottom, top, kChamber9, &fMc1);
770 case kWaitMoreChamber10:
771 fSm5state = kSM5Done;
772 EndOfClusterRequests();
773 if (fRequestsCompleted == fSt5data.Count())
778 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10!");
783 void AliHLTMUONMansoTrackerFSM::ProjectToStation4(
784 AliStation5Data* data, AliHLTFloat32_t station5z, AliHLTUInt32_t chamberSt5
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 assert( fSm4state == kWaitChamber8
792 || fSm4state == kWaitMoreChamber8
793 || fSm4state == kWaitChamber7
794 || fSm4state == kWaitMoreChamber7
796 assert( chamberSt5 == 2 or chamberSt5 == 3 );
797 AliTagData* tag = &data->fTag;
799 if (fSm4state == kWaitChamber8 || fSm4state == kWaitMoreChamber8)
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 );
804 AliHLTMUONRecHitStruct intercept = line51.FindIntersectWithXYPlain( fgZ8 );
807 // Build a region of interest for tracking station 4.
808 tag->fChamber = kChamber8;
809 tag->fRoi.Create(intercept, fgA8, fgB8);
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 );
817 AliHLTMUONRecHitStruct intercept = line51.FindIntersectWithXYPlain( fgZ7 );
820 // Build a region of interest for tracking station 4.
821 tag->fChamber = kChamber7;
822 tag->fRoi.Create(intercept, fgA7, fgB7);
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()
834 tag->fCandidate = fMc1.fCandidate;
838 tag->fCandidate = AddTrackCandidate();
839 if (tag->fCandidate != NULL) *tag->fCandidate = *fMc1.fCandidate;
841 // Now fill the cluster point found on station 5 and RoI on station 4.
842 if (tag->fCandidate != NULL)
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();
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);
859 void AliHLTMUONMansoTrackerFSM::ProcessClusters()
861 // Process clusters that have been received.
862 // This is called once all clusters have been found.
864 DebugTrace("ProcessClusters...");
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())
875 fSt5rec = fSt5data.First();
876 if (fSt5rec != fSt5data.End())
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)
889 // For all combinations of cluster point pairs from station 4 and 5
890 // signal a found track:
893 DebugTrace("\tfSt5rec->fTag.chamber = " << fSt5rec->fTag.fChamber
894 << " , fSt4chamber = " << fSt4chamber
897 for (fFoundPoint = fSt4points.First(); fFoundPoint != fSt4points.End(); fFoundPoint++)
899 if (fFoundPoint->fSt5tag == &fSt5rec->fTag)
903 fSt5rec++; // Get next station 5 cluster point.
904 } while (fSt5rec != fSt5data.End() && fSt5rec->fTag.fChamber == fSt4chamber);
911 AliHLTMUONMansoCandidateStruct* AliHLTMUONMansoTrackerFSM::AddTrackCandidate()
913 // Adds a new track candidate to the fCandidates list and returns a pointer
914 // to the new structure.
916 // First allocate or reallocate buffer if necessary.
917 if (fCandidates == NULL)
921 fCandidates = new AliHLTMUONMansoCandidateStruct[1024];
925 HLTError("Could not allocate buffer space for Manso track candidates.");
928 fCandidatesSize = 1024;
930 else if (fCandidatesCount >= fCandidatesSize)
932 AliHLTMUONMansoCandidateStruct* newbuf = NULL;
935 newbuf = new AliHLTMUONMansoCandidateStruct[fCandidatesSize*2];
939 HLTError("Could not allocate more buffer space for Manso track candidates.");
942 for (AliHLTUInt32_t i = 0; i < fCandidatesSize; ++i) newbuf[i] = fCandidates[i];
943 delete [] fCandidates;
944 fCandidates = newbuf;
945 fCandidatesSize = fCandidatesSize*2;
948 return &fCandidates[fCandidatesCount++];