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 track.fId = (fTrackId << 8) | (fTriggerId & 0xFF);
379 // Increment the track ID and warp it around at 0x7FFFFF since the
380 // bottom 8 bits are copied from fTriggerId and the sign bit in
381 // track.fId must be positive.
382 fTrackId = (fTrackId + 1) & 0x007FFFFF;
384 track.fTrigRec = fTriggerId;
386 AliHLTFloat32_t x1 = fFoundPoint->fClusterPoint.fX;
387 AliHLTFloat32_t y1 = fFoundPoint->fClusterPoint.fY;
388 AliHLTFloat32_t z1 = fFoundPoint->fClusterPoint.fZ;
389 AliHLTFloat32_t y2 = fSt5rec->fClusterPoint.fY;
390 AliHLTFloat32_t z2 = fSt5rec->fClusterPoint.fZ;
392 bool calculated = AliHLTMUONCalculations::ComputeMomentum(x1, y1, y2, z1, z2);
394 track.fPx = AliHLTMUONCalculations::Px();
395 track.fPy = AliHLTMUONCalculations::Py();
396 track.fPz = AliHLTMUONCalculations::Pz();
397 DebugTrace("Calculated Px = " << track.fPx << ", Py = " << track.fPy
398 << ", Pz = " << track.fPx
400 DebugTrace("\tusing x1 = " << x1 << " , y1 = " << y1 << " , y2 = " << y2
401 << " , z1 = " << z1 << " , z2 = " << z2
407 // Depending on which chamber we found reconstructed hits, fill the hit
408 // in the appropriate location. This is done for station 4 then 5.
409 if (fSt4chamber == kChamber8)
411 track.fHit[0] = AliHLTMUONConstants::NilRecHitStruct();
413 track.fHit[1] = fFoundPoint->fClusterPoint;
418 track.fHit[0] = fFoundPoint->fClusterPoint;
420 track.fHit[1] = AliHLTMUONConstants::NilRecHitStruct();
423 if (fMc1.fChamber == kChamber10)
425 track.fHit[2] = AliHLTMUONConstants::NilRecHitStruct();
427 track.fHit[3] = fSt5rec->fClusterPoint;
432 track.fHit[2] = fSt5rec->fClusterPoint;
434 track.fHit[3] = AliHLTMUONConstants::NilRecHitStruct();
438 track.fFlags = AliHLTMUONUtils::PackMansoTrackFlags(
439 AliHLTMUONCalculations::Sign(), hitset
444 AliHLTMUONMansoCandidateStruct* candidate = fSt5rec->fTag.fCandidate;
445 if (candidate != NULL)
447 candidate->fTrack = track;
455 void AliHLTMUONMansoTrackerFSM::Reset()
457 // Implementation of AliHLTMUONMansoTrackerFSM::Reset
459 DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
462 fSm4state = kSM4Idle;
463 fSm5state = kSM5Idle;
464 fRequestsCompleted = 0;
469 // Note: In the following ReceiveClustersXXX and EndOfClustersXXX methods we make
470 // the state machine transitions before calls to RequestClusters, FoundTrack,
471 // NoTrackFound or EndOfClusterRequests. This is important since the callback
472 // object will make recursive calls to the tracker's methods so we need to maintain
473 // a consistant internal state.
474 // The same would go for updating internal variables.
475 // In general one should only call the callback methods at the end of any of the
476 // following routines.
478 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7(
479 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count,
480 const AliTagData* data
483 // State change method for Station 4 state machine.
488 // We switch state below.
490 case kWaitMoreChamber7:
491 for (AliHLTUInt32_t j = 0; j < count; j++)
493 AliHLTMUONRecHitStruct cluster = clusters[j];
494 // Check that the cluster actually is in our region of interest on station 4.
495 if ( data->fRoi.Contains(cluster) )
497 // Go to next wait state only if we actually found anything in the RoI.
498 fSm4state = kWaitMoreChamber7;
500 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 7.");
501 AliStation4Data* newdata = fSt4points.Add();
502 newdata->fClusterPoint = cluster;
503 newdata->fSt5tag = data;
509 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7!");
514 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8(
515 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count,
516 const AliTagData* data
519 // State change method for Station 4 state machine.
524 fSt4chamber = kChamber8;
526 case kWaitMoreChamber8:
527 for (AliHLTUInt32_t j = 0; j < count; j++)
529 AliHLTMUONRecHitStruct cluster = clusters[j];
530 // Check that the cluster actually is in our region of interest on station 4.
531 if ( data->fRoi.Contains(cluster) )
533 // Go to next wait state only if we actually found anything in the RoI.
534 fSm4state = kWaitMoreChamber8;
536 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 8.");
537 AliStation4Data* newdata = fSt4points.Add();
538 newdata->fClusterPoint = cluster;
539 newdata->fSt5tag = data;
545 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8!");
550 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9(
551 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count
554 // State change method for Station 5 state machine.
559 fSm4state = kWaitChamber8; // Start SM4.
561 case kWaitMoreChamber9:
562 for (AliHLTUInt32_t j = 0; j < count; j++)
564 AliHLTMUONRecHitStruct cluster = clusters[j];
565 // Check that the cluster actually is in our region of interest on station 5.
566 if ( fMc1.fRoi.Contains(cluster) )
568 // Go to next wait state only if we actually found anything in the RoI.
569 fSm5state = kWaitMoreChamber9;
571 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 9.");
572 AliStation5Data* data = fSt5data.Add();
573 data->fClusterPoint = cluster;
574 ProjectToStation4(data, fgZ9, 2); // This adds a new request for station 4.
580 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9!");
585 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10(
586 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count
589 // State change method for Station 5 state machine.
594 fSm4state = kWaitChamber8; // Start SM4.
596 case kWaitMoreChamber10:
597 for (AliHLTUInt32_t j = 0; j < count; j++)
599 AliHLTMUONRecHitStruct cluster = clusters[j];
600 // Check that the cluster actually is in our region of interest on station 5.
601 if ( fMc1.fRoi.Contains(cluster) )
603 // Go to next wait state only if we actually found anything in the RoI.
604 fSm5state = kWaitMoreChamber10;
606 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 10.");
607 AliStation5Data* data = fSt5data.Add();
608 data->fClusterPoint = cluster;
609 ProjectToStation4(data, fgZ10, 3); // This adds a new request for station 4.
615 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10!");
620 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7()
622 // State change method for Station 4 state machine.
624 fRequestsCompleted++; // Increment the number of requests completed for station 4.
625 DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
630 // If all data from station 5 is received and no data found on
631 // chambers 7 or 8 then we can not find a track.
632 if (fSm5state == kSM5Done) NoTrackFound();
635 case kWaitMoreChamber7:
636 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
641 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7!");
646 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8()
648 // State change method for Station 4 state machine.
650 fRequestsCompleted++; // Increment the number of requests completed for station 4.
651 DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
656 // Ignore. The requests for chamber 8 are already re-requested below.
661 fSm4state = kWaitChamber7;
662 fSt4chamber = kChamber7;
664 // We need to resend the requests for chamber 8, but change the request
665 // to get data for chamber 7 instead:
666 AliHLTUInt32_t reqlistsize = fSt5data.Count();
667 DebugTrace("Re-requesting clusters from chamber 7... reqlistsize = " << reqlistsize);
669 Station5List::Iterator rec = fSt5data.First();
670 for (AliHLTUInt32_t i = 0; i < reqlistsize; i++, rec++)
672 // Need to create a new st5 data block for the request.
673 AliStation5Data* data = fSt5data.Add();
674 data->fClusterPoint = rec->fClusterPoint;
675 data->fTag.fLine = rec->fTag.fLine;
676 data->fTag.fCandidate = rec->fTag.fCandidate;
678 // Rebuild a region of interest for chamber 7.
679 // Remember the parameters a and b are station specific.
680 AliHLTMUONRecHitStruct p7 = data->fTag.fLine.FindIntersectWithXYPlain( fgZ7 );
681 data->fTag.fChamber = kChamber7;
682 data->fTag.fRoi.Create(p7, fgA7, fgB7);
684 if (fMakeCandidates and data->fTag.fCandidate != NULL)
686 data->fTag.fCandidate->fRoI[0].fX = data->fTag.fRoi.Centre().fX;
687 data->fTag.fCandidate->fRoI[0].fY = data->fTag.fRoi.Centre().fY;
688 data->fTag.fCandidate->fRoI[0].fZ = data->fTag.fRoi.Centre().fZ;
689 data->fTag.fCandidate->fRoI[0].fRadius = data->fTag.fRoi.Radius();
692 AliHLTFloat32_t left, right, bottom, top;
693 data->fTag.fRoi.GetBoundaryBox(left, right, bottom, top);
694 // Make request for chamber 7 data.
695 RequestClusters(left, right, bottom, top, kChamber7, &data->fTag);
700 case kWaitMoreChamber8:
701 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
706 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8!");
711 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9()
713 // State change method for Station 5 state machine.
718 fSm5state = kSM5Done;
719 EndOfClusterRequests();
723 case kWaitMoreChamber9:
724 fSm5state = kSM5Done;
725 EndOfClusterRequests();
726 if (fRequestsCompleted == fSt5data.Count())
731 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9!");
736 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10()
738 // State change method for Station 5 state machine.
744 fSm5state = kWaitChamber9;
746 // No clusters found on chamber 10 so we need to make a request for
747 // clusters from chamber 9:
748 AliHLTMUONRecHitStruct p9 = fMc1.fLine.FindIntersectWithXYPlain( fgZ9 );
750 // Build a region of interest for tracking station 5 (chamber 9).
751 // Remember the parameters a and b are station specific.
752 fMc1.fChamber = kChamber9;
753 fMc1.fRoi.Create(p9, fgA9, fgB9);
755 if (fMakeCandidates and fMc1.fCandidate != NULL)
757 fMc1.fCandidate->fRoI[2].fX = fMc1.fRoi.Centre().fX;
758 fMc1.fCandidate->fRoI[2].fY = fMc1.fRoi.Centre().fY;
759 fMc1.fCandidate->fRoI[2].fZ = fMc1.fRoi.Centre().fZ;
760 fMc1.fCandidate->fRoI[2].fRadius = fMc1.fRoi.Radius();
763 AliHLTFloat32_t left, right, bottom, top;
764 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
765 RequestClusters(left, right, bottom, top, kChamber9, &fMc1);
769 case kWaitMoreChamber10:
770 fSm5state = kSM5Done;
771 EndOfClusterRequests();
772 if (fRequestsCompleted == fSt5data.Count())
777 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10!");
782 void AliHLTMUONMansoTrackerFSM::ProjectToStation4(
783 AliStation5Data* data, AliHLTFloat32_t station5z, AliHLTUInt32_t chamberSt5
786 // Perform chamber specific operations:
787 // Since certain states of SM4 means that it is fetching for Chamber8
788 // and other states are for fetching from Chamber7. We need to make
789 // requests for the correct chamber.
790 assert( fSm4state == kWaitChamber8
791 || fSm4state == kWaitMoreChamber8
792 || fSm4state == kWaitChamber7
793 || fSm4state == kWaitMoreChamber7
795 assert( chamberSt5 == 2 or chamberSt5 == 3 );
796 AliTagData* tag = &data->fTag;
798 if (fSm4state == kWaitChamber8 || fSm4state == kWaitMoreChamber8)
800 // Form the vector line between trigger station 1 and tracking station 5,
801 // and find the intersection point of the line with station 4 (chamber8).
802 AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
803 AliHLTMUONRecHitStruct intercept = line51.FindIntersectWithXYPlain( fgZ8 );
806 // Build a region of interest for tracking station 4.
807 tag->fChamber = kChamber8;
808 tag->fRoi.Create(intercept, fgA8, fgB8);
813 // Form the vector line between trigger station 1 and tracking station 5,
814 // and find the intersection point of the line with station 4 (chamber7).
815 AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
816 AliHLTMUONRecHitStruct intercept = line51.FindIntersectWithXYPlain( fgZ7 );
819 // Build a region of interest for tracking station 4.
820 tag->fChamber = kChamber7;
821 tag->fRoi.Create(intercept, fgA7, fgB7);
827 // Make a copy of the track candidate if the exisiting track candidate
828 // has already had its point on the given chamber filled.
829 if (fMc1.fCandidate != NULL and
830 fMc1.fCandidate->fTrack.fHit[chamberSt5] == AliHLTMUONConstants::NilRecHitStruct()
833 tag->fCandidate = fMc1.fCandidate;
837 tag->fCandidate = AddTrackCandidate();
838 if (tag->fCandidate != NULL) *tag->fCandidate = *fMc1.fCandidate;
840 // Now fill the cluster point found on station 5 and RoI on station 4.
841 if (tag->fCandidate != NULL)
843 tag->fCandidate->fTrack.fHit[chamberSt5] = data->fClusterPoint;
844 tag->fCandidate->fRoI[chamber].fX = tag->fRoi.Centre().fX;
845 tag->fCandidate->fRoI[chamber].fY = tag->fRoi.Centre().fY;
846 tag->fCandidate->fRoI[chamber].fZ = tag->fRoi.Centre().fZ;
847 tag->fCandidate->fRoI[chamber].fRadius = tag->fRoi.Radius();
851 // Make the request for clusters from station 4.
852 AliHLTFloat32_t left, right, bottom, top;
853 tag->fRoi.GetBoundaryBox(left, right, bottom, top);
854 RequestClusters(left, right, bottom, top, tag->fChamber, tag);
858 void AliHLTMUONMansoTrackerFSM::ProcessClusters()
860 // Process clusters that have been received.
861 // This is called once all clusters have been found.
863 DebugTrace("ProcessClusters...");
865 // Check if the cluster point list on station 4 is empty.
866 // If it is then we have not found any tracks.
867 fFoundPoint = fSt4points.First();
868 if (fFoundPoint == fSt4points.End())
874 fSt5rec = fSt5data.First();
875 if (fSt5rec != fSt5data.End())
877 // Only look at station 5 data records that are for the found chamber number.
878 // Note: either we only have chamber 8 data or we have chamber 7 data followed
879 // by chamber 8 data.
880 // Thus if we hit records that we are not interested in already then the list
881 // contains no interesting data and we can signal no track found.
882 if (fSt5rec->fTag.fChamber != fSt4chamber)
888 // For all combinations of cluster point pairs from station 4 and 5
889 // signal a found track:
892 DebugTrace("\tfSt5rec->fTag.chamber = " << fSt5rec->fTag.fChamber
893 << " , fSt4chamber = " << fSt4chamber
896 for (fFoundPoint = fSt4points.First(); fFoundPoint != fSt4points.End(); fFoundPoint++)
898 if (fFoundPoint->fSt5tag == &fSt5rec->fTag)
902 fSt5rec++; // Get next station 5 cluster point.
903 } while (fSt5rec != fSt5data.End() && fSt5rec->fTag.fChamber == fSt4chamber);
910 AliHLTMUONMansoCandidateStruct* AliHLTMUONMansoTrackerFSM::AddTrackCandidate()
912 // Adds a new track candidate to the fCandidates list and returns a pointer
913 // to the new structure.
915 // First allocate or reallocate buffer if necessary.
916 if (fCandidates == NULL)
920 fCandidates = new AliHLTMUONMansoCandidateStruct[1024];
924 HLTError("Could not allocate buffer space for Manso track candidates.");
927 fCandidatesSize = 1024;
929 else if (fCandidatesCount >= fCandidatesSize)
931 AliHLTMUONMansoCandidateStruct* newbuf = NULL;
934 newbuf = new AliHLTMUONMansoCandidateStruct[fCandidatesSize*2];
938 HLTError("Could not allocate more buffer space for Manso track candidates.");
941 for (AliHLTUInt32_t i = 0; i < fCandidatesSize; ++i) newbuf[i] = fCandidates[i];
942 delete [] fCandidates;
943 fCandidates = newbuf;
944 fCandidatesSize = fCandidatesSize*2;
947 return &fCandidates[fCandidatesCount++];