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.
26 #include "AliHLTMUONMansoTrackerFSM.h"
27 #include "AliHLTMUONCalculations.h"
28 #include "AliHLTMUONConstants.h"
29 #include "AliHLTMUONUtils.h"
38 std::ostream& operator << (std::ostream& os, AliHLTMUONMansoTrackerFSM::StatesSM4 state)
42 case AliHLTMUONMansoTrackerFSM::kSM4Idle: os << "kSM4Idle"; break;
43 case AliHLTMUONMansoTrackerFSM::kWaitChamber8: os << "kWaitChamber8"; break;
44 case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber8: os << "kWaitMoreChamber8"; break;
45 case AliHLTMUONMansoTrackerFSM::kWaitChamber7: os << "kWaitChamber7"; break;
46 case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber7: os << "kWaitMoreChamber7"; break;
47 default: os << "FAULT!!";
52 std::ostream& operator << (std::ostream& os, AliHLTMUONMansoTrackerFSM::StatesSM5 state)
56 case AliHLTMUONMansoTrackerFSM::kSM5Idle: os << "kSM5Idle"; break;
57 case AliHLTMUONMansoTrackerFSM::kWaitChamber10: os << "kWaitChamber10"; break;
58 case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber10: os << "kWaitMoreChamber10"; break;
59 case AliHLTMUONMansoTrackerFSM::kWaitChamber9: os << "kWaitChamber9"; break;
60 case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber9: os << "kWaitMoreChamber9"; break;
61 case AliHLTMUONMansoTrackerFSM::kSM5Done: os << "kSM5Done"; break;
62 default: os << "FAULT!!";
71 // Deviate from the Manso implementation by allowing a and b
72 // parameters per chamber and not just per station.
73 // The default values are derived from the work done in
74 // "A first algorithm for dimuon High Level Trigger"
75 // Ref ID: ALICE-INT-2002-04 version 1.0
76 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA7 = 0.016f;
77 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB7 = 2.0f;
78 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA8 = 0.016f;
79 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB8 = 2.0f;
80 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA9 = 0.020f;
81 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB9 = 3.0f;
82 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA10 = 0.020f;
83 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB10 = 3.0f;
84 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ7 = -1274.5f;
85 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ8 = -1305.5f;
86 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ9 = -1408.6f;
87 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ10 = -1439.6f;
88 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ11 = -1603.5f;
89 AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ13 = -1703.5f;
92 void AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::Create(
93 AliHLTMUONRecHitStruct p, AliHLTFloat32_t a, AliHLTFloat32_t b
96 // Creates a region of interest specific to the Manso algorithm from a point and
97 // two Manso specific parameters.
100 // Compute the radius Rp
101 AliHLTFloat32_t rp = (AliHLTFloat32_t) sqrt( p.fX * p.fX + p.fY * p.fY );
103 // The radius Rs for the region of interest is computed from the
104 // specification given in the document:
105 // "A first algorithm for dimuon High Level Trigger"
106 // Ref ID: ALICE-INT-2002-04 version 1.0
109 // given on page 3 section 4.
114 bool AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::Contains(AliHLTMUONRecHitStruct p) const
116 // Compute the distance between the centre of the region of interest and
117 // the point p. This distance must be less than the radius of the region
118 // of interest for p to be contained in the region of interest.
119 register AliHLTFloat32_t lx = fCentre.fX - p.fX;
120 register AliHLTFloat32_t ly = fCentre.fY - p.fY;
121 register AliHLTFloat32_t r = (AliHLTFloat32_t) sqrt( lx * lx + ly * ly );
122 DebugTrace("\tAliRegionOfInterest::Contains : p = " << p
123 << " , centre = " << fCentre << " , r = " << r << " , Rs = " << fRs
129 void AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::GetBoundaryBox(
130 AliHLTFloat32_t& left, AliHLTFloat32_t& right,
131 AliHLTFloat32_t& bottom, AliHLTFloat32_t& top
134 // Works out the smallest boundary box that will contain the region of interest.
136 left = fCentre.fX - fRs;
137 right = fCentre.fX + fRs;
138 bottom = fCentre.fY - fRs;
139 top = fCentre.fY + fRs;
143 AliHLTMUONMansoTrackerFSM::AliVertex::AliVertex(
144 AliHLTFloat32_t x, AliHLTFloat32_t y, AliHLTFloat32_t z
146 : fX(x), fY(y), fZ(z)
148 // Constructor for vertex.
152 AliHLTMUONMansoTrackerFSM::AliVertex::AliVertex(AliHLTMUONRecHitStruct xy, AliHLTFloat32_t z)
153 : fX(xy.fX), fY(xy.fY), fZ(z)
155 // Construct vertex from a point on the XY plane and z coordinate.
159 AliHLTMUONMansoTrackerFSM::AliLine::AliLine(
160 AliHLTFloat32_t ax, AliHLTFloat32_t ay, AliHLTFloat32_t az,
161 AliHLTFloat32_t bx, AliHLTFloat32_t by, AliHLTFloat32_t bz
170 // Construct a line defined by L = M*t + C = (A-B)*t + B
171 // where M and C are 3D vectors and t is a free parameter.
172 // A = (ax, ay, az) and B = (bx, by, bz)
176 AliHLTMUONMansoTrackerFSM::AliLine::AliLine(AliVertex a, AliVertex b) :
184 // Contruct a line to go through two vertices a and b.
188 AliHLTMUONRecHitStruct AliHLTMUONMansoTrackerFSM::AliLine::FindIntersectWithXYPlain(
192 // Find the point of intersection of the line and the XY plane at z.
195 if (fMz != 0) // Should not have a ray perpendicular to the beam axis.
199 AliHLTMUONRecHitStruct p;
207 AliHLTMUONMansoTrackerFSM::AliHLTMUONMansoTrackerFSM() :
211 fRequestsCompleted(0),
212 fSt4chamber(kChamber1),
222 // Default constructor
226 bool AliHLTMUONMansoTrackerFSM::LineFit(
227 const AliHLTMUONTriggerRecordStruct& trigger,
228 AliHLTMUONRecHitStruct& pa, AliHLTMUONRecHitStruct& pb
231 // Apply least squares fit to the hits on the trigger record.
232 // http://mathworld.wolfram.com/LeastSquaresFitting.html
234 AliHLTMUONParticleSign sign;
236 AliHLTMUONUtils::UnpackTriggerRecordFlags(trigger.fFlags, sign, hitset);
237 DebugTrace("hitset = {" << hitset[0] << ", " << hitset[1] << ", "
238 << hitset[2] << ", " << hitset[3] << "}"
241 AliHLTFloat32_t sumX = 0;
242 AliHLTFloat32_t sumY = 0;
243 AliHLTFloat32_t sumZ = 0;
245 for (int i = 0; i < 4; i++)
249 sumX += trigger.fHit[i].fX;
250 sumY += trigger.fHit[i].fY;
251 sumZ += trigger.fHit[i].fZ;
255 if (n < 2) return false;
256 AliHLTFloat32_t meanX = sumX / AliHLTFloat32_t(n);
257 AliHLTFloat32_t meanY = sumY / AliHLTFloat32_t(n);
258 AliHLTFloat32_t meanZ = sumZ / AliHLTFloat32_t(n);
260 AliHLTFloat32_t SSzz = 0;
261 AliHLTFloat32_t SSzx = 0;
262 AliHLTFloat32_t SSzy = 0;
263 for (int i = 0; i < 4; i++)
267 SSzz += (trigger.fHit[i].fZ - meanZ)*(trigger.fHit[i].fZ - meanZ);
268 SSzx += (trigger.fHit[i].fZ - meanZ)*(trigger.fHit[i].fX - meanX);
269 SSzy += (trigger.fHit[i].fZ - meanZ)*(trigger.fHit[i].fY - meanY);
273 // Calculate params for lines x = Mzx * z + Czx and y = Mzy * z + Czy.
274 if (SSzz == 0) return false;
275 AliHLTFloat32_t Mzx = SSzx / SSzz;
276 AliHLTFloat32_t Mzy = SSzy / SSzz;
277 AliHLTFloat32_t Czx = meanX - Mzx * meanZ;
278 AliHLTFloat32_t Czy = meanY - Mzy * meanZ;
280 // Calculate ideal points on chambers 11 and 13:
282 pa.fX = Mzx * pa.fZ + Czx;
283 pa.fY = Mzy * pa.fZ + Czy;
285 pb.fX = Mzx * pb.fZ + Czx;
286 pb.fY = Mzy * pb.fZ + Czy;
292 void AliHLTMUONMansoTrackerFSM::FindTrack(const AliHLTMUONTriggerRecordStruct& trigger)
294 // Tries to find the track from the trigger seed.
296 DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
297 DebugTrace("Processing trigger with ID = " << trigger.fId);
299 fTriggerId = trigger.fId;
301 AliHLTMUONRecHitStruct pa, pb;
302 if (not LineFit(trigger, pa, pb))
308 fV1 = AliVertex(pa.fX, pa.fY, pa.fZ);
309 AliVertex v2 = AliVertex(pb.fX, pb.fY, pb.fZ);
311 DebugTrace("Using fV1 = {x = " << fV1.X() << ", y = " << fV1.Y() << ", " << fV1.Z() << "}");
312 DebugTrace("Using v2 = {x = " << v2.X() << ", y = " << v2.Y() << ", " << v2.Z() << "}");
314 // Form the vector line between the above two impact points and
315 // find the crossing point of the line with chamber 10 (i.e. station 5).
316 fMc1.fLine = AliLine(fV1, v2);
317 AliHLTMUONRecHitStruct p10 = fMc1.fLine.FindIntersectWithXYPlain( fgZ10 );
319 // Build a region of interest for tracking station 5 (chamber 10).
320 // Remember the parameters a and b are station specific.
321 fMc1.fChamber = kChamber10;
322 fMc1.fRoi.Create(p10, fgA10, fgB10);
324 // Make SM5 state transition before the call to RequestClusters since
325 // that method could call one of our methods again, so we need to be
326 // in a consistant internal state.
327 fSm5state = kWaitChamber10;
329 AliHLTFloat32_t left, right, bottom, top;
330 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
331 RequestClusters(left, right, bottom, top, kChamber10, &fMc1);
335 void AliHLTMUONMansoTrackerFSM::ReturnClusters(
336 void* tag, const AliHLTMUONRecHitStruct* clusters,
340 // Implementation of AliHLTMUONMansoTrackerFSM::ReturnClusters.
343 assert( clusters != NULL );
345 AliTagData* data = (AliTagData*)tag;
346 DebugTrace("Got AliHLTMUONMansoTrackerFSM::ReturnClusters(tag = " << tag
347 << ", chamber = " << data->fChamber
348 << ", clusters = " << clusters << ", count = " << count << ")"
350 DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
352 switch (data->fChamber)
354 case kChamber7: ReceiveClustersChamber7(clusters, count, data); break;
355 case kChamber8: ReceiveClustersChamber8(clusters, count, data); break;
356 case kChamber9: ReceiveClustersChamber9(clusters, count); break;
357 case kChamber10: ReceiveClustersChamber10(clusters, count); break;
360 DebugTrace("ERROR: Got tag with an invalid value: " << data->fChamber);
365 void AliHLTMUONMansoTrackerFSM::EndOfClusters(void* tag)
367 // Implementation of AliHLTMUONMansoTrackerFSM::EndOfClusters.
369 AliTagData* data = (AliTagData*)tag;
370 DebugTrace("Got AliHLTMUONMansoTrackerFSM::EndOfClusters(chamber = " << data->fChamber << ")");
371 DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
373 switch (data->fChamber)
375 case kChamber7: EndOfClustersChamber7(); break;
376 case kChamber8: EndOfClustersChamber8(); break;
377 case kChamber9: EndOfClustersChamber9(); break;
378 case kChamber10: EndOfClustersChamber10(); break;
381 DebugTrace("ERROR: Got tag with an invalid value: " << data->fChamber);
386 bool AliHLTMUONMansoTrackerFSM::FillTrackData(AliHLTMUONMansoTrackStruct& track)
388 // Implementation of AliHLTMUONMansoTrackerFSM::FillTrackData
390 DebugTrace("FillTrack: st5 = " << fSt5rec->fClusterPoint << ", st4 = " << fFoundPoint->fClusterPoint);
392 track.fId = fTrackId;
393 // Increment track Id and keep it positive.
394 //TODO: handle the wrapparound better.
395 if (fTrackId < 0x7FFFFFFF)
400 track.fTrigRec = fTriggerId;
402 AliHLTFloat32_t x1 = fFoundPoint->fClusterPoint.fX;
403 AliHLTFloat32_t y1 = fFoundPoint->fClusterPoint.fY;
404 AliHLTFloat32_t z1 = fFoundPoint->fClusterPoint.fZ;
405 AliHLTFloat32_t y2 = fSt5rec->fClusterPoint.fY;
406 AliHLTFloat32_t z2 = fSt5rec->fClusterPoint.fZ;
408 bool calculated = AliHLTMUONCalculations::ComputeMomentum(x1, y1, y2, z1, z2);
410 track.fPx = AliHLTMUONCalculations::Px();
411 track.fPy = AliHLTMUONCalculations::Py();
412 track.fPz = AliHLTMUONCalculations::Pz();
413 DebugTrace("Calculated Px = " << track.fPx << ", Py = " << track.fPy
414 << ", Pz = " << track.fPx
416 DebugTrace("\tusing x1 = " << x1 << " , y1 = " << y1 << " , y2 = " << y2
417 << " , z1 = " << z1 << " , z2 = " << z2
423 // Depending on which chamber we found reconstructed hits, fill the hit
424 // in the appropriate location. This is done for station 4 then 5.
425 if (fSt4chamber == kChamber8)
427 track.fHit[0] = AliHLTMUONConstants::NilRecHitStruct();
429 track.fHit[1] = fFoundPoint->fClusterPoint;
434 track.fHit[0] = fFoundPoint->fClusterPoint;
436 track.fHit[1] = AliHLTMUONConstants::NilRecHitStruct();
439 if (fMc1.fChamber == kChamber10)
441 track.fHit[2] = AliHLTMUONConstants::NilRecHitStruct();
443 track.fHit[3] = fSt5rec->fClusterPoint;
448 track.fHit[2] = fSt5rec->fClusterPoint;
450 track.fHit[3] = AliHLTMUONConstants::NilRecHitStruct();
454 track.fFlags = AliHLTMUONUtils::PackMansoTrackFlags(
455 AliHLTMUONCalculations::Sign(), hitset
461 void AliHLTMUONMansoTrackerFSM::Reset()
463 // Implementation of AliHLTMUONMansoTrackerFSM::Reset
465 DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
468 fSm4state = kSM4Idle;
469 fSm5state = kSM5Idle;
470 fRequestsCompleted = 0;
475 // Note: In the following ReceiveClustersXXX and EndOfClustersXXX methods we make
476 // the state machine transitions before calls to RequestClusters, FoundTrack,
477 // NoTrackFound or EndOfClusterRequests. This is important since the callback
478 // object will make recursive calls to the tracker's methods so we need to maintain
479 // a consistant internal state.
480 // The same would go for updating internal variables.
481 // In general one should only call the callback methods at the end of any of the
482 // following routines.
484 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7(
485 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count,
486 const AliTagData* data
489 // State change method for Station 4 state machine.
494 fSm4state = kWaitMoreChamber7;
496 case kWaitMoreChamber7:
497 for (AliHLTUInt32_t j = 0; j < count; j++)
499 AliHLTMUONRecHitStruct cluster = clusters[j];
500 // Check that the cluster actually is in our region of interest on station 4.
501 if ( data->fRoi.Contains(cluster) )
503 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 7.");
504 AliStation4Data* newdata = fSt4points.Add();
505 newdata->fClusterPoint = cluster;
506 newdata->fSt5tag = data;
512 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7!");
517 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8(
518 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count,
519 const AliTagData* data
522 // State change method for Station 4 state machine.
527 fSm4state = kWaitMoreChamber8;
528 fSt4chamber = kChamber8;
530 case kWaitMoreChamber8:
531 for (AliHLTUInt32_t j = 0; j < count; j++)
533 AliHLTMUONRecHitStruct cluster = clusters[j];
534 // Check that the cluster actually is in our region of interest on station 4.
535 if ( data->fRoi.Contains(cluster) )
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 fSm5state = kWaitMoreChamber9;
561 fSm4state = kWaitChamber8; // Start SM4.
563 case kWaitMoreChamber9:
564 for (AliHLTUInt32_t j = 0; j < count; j++)
566 AliHLTMUONRecHitStruct cluster = clusters[j];
567 // Check that the cluster actually is in our region of interest on station 5.
568 if ( fMc1.fRoi.Contains(cluster) )
570 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 9.");
571 AliStation5Data* data = fSt5data.Add();
572 data->fClusterPoint = cluster;
573 ProjectToStation4(data, fgZ9); // This adds a new request for station 4.
579 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9!");
584 void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10(
585 const AliHLTMUONRecHitStruct* clusters, AliHLTUInt32_t count
588 // State change method for Station 5 state machine.
593 fSm5state = kWaitMoreChamber10;
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 DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 10.");
604 AliStation5Data* data = fSt5data.Add();
605 data->fClusterPoint = cluster;
606 ProjectToStation4(data, fgZ10); // This adds a new request for station 4.
612 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10!");
617 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7()
619 // State change method for Station 4 state machine.
621 fRequestsCompleted++; // Increment the number of requests completed for station 4.
622 DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
627 // If all data from station 5 is received and no data found on
628 // chambers 7 or 8 then we can not find a track.
629 if (fSm5state == kSM5Done) NoTrackFound();
632 case kWaitMoreChamber7:
633 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
638 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7!");
643 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8()
645 // State change method for Station 4 state machine.
647 fRequestsCompleted++; // Increment the number of requests completed for station 4.
648 DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
653 // Ignore. The requests for chamber 8 are already re-requested below.
658 fSm4state = kWaitChamber7;
659 fSt4chamber = kChamber7;
661 // We need to resend the requests for chamber 8, but change the request
662 // to get data for chamber 7 instead:
663 AliHLTUInt32_t reqlistsize = fSt5data.Count();
664 DebugTrace("Re-requesting clusters from chamber 7... reqlistsize = " << reqlistsize);
666 Station5List::Iterator rec = fSt5data.First();
667 for (AliHLTUInt32_t i = 0; i < reqlistsize; i++, rec++)
669 // Need to create a new st5 data block for the request.
670 AliStation5Data* data = fSt5data.Add();
671 data->fClusterPoint = rec->fClusterPoint;
672 data->fTag.fLine = rec->fTag.fLine;
674 // Rebuild a region of interest for chamber 7.
675 // Remember the parameters a and b are station specific.
676 AliHLTMUONRecHitStruct p7 = data->fTag.fLine.FindIntersectWithXYPlain( fgZ7 );
677 data->fTag.fChamber = kChamber7;
678 data->fTag.fRoi.Create(p7, fgA7, fgB7);
680 AliHLTFloat32_t left, right, bottom, top;
681 data->fTag.fRoi.GetBoundaryBox(left, right, bottom, top);
682 // Make request for chamber 7 data.
683 RequestClusters(left, right, bottom, top, kChamber7, &data->fTag);
688 case kWaitMoreChamber8:
689 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
694 DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8!");
699 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9()
701 // State change method for Station 5 state machine.
706 fSm5state = kSM5Done;
707 EndOfClusterRequests();
711 case kWaitMoreChamber9:
712 fSm5state = kSM5Done;
713 EndOfClusterRequests();
714 if (fRequestsCompleted == fSt5data.Count())
719 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9!");
724 void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10()
726 // State change method for Station 5 state machine.
732 fSm5state = kWaitChamber9;
734 // No clusters found on chamber 10 so we need to make a request for
735 // clusters from chamber 9:
736 AliHLTMUONRecHitStruct p9 = fMc1.fLine.FindIntersectWithXYPlain( fgZ9 );
738 // Build a region of interest for tracking station 5 (chamber 9).
739 // Remember the parameters a and b are station specific.
740 fMc1.fChamber = kChamber9;
741 fMc1.fRoi.Create(p9, fgA9, fgB9);
743 AliHLTFloat32_t left, right, bottom, top;
744 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
745 RequestClusters(left, right, bottom, top, kChamber9, &fMc1);
749 case kWaitMoreChamber10:
750 fSm5state = kSM5Done;
751 EndOfClusterRequests();
752 if (fRequestsCompleted == fSt5data.Count())
757 DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10!");
762 void AliHLTMUONMansoTrackerFSM::ProjectToStation4(
763 AliStation5Data* data, register AliHLTFloat32_t station5z
766 // Perform chamber specific operations:
767 // Since certain states of SM4 means that it is fetching for Chamber8
768 // and other states are for fetching from Chamber7. We need to make
769 // requests for the correct chamber.
770 assert( fSm4state == kWaitChamber8
771 || fSm4state == kWaitMoreChamber8
772 || fSm4state == kWaitChamber7
773 || fSm4state == kWaitMoreChamber7
775 AliTagData* tag = &data->fTag;
776 if (fSm4state == kWaitChamber8 || fSm4state == kWaitMoreChamber8)
778 // Form the vector line between trigger station 1 and tracking station 5,
779 // and find the intersection point of the line with station 4 (chamber8).
780 AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
781 AliHLTMUONRecHitStruct intercept = line51.FindIntersectWithXYPlain( fgZ8 );
784 // Build a region of interest for tracking station 4.
785 tag->fChamber = kChamber8;
786 tag->fRoi.Create(intercept, fgA8, fgB8);
790 // Form the vector line between trigger station 1 and tracking station 5,
791 // and find the intersection point of the line with station 4 (chamber7).
792 AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
793 AliHLTMUONRecHitStruct intercept = line51.FindIntersectWithXYPlain( fgZ7 );
796 // Build a region of interest for tracking station 4.
797 tag->fChamber = kChamber7;
798 tag->fRoi.Create(intercept, fgA7, fgB7);
801 // Make the request for clusters from station 4.
802 AliHLTFloat32_t left, right, bottom, top;
803 tag->fRoi.GetBoundaryBox(left, right, bottom, top);
804 RequestClusters(left, right, bottom, top, tag->fChamber, tag);
808 void AliHLTMUONMansoTrackerFSM::ProcessClusters()
810 // Process clusters that have been received.
811 // This is called once all clusters have been found.
813 DebugTrace("ProcessClusters...");
815 // Check if the cluster point list on station 4 is empty.
816 // If it is then we have not found any tracks.
817 fFoundPoint = fSt4points.First();
818 if (fFoundPoint == fSt4points.End())
824 fSt5rec = fSt5data.First();
825 if (fSt5rec != fSt5data.End())
827 // Only look at station 5 data records that are for the found chamber number.
828 // Note: either we only have chamber 8 data or we have chamber 7 data followed
829 // by chamber 8 data.
830 // Thus if we hit records that we are not interested in already then the list
831 // contains no interesting data and we can signal no track found.
832 if (fSt5rec->fTag.fChamber != fSt4chamber)
838 // For all combinations of cluster point pairs from station 4 and 5
839 // signal a found track:
842 DebugTrace("\tfSt5rec->fTag.chamber = " << fSt5rec->fTag.fChamber
843 << " , fSt4chamber = " << fSt4chamber
846 for (fFoundPoint = fSt4points.First(); fFoundPoint != fSt4points.End(); fFoundPoint++)
848 if (fFoundPoint->fSt5tag == &fSt5rec->fTag)
852 fSt5rec++; // Get next station 5 cluster point.
853 } while (fSt5rec != fSt5data.End() && fSt5rec->fTag.fChamber == fSt4chamber);