1 ////////////////////////////////////////////////////////////////////////////////
3 // Author: Artur Szostak
4 // Email: artur@alice.phy.uct.ac.za | artursz@iafrica.com
6 ////////////////////////////////////////////////////////////////////////////////
8 #include "Tracking/MansoTracker.hpp"
10 #include "Tracking/Calculations.hpp"
13 #include "RegionOfInterest.hpp"
16 #if defined(DEBUG) || (defined(USE_ALILOG) && ! defined(LOG_NO_DEBUG))
18 #include "Debug/print.hpp"
22 std::ostream& operator << (std::ostream& os, AliHLTMUONCoreMansoTracker::StatesSM4 state)
26 case AliHLTMUONCoreMansoTracker::kSM4Idle: os << "kSM4Idle"; break;
27 case AliHLTMUONCoreMansoTracker::kWaitChamber8: os << "kWaitChamber8"; break;
28 case AliHLTMUONCoreMansoTracker::kWaitMoreChamber8: os << "kWaitMoreChamber8"; break;
29 case AliHLTMUONCoreMansoTracker::kWaitChamber7: os << "kWaitChamber7"; break;
30 case AliHLTMUONCoreMansoTracker::kWaitMoreChamber7: os << "kWaitMoreChamber7"; break;
31 default: os << "FAULT!!";
36 std::ostream& operator << (std::ostream& os, AliHLTMUONCoreMansoTracker::StatesSM5 state)
40 case AliHLTMUONCoreMansoTracker::kSM5Idle: os << "kSM5Idle"; break;
41 case AliHLTMUONCoreMansoTracker::kWaitChamber10: os << "kWaitChamber10"; break;
42 case AliHLTMUONCoreMansoTracker::kWaitMoreChamber10: os << "kWaitMoreChamber10"; break;
43 case AliHLTMUONCoreMansoTracker::kWaitChamber9: os << "kWaitChamber9"; break;
44 case AliHLTMUONCoreMansoTracker::kWaitMoreChamber9: os << "kWaitMoreChamber9"; break;
45 case AliHLTMUONCoreMansoTracker::kSM5Done: os << "kSM5Done"; break;
46 default: os << "FAULT!!";
55 // Deviate from the Manso implementation by allowing a and b
56 // parameters per chamber and not just per station.
57 // The default values are derived from the work done in
58 // "A first algorithm for dimuon High Level Trigger"
59 // Ref ID: ALICE-INT-2002-04 version 1.0
60 Float AliHLTMUONCoreMansoTracker::fgA7 = 0.016f;
61 Float AliHLTMUONCoreMansoTracker::fgB7 = 2.0f;
62 Float AliHLTMUONCoreMansoTracker::fgA8 = 0.016f;
63 Float AliHLTMUONCoreMansoTracker::fgB8 = 2.0f;
64 Float AliHLTMUONCoreMansoTracker::fgA9 = 0.020f;
65 Float AliHLTMUONCoreMansoTracker::fgB9 = 3.0f;
66 Float AliHLTMUONCoreMansoTracker::fgA10 = 0.020f;
67 Float AliHLTMUONCoreMansoTracker::fgB10 = 3.0f;
68 Float AliHLTMUONCoreMansoTracker::fgZ7 = 1274.5f;
69 Float AliHLTMUONCoreMansoTracker::fgZ8 = 1305.5f;
70 Float AliHLTMUONCoreMansoTracker::fgZ9 = 1408.6f;
71 Float AliHLTMUONCoreMansoTracker::fgZ10 = 1439.6f;
72 Float AliHLTMUONCoreMansoTracker::fgZ11 = 1603.5f;
73 Float AliHLTMUONCoreMansoTracker::fgZ13 = 1703.5f;
76 void AliHLTMUONCoreMansoTracker::RegionOfInterest::Create(AliHLTMUONCorePoint p, Float a, Float b)
79 // Compute the radius Rp
80 Float Rp = (Float) sqrt( p.fX * p.fX + p.fY * p.fY );
82 // The radius Rs for the region of interest is computed from the
83 // specification given in the document:
84 // "A first algorithm for dimuon High Level Trigger"
85 // Ref ID: ALICE-INT-2002-04 version 1.0
88 // given on page 3 section 4.
93 bool AliHLTMUONCoreMansoTracker::RegionOfInterest::Contains(AliHLTMUONCorePoint p) const
95 // Compute the distance between the centre of the region of interest and
96 // the point p. This distance must be less than the radius of the region
97 // of interest for p to be contained in the region of interest.
98 register Float lx = fCentre.fX - p.fX;
99 register Float ly = fCentre.fY - p.fY;
100 register Float r = (Float) sqrt( lx * lx + ly * ly );
101 DebugMsg(4, "\tRegionOfInterest::Contains : p = " << p
102 << " , centre = " << fCentre << " , r = " << r << " , Rs = " << fRs
108 void AliHLTMUONCoreMansoTracker::RegionOfInterest::GetBoundaryBox(Float& left, Float& right, Float& bottom, Float& top)
110 left = fCentre.fX - fRs;
111 right = fCentre.fX + fRs;
112 bottom = fCentre.fY - fRs;
113 top = fCentre.fY + fRs;
117 AliHLTMUONCoreMansoTracker::Vertex::Vertex(Float x, Float y, Float z)
125 AliHLTMUONCoreMansoTracker::Vertex::Vertex(AliHLTMUONCorePoint xy, Float z)
133 AliHLTMUONCoreMansoTracker::Line::Line(
134 Float Ax, Float Ay, Float Az,
135 Float Bx, Float By, Float Bz
147 AliHLTMUONCoreMansoTracker::Line::Line(Vertex A, Vertex B)
158 AliHLTMUONCorePoint AliHLTMUONCoreMansoTracker::Line::FindIntersectWithXYPlain(Float z) const
160 Assert( fMz != 0.0 ); // Should not have a ray perpendicular to the beam axis.
161 Float t = (z - fCz) / fMz;
162 Float Lx = fMx*t + fCx;
163 Float Ly = fMy*t + fCy;
165 return AliHLTMUONCorePoint(Lx, Ly);
169 AliHLTMUONCoreMansoTracker::AliHLTMUONCoreMansoTracker() : AliHLTMUONCoreTracker()
171 fSm4state = kSM4Idle;
172 fSm5state = kSM5Idle;
173 fRequestsCompleted = 0;
177 void AliHLTMUONCoreMansoTracker::FindTrack(const AliHLTMUONCoreTriggerRecord& trigger)
179 DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
180 DebugMsg(1, "Processing trigger with pt = " << trigger.fPt);
181 fV1 = Vertex( trigger.fStation1impact, fgZ11 );
182 Vertex v2 = Vertex( trigger.fStation2impact, fgZ13 );
184 // Form the vector line between the above two impact points and
185 // find the crossing point of the line with chamber 10 (i.e. station 5).
186 fMc1.fLine = Line(fV1, v2);
187 AliHLTMUONCorePoint p10 = fMc1.fLine.FindIntersectWithXYPlain( fgZ10 );
189 // Build a region of interest for tracking station 5 (chamber 10).
190 // Remember the parameters a and b are station specific.
191 fMc1.fChamber = kChamber10;
192 fMc1.fRoi.Create(p10, fgA10, fgB10);
194 // Make SM5 state transition before the call to RequestClusters since
195 // that method could call one of our methods again, so we need to be
196 // in a consistant internal state.
197 fSm5state = kWaitChamber10;
199 Float left, right, bottom, top;
200 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
201 RequestClusters(left, right, bottom, top, kChamber10, &fMc1);
205 void AliHLTMUONCoreMansoTracker::ReturnClusters(void* tag, const AliHLTMUONCoreClusterPoint* clusters, UInt count)
208 Assert( clusters != NULL );
210 TagData* data = (TagData*)tag;
211 DebugMsg(4, "Got AliHLTMUONCoreMansoTracker::ReturnClusters(tag = " << tag
212 << ", chamber = " << data->fChamber
213 << ", clusters = " << clusters << ", count = " << count << ")"
215 DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
217 switch (data->fChamber)
219 case kChamber7: ReceiveClustersChamber7(clusters, count, data); break;
220 case kChamber8: ReceiveClustersChamber8(clusters, count, data); break;
221 case kChamber9: ReceiveClustersChamber9(clusters, count); break;
222 case kChamber10: ReceiveClustersChamber10(clusters, count); break;
225 DebugMsg(1, "ERROR: Got tag with an invalid value: " << data->fChamber);
230 void AliHLTMUONCoreMansoTracker::EndOfClusters(void* tag)
232 TagData* data = (TagData*)tag;
233 DebugMsg(4, "Got AliHLTMUONCoreMansoTracker::EndOfClusters(chamber = " << data->fChamber << ")");
234 DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
236 switch (data->fChamber)
238 case kChamber7: EndOfClustersChamber7(); break;
239 case kChamber8: EndOfClustersChamber8(); break;
240 case kChamber9: EndOfClustersChamber9(); break;
241 case kChamber10: EndOfClustersChamber10(); break;
244 DebugMsg(1, "ERROR: Got tag with an invalid value: " << data->fChamber);
249 void AliHLTMUONCoreMansoTracker::FillTrackData(AliHLTMUONCoreTrack& track)
251 DebugMsg(4, "FillTrack: st5 = " << fSt5rec->fClusterPoint << ", st4 = " << fFoundPoint->fClusterPoint);
253 Float x1 = fFoundPoint->fClusterPoint.fX;
254 Float y1 = fFoundPoint->fClusterPoint.fY;
255 Float y2 = fSt5rec->fClusterPoint.fY;
257 Float pt = AliHLTMUONCoreCalculateSignedPt(x1, y1, y2, fSt4z, fSt5z, momentum);
258 DebugMsg(1, "Calculated Pt = " << pt);
259 DebugMsg(1, "\tusing x1 = " << x1 << " , y1 = " << y1 << " , y2 = " << y2
260 << " , z1 = " << fSt4z << " , z2 = " << fSt5z
264 track.fSign = kSignMinus;
266 track.fSign = kSignPlus;
268 track.fSign = kUnknownSign;
271 track.fPt = (Float) fabs(pt);
272 for (UInt i = 0; i < 6; i++)
274 track.fPoint[i] = AliHLTMUONCorePoint(0.0, 0.0);
275 track.fRegion[i] = kINVALID_ROI;
278 Float left, right, bottom, top;
280 // Have to create the ROI numbers from the internal region of interest structures.
281 fSt5rec->fTag.fRoi.GetBoundaryBox(left, right, bottom, top);
282 AliHLTMUONCoreRegionOfInterest region4(left, right, bottom, top, fSt4chamber);
283 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
284 AliHLTMUONCoreRegionOfInterest region5(left, right, bottom, top, fMc1.fChamber);
286 // Depending on the chamber we received cluster points from, fill the appropriate
287 // point and ROI number. This is done for station 4 then 5.
288 if (fSt4chamber == kChamber8)
290 track.fPoint[6] = AliHLTMUONCorePoint(0.0, 0.0);
291 track.fRegion[6] = kINVALID_ROI;
292 track.fPoint[7] = fFoundPoint->fClusterPoint;
293 track.fRegion[7] = region4;
297 track.fPoint[6] = fFoundPoint->fClusterPoint;
298 track.fRegion[6] = region4;
299 track.fPoint[7] = AliHLTMUONCorePoint(0.0, 0.0);
300 track.fRegion[7] = kINVALID_ROI;
302 if (fMc1.fChamber == kChamber10)
304 track.fPoint[8] = AliHLTMUONCorePoint(0.0, 0.0);
305 track.fRegion[8] = kINVALID_ROI;
306 track.fPoint[9] = fSt5rec->fClusterPoint;
307 track.fRegion[9] = region5;
311 track.fPoint[8] = fSt5rec->fClusterPoint;
312 track.fRegion[8] = region5;
313 track.fPoint[9] = AliHLTMUONCorePoint(0.0, 0.0);
314 track.fRegion[9] = kINVALID_ROI;
319 void AliHLTMUONCoreMansoTracker::Reset()
321 DebugMsg(4, "SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
324 fSm4state = kSM4Idle;
325 fSm5state = kSM5Idle;
326 fRequestsCompleted = 0;
330 // Note: In the following ReceiveClustersXXX and EndOfClustersXXX methods we make
331 // the state machine transitions before calls to RequestClusters, FoundTrack,
332 // NoTrackFound or EndOfClusterRequests. This is important since the callback
333 // object will make recursive calls to the tracker's methods so we need to maintain
334 // a consistant internal state.
335 // The same would go for updating internal variables.
336 // In general one should only call the callback methods at the end of any of the
337 // following routines.
339 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber7(
340 const AliHLTMUONCoreClusterPoint* clusters, UInt count, const TagData* data
346 fSm4state = kWaitMoreChamber7;
348 case kWaitMoreChamber7:
349 for (UInt j = 0; j < count; j++)
351 AliHLTMUONCoreClusterPoint cluster = clusters[j];
352 // Check that the cluster actually is in our region of interest on station 4.
353 if ( data->fRoi.Contains(cluster) )
355 DebugMsg(4, "Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 7.");
356 Station4Data* newdata = fSt4points.New();
357 newdata->fClusterPoint = cluster;
358 newdata->fSt5tag = data;
364 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber7!");
369 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber8(
370 const AliHLTMUONCoreClusterPoint* clusters, UInt count, const TagData* data
376 fSm4state = kWaitMoreChamber8;
378 fSt4chamber = kChamber8;
380 case kWaitMoreChamber8:
381 for (UInt j = 0; j < count; j++)
383 AliHLTMUONCoreClusterPoint cluster = clusters[j];
384 // Check that the cluster actually is in our region of interest on station 4.
385 if ( data->fRoi.Contains(cluster) )
387 DebugMsg(4, "Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 8.");
388 Station4Data* newdata = fSt4points.New();
389 newdata->fClusterPoint = cluster;
390 newdata->fSt5tag = data;
396 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber8!");
401 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber9(const AliHLTMUONCoreClusterPoint* clusters, UInt count)
406 fSm5state = kWaitMoreChamber9;
407 fSm4state = kWaitChamber8; // Start SM4.
409 case kWaitMoreChamber9:
410 for (UInt j = 0; j < count; j++)
412 AliHLTMUONCoreClusterPoint cluster = clusters[j];
413 // Check that the cluster actually is in our region of interest on station 5.
414 if ( fMc1.fRoi.Contains(cluster) )
416 DebugMsg(4, "Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 9.");
417 Station5Data* data = fSt5data.New();
418 data->fClusterPoint = cluster;
419 ProjectToStation4(data, fgZ9); // This adds a new request for station 4.
425 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber9!");
430 void AliHLTMUONCoreMansoTracker::ReceiveClustersChamber10(const AliHLTMUONCoreClusterPoint* clusters, UInt count)
435 fSm5state = kWaitMoreChamber10;
437 fSm4state = kWaitChamber8; // Start SM4.
439 case kWaitMoreChamber10:
440 for (UInt j = 0; j < count; j++)
442 AliHLTMUONCoreClusterPoint cluster = clusters[j];
443 // Check that the cluster actually is in our region of interest on station 5.
444 if ( fMc1.fRoi.Contains(cluster) )
446 DebugMsg(4, "Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 10.");
447 Station5Data* data = fSt5data.New();
448 data->fClusterPoint = cluster;
449 ProjectToStation4(data, fgZ10); // This adds a new request for station 4.
455 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::ReceiveClustersChamber10!");
460 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber7()
462 fRequestsCompleted++; // Increment the number of requests completed for station 4.
463 DebugMsg(4, "fRequestsCompleted = " << fRequestsCompleted );
468 // If all data from station 5 is received and no data found on
469 // chambers 7 or 8 then we can not find a track.
470 if (fSm5state == kSM5Done) NoTrackFound();
473 case kWaitMoreChamber7:
474 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
479 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber7!");
484 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber8()
486 fRequestsCompleted++; // Increment the number of requests completed for station 4.
487 DebugMsg(4, "fRequestsCompleted = " << fRequestsCompleted );
492 // Ignore. The requests for chamber 8 are already re-requested below.
497 fSm4state = kWaitChamber7;
499 fSt4chamber = kChamber7;
501 // We need to resend the requests for chamber 8, but change the request
502 // to get data for chamber 7 instead:
503 UInt reqlistsize = fSt5data.Count();
504 DebugMsg(4, "Re-requesting clusters from chamber 7... reqlistsize = " << reqlistsize);
506 Station5List::Iterator rec = fSt5data.First();
507 for (UInt i = 0; i < reqlistsize; i++, rec++)
509 // Need to create a new st5 data block for the request.
510 Station5Data* data = fSt5data.New();
511 data->fClusterPoint = rec->fClusterPoint;
512 data->fTag.fLine = rec->fTag.fLine;
514 // Rebuild a region of interest for chamber 7.
515 // Remember the parameters a and b are station specific.
516 AliHLTMUONCorePoint p7 = data->fTag.fLine.FindIntersectWithXYPlain( fgZ7 );
517 data->fTag.fChamber = kChamber7;
518 data->fTag.fRoi.Create(p7, fgA7, fgB7);
520 Float left, right, bottom, top;
521 data->fTag.fRoi.GetBoundaryBox(left, right, bottom, top);
522 // Make request for chamber 7 data.
523 RequestClusters(left, right, bottom, top, kChamber7, &data->fTag);
528 case kWaitMoreChamber8:
529 if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
534 DebugMsg(1, "ERROR: Unexpected state for SM4 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber8!");
539 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber9()
544 fSm5state = kSM5Done;
545 EndOfClusterRequests();
549 case kWaitMoreChamber9:
550 fSm5state = kSM5Done;
551 EndOfClusterRequests();
552 if (fRequestsCompleted == fSt5data.Count())
557 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber9!");
562 void AliHLTMUONCoreMansoTracker::EndOfClustersChamber10()
568 fSm5state = kWaitChamber9;
571 // No clusters found on chamber 10 so we need to make a request for
572 // clusters from chamber 9:
573 AliHLTMUONCorePoint p9 = fMc1.fLine.FindIntersectWithXYPlain( fgZ9 );
575 // Build a region of interest for tracking station 5 (chamber 9).
576 // Remember the parameters a and b are station specific.
577 fMc1.fChamber = kChamber9;
578 fMc1.fRoi.Create(p9, fgA9, fgB9);
580 Float left, right, bottom, top;
581 fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
582 RequestClusters(left, right, bottom, top, kChamber9, &fMc1);
586 case kWaitMoreChamber10:
587 fSm5state = kSM5Done;
588 EndOfClusterRequests();
589 if (fRequestsCompleted == fSt5data.Count())
594 DebugMsg(1, "ERROR: Unexpected state for SM5 in AliHLTMUONCoreMansoTracker::EndOfClustersChamber10!");
599 void AliHLTMUONCoreMansoTracker::ProjectToStation4(Station5Data* data, register Float station5z)
601 // Perform chamber specific operations:
602 // Since certain states of SM4 means that it is fetching for Chamber8
603 // and other states are for fetching from Chamber7. We need to make
604 // requests for the correct chamber.
605 Assert( fSm4state == kWaitChamber8
606 || fSm4state == kWaitMoreChamber8
607 || fSm4state == kWaitChamber7
608 || fSm4state == kWaitMoreChamber7
610 TagData* tag = &data->fTag;
611 if (fSm4state == kWaitChamber8 || fSm4state == kWaitMoreChamber8)
613 // Form the vector line between trigger station 1 and tracking station 5,
614 // and find the intersection point of the line with station 4 (chamber8).
615 Line line51( Vertex(data->fClusterPoint, station5z), fV1 );
616 AliHLTMUONCorePoint intercept = line51.FindIntersectWithXYPlain( fgZ8 );
619 // Build a region of interest for tracking station 4.
620 tag->fChamber = kChamber8;
621 tag->fRoi.Create(intercept, fgA8, fgB8);
625 // Form the vector line between trigger station 1 and tracking station 5,
626 // and find the intersection point of the line with station 4 (chamber7).
627 Line line51( Vertex(data->fClusterPoint, station5z), fV1 );
628 AliHLTMUONCorePoint intercept = line51.FindIntersectWithXYPlain( fgZ7 );
631 // Build a region of interest for tracking station 4.
632 tag->fChamber = kChamber7;
633 tag->fRoi.Create(intercept, fgA7, fgB7);
636 // Make the request for clusters from station 4.
637 Float left, right, bottom, top;
638 tag->fRoi.GetBoundaryBox(left, right, bottom, top);
639 RequestClusters(left, right, bottom, top, tag->fChamber, tag);
643 void AliHLTMUONCoreMansoTracker::ProcessClusters()
645 DebugMsg(2, "ProcessClusters...");
647 // Check if the cluster point list on station 4 is empty.
648 // If it is then we have not found any tracks.
649 fFoundPoint = fSt4points.First();
650 if (fFoundPoint == fSt4points.End())
656 fSt5rec = fSt5data.First();
657 if (fSt5rec != fSt5data.End())
659 // Only look at station 5 data records that are for the found chamber number.
660 // Note: either we only have chamber 8 data or we have chamber 7 data followed
661 // by chamber 8 data.
662 // Thus if we hit records that we are not interested in already then the list
663 // contains no interesting data and we can signal no track found.
664 if (fSt5rec->fTag.fChamber != fSt4chamber)
670 // For all combinations of cluster point pairs from station 4 and 5
671 // signal a found track:
674 DebugMsg(4, "\tfSt5rec->fTag.chamber = " << fSt5rec->fTag.fChamber
675 << " , fSt4chamber = " << fSt4chamber
678 for (fFoundPoint = fSt4points.First(); fFoundPoint != fSt4points.End(); fFoundPoint++)
680 if (fFoundPoint->fSt5tag == &fSt5rec->fTag)
684 fSt5rec++; // Get next station 5 cluster point.
685 } while (fSt5rec != fSt5data.End() && fSt5rec->fTag.fChamber == fSt4chamber);