]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Merging files and moving them to their correct position.
authorszostak <szostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 29 May 2007 04:24:34 +0000 (04:24 +0000)
committerszostak <szostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 29 May 2007 04:24:34 +0000 (04:24 +0000)
HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.cxx [new file with mode: 0644]
HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.h [new file with mode: 0644]

diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.cxx b/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.cxx
new file mode 100644 (file)
index 0000000..c6b375d
--- /dev/null
@@ -0,0 +1,769 @@
+/**************************************************************************
+ * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Author: Artur Szostak
+// Email:  artur@alice.phy.uct.ac.za | artursz@iafrica.com
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "AliHLTMUONMansoTrackerFSM.h"
+#include "AliHLTMUONCalculations.h"
+#include "AliHLTMUONUtils.h"
+#include <cmath>
+
+
+#ifdef DEBUG
+#include <ostream>
+namespace
+{
+
+std::ostream& operator << (std::ostream& os, AliHLTMUONMansoTrackerFSM::StatesSM4 state)
+{
+       switch (state)
+       {
+       case AliHLTMUONMansoTrackerFSM::kSM4Idle:          os << "kSM4Idle"; break;
+       case AliHLTMUONMansoTrackerFSM::kWaitChamber8:     os << "kWaitChamber8"; break;
+       case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber8: os << "kWaitMoreChamber8"; break;
+       case AliHLTMUONMansoTrackerFSM::kWaitChamber7:     os << "kWaitChamber7"; break;
+       case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber7: os << "kWaitMoreChamber7"; break;
+       default:                             os << "FAULT!!"; 
+       }
+       return os;
+}
+
+std::ostream& operator << (std::ostream& os, AliHLTMUONMansoTrackerFSM::StatesSM5 state)
+{
+       switch (state)
+       {
+       case AliHLTMUONMansoTrackerFSM::kSM5Idle:           os << "kSM5Idle"; break;
+       case AliHLTMUONMansoTrackerFSM::kWaitChamber10:     os << "kWaitChamber10"; break;
+       case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber10: os << "kWaitMoreChamber10"; break;
+       case AliHLTMUONMansoTrackerFSM::kWaitChamber9:      os << "kWaitChamber9"; break;
+       case AliHLTMUONMansoTrackerFSM::kWaitMoreChamber9:  os << "kWaitMoreChamber9"; break;
+       case AliHLTMUONMansoTrackerFSM::kSM5Done:           os << "kSM5Done"; break;
+       default:                              os << "FAULT!!"; 
+       }
+       return os;
+}
+
+} // end of namespace
+#endif // DEBUG
+
+
+// Deviate from the Manso implementation by allowing a and b
+// parameters per chamber and not just per station.
+// The default values are derived from the work done in
+//    "A first algorithm for dimuon High Level Trigger"
+//    Ref ID:  ALICE-INT-2002-04 version 1.0
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA7  = 0.016f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB7  = 2.0f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA8  = 0.016f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB8  = 2.0f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA9  = 0.020f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB9  = 3.0f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgA10 = 0.020f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgB10 = 3.0f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ7  = 1274.5f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ8  = 1305.5f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ9  = 1408.6f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ10 = 1439.6f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ11 = 1603.5f;
+AliHLTFloat32_t AliHLTMUONMansoTrackerFSM::fgZ13 = 1703.5f;
+
+
+void AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::Create(AliHLTMUONCorePoint p, AliHLTFloat32_t a, AliHLTFloat32_t b)
+{
+// Creates a region of interest specific to the Manso algorithm from a point and
+// two Manso specific parameters.
+
+       fCentre = p;
+       // Compute the radius Rp
+       AliHLTFloat32_t rp = (AliHLTFloat32_t) sqrt( p.X() * p.X() + p.Y() * p.Y() );
+
+       // The radius Rs for the region of interest is computed from the
+       // specification given in the document:
+       //   "A first algorithm for dimuon High Level Trigger"
+       //   Ref ID:  ALICE-INT-2002-04 version 1.0
+       //   equation:
+       //     Rs = a * Rp + b
+       //   given on page 3 section 4.
+       fRs = a * rp + b;
+}
+
+
+bool AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::Contains(AliHLTMUONCorePoint p) const
+{
+       // Compute the distance between the centre of the region of interest and
+       // the point p. This distance must be less than the radius of the region
+       // of interest for p to be contained in the region of interest.
+       register AliHLTFloat32_t lx = fCentre.X() - p.X();
+       register AliHLTFloat32_t ly = fCentre.Y() - p.Y();
+       register AliHLTFloat32_t r = (AliHLTFloat32_t) sqrt( lx * lx + ly * ly );
+       DebugTrace("\tAliRegionOfInterest::Contains : p = " << p
+               << " , centre = " << fCentre << " , r = " << r << " , Rs = " << fRs
+       );
+       return r <= fRs;
+}
+
+
+void AliHLTMUONMansoTrackerFSM::AliRegionOfInterest::GetBoundaryBox(
+               AliHLTFloat32_t& left, AliHLTFloat32_t& right, AliHLTFloat32_t& bottom, AliHLTFloat32_t& top
+       ) const
+{
+// Works out the smallest boundary box that will contain the region of interest.
+
+       left = fCentre.X() - fRs;
+       right = fCentre.X() + fRs;
+       bottom = fCentre.Y() - fRs;
+       top = fCentre.Y() + fRs;
+}
+
+
+AliHLTMUONMansoTrackerFSM::AliVertex::AliVertex(AliHLTFloat32_t x, AliHLTFloat32_t y, AliHLTFloat32_t z)
+       : fX(x), fY(y), fZ(z)
+{
+// Constructor for vertex.
+
+       fX = x;
+       fY = y;
+       fZ = z;
+}
+
+
+AliHLTMUONMansoTrackerFSM::AliVertex::AliVertex(AliHLTMUONCorePoint xy, AliHLTFloat32_t z)
+       : fX(xy.X()), fY(xy.Y()), fZ(z)
+{
+// Construct vertex from a point on the XY plane and z coordinate.
+
+       fX = xy.X();
+       fY = xy.Y();
+       fZ = z;
+}
+
+
+AliHLTMUONMansoTrackerFSM::AliLine::AliLine(
+        AliHLTFloat32_t ax, AliHLTFloat32_t ay, AliHLTFloat32_t az,
+        AliHLTFloat32_t bx, AliHLTFloat32_t by, AliHLTFloat32_t bz
+    ) :
+       fMx(ax - bx), fMy(ay - by), fMz(az - bz),
+       fCx(bx), fCy(by), fCz(bz)
+{
+// Construct a line defined by L = M*t + C = (A-B)*t + B
+// where M and C are 3D vectors and t is a free parameter.
+// A = (ax, ay, az) and B = (bx, by, bz)
+
+       fMx = ax - bx;
+       fMy = ay - by;
+       fMz = az - bz;
+       fCx = bx;
+       fCy = by;
+       fCz = bz;
+}
+
+
+AliHLTMUONMansoTrackerFSM::AliLine::AliLine(AliVertex a, AliVertex b) :
+       fMx(a.X() - b.X()), fMy(a.Y() - b.Y()), fMz(a.Z() - b.Z()),
+       fCx(b.X()), fCy(b.Y()), fCz(b.Z())
+{
+// Contruct a line to go through two vertices a and b.
+
+       fMx = a.X() - b.X();
+       fMy = a.Y() - b.Y();
+       fMz = a.Z() - b.Z();
+       fCx = b.X();
+       fCy = b.Y();
+       fCz = b.Z();
+}
+
+
+AliHLTMUONCorePoint AliHLTMUONMansoTrackerFSM::AliLine::FindIntersectWithXYPlain(AliHLTFloat32_t z) const
+{
+// Find the point of intersection of the line and the XY plane at z.
+
+       Assert( fMz != 0.0 );    // Should not have a ray perpendicular to the beam axis.
+       AliHLTFloat32_t t = (z - fCz) / fMz;
+       AliHLTFloat32_t lx = fMx*t + fCx;
+       AliHLTFloat32_t ly = fMy*t + fCy;
+
+       return AliHLTMUONCorePoint(lx, ly);
+}
+
+
+AliHLTMUONMansoTrackerFSM::AliHLTMUONMansoTrackerFSM() :
+       fCallback(NULL),
+       fSm4state(kSM4Idle),
+       fSm5state(kSM5Idle),
+       fRequestsCompleted(0),
+       fSt4chamber(kChamber1),
+       fV1(),
+       fMc1(),
+       fSt5z(0),
+       fSt5data(),
+       fSt4z(0),
+       fSt4points(),
+       fSt5rec(),
+       fFoundPoint()
+{
+// Default constructor
+}
+
+
+void AliHLTMUONMansoTrackerFSM::FindTrack(const AliHLTMUONCoreTriggerRecord& trigger)
+{
+// Tries to find the track from the trigger seed.
+
+       DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
+       DebugTrace("Processing trigger with pt = " << trigger.fPt);
+       fV1 = AliVertex( trigger.fStation1impact, fgZ11 );
+       AliVertex v2 = AliVertex( trigger.fStation2impact, fgZ13 );
+
+       // Form the vector line between the above two impact points and
+       // find the crossing point of the line with chamber 10 (i.e. station 5).
+       fMc1.fLine = AliLine(fV1, v2);
+       AliHLTMUONCorePoint p10 = fMc1.fLine.FindIntersectWithXYPlain( fgZ10 );
+
+       // Build a region of interest for tracking station 5 (chamber 10).
+       // Remember the parameters a and b are station specific.
+       fMc1.fChamber = kChamber10;
+       fMc1.fRoi.Create(p10, fgA10, fgB10);
+       
+       // Make SM5 state transition before the call to RequestClusters since
+       // that method could call one of our methods again, so we need to be
+       // in a consistant internal state.
+       fSm5state = kWaitChamber10;
+
+       AliHLTFloat32_t left, right, bottom, top;
+       fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
+       RequestClusters(left, right, bottom, top, kChamber10, &fMc1);
+}
+
+
+void AliHLTMUONMansoTrackerFSM::ReturnClusters(void* tag, const AliHLTMUONCoreClusterPoint* clusters, UInt count)
+{
+// Implementation of AliHLTMUONCoreTracker::ReturnClusters.
+
+       Assert( count > 0 );
+       Assert( clusters != NULL );
+       
+       AliTagData* data = (AliTagData*)tag;
+       DebugTrace("Got AliHLTMUONMansoTrackerFSM::ReturnClusters(tag = " << tag
+               << ", chamber = " << data->fChamber
+               << ", clusters = " << clusters <<  ", count = " << count << ")"
+       );
+       DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
+
+       switch (data->fChamber)
+       {
+       case kChamber7:  ReceiveClustersChamber7(clusters, count, data); break;
+       case kChamber8:  ReceiveClustersChamber8(clusters, count, data); break;
+       case kChamber9:  ReceiveClustersChamber9(clusters, count); break;
+       case kChamber10: ReceiveClustersChamber10(clusters, count); break;
+       default:
+               // Error
+               DebugTrace("ERROR: Got tag with an invalid value: " << data->fChamber);
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::EndOfClusters(void* tag)
+{
+// Implementation of AliHLTMUONCoreTracker::EndOfClusters.
+
+       AliTagData* data = (AliTagData*)tag;
+       DebugTrace("Got AliHLTMUONMansoTrackerFSM::EndOfClusters(chamber = " << data->fChamber << ")");
+       DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
+
+       switch (data->fChamber)
+       {
+       case kChamber7:  EndOfClustersChamber7(); break;
+       case kChamber8:  EndOfClustersChamber8(); break;
+       case kChamber9:  EndOfClustersChamber9(); break;
+       case kChamber10: EndOfClustersChamber10(); break;
+       default:
+               // Error
+               DebugTrace("ERROR: Got tag with an invalid value: " << data->fChamber);
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::FillTrackData(AliHLTMUONCoreTrack& track)
+{
+// Implementation of AliHLTMUONCoreTracker::FillTrackData
+
+       DebugTrace("FillTrack: st5 = " << fSt5rec->fClusterPoint << ", st4 = " << fFoundPoint->fClusterPoint);
+       
+       AliHLTFloat32_t x1 = fFoundPoint->fClusterPoint.X();
+       AliHLTFloat32_t y1 = fFoundPoint->fClusterPoint.Y();
+       AliHLTFloat32_t y2 = fSt5rec->fClusterPoint.Y();
+       AliHLTFloat32_t momentum;
+       AliHLTFloat32_t pt = AliHLTMUONCoreCalculateSignedPt(x1, y1, y2, fSt4z, fSt5z, momentum);
+       DebugTrace("Calculated Pt = " << pt);
+       DebugTrace("\tusing x1 = " << x1 << " , y1 = " << y1 << " , y2 = " << y2
+               << " , z1 = " << fSt4z << " , z2 = " << fSt5z
+       );
+
+       if (pt < 0)
+               track.fSign = kSignMinus;
+       else if (pt > 0)
+               track.fSign = kSignPlus;
+       else
+               track.fSign = kUnknownSign;
+
+       track.fP = momentum;
+       track.fPt = (AliHLTFloat32_t) fabs(pt);
+       for (UInt i = 0; i < 6; i++)
+       {
+               track.fPoint[i] = AliHLTMUONCorePoint(0.0, 0.0);
+               track.fRegion[i] = kInvalidROI;
+       }
+
+       AliHLTFloat32_t left, right, bottom, top;
+       
+       // Have to create the ROI numbers from the internal region of interest structures.
+       fSt5rec->fTag.fRoi.GetBoundaryBox(left, right, bottom, top);
+       AliHLTMUONCoreRegionOfInterest region4(left, right, bottom, top, fSt4chamber);
+       fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
+       AliHLTMUONCoreRegionOfInterest region5(left, right, bottom, top, fMc1.fChamber);
+       
+       // Depending on the chamber we received cluster points from, fill the appropriate
+       // point and ROI number. This is done for station 4 then 5.
+       if (fSt4chamber == kChamber8)
+       {
+               track.fPoint[6] = AliHLTMUONCorePoint(0.0, 0.0);
+               track.fRegion[6] = kInvalidROI;
+               track.fPoint[7] = fFoundPoint->fClusterPoint;
+               track.fRegion[7] = region4;
+       }
+       else
+       {
+               track.fPoint[6] = fFoundPoint->fClusterPoint;
+               track.fRegion[6] = region4;
+               track.fPoint[7] = AliHLTMUONCorePoint(0.0, 0.0);
+               track.fRegion[7] = kInvalidROI;
+       }
+       if (fMc1.fChamber == kChamber10)
+       {
+               track.fPoint[8] = AliHLTMUONCorePoint(0.0, 0.0);
+               track.fRegion[8] = kInvalidROI;
+               track.fPoint[9] = fSt5rec->fClusterPoint;
+               track.fRegion[9] = region5;
+       }
+       else
+       {
+               track.fPoint[8] = fSt5rec->fClusterPoint;
+               track.fRegion[8] = region5;
+               track.fPoint[9] = AliHLTMUONCorePoint(0.0, 0.0);
+               track.fRegion[9] = kInvalidROI;
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::Reset()
+{
+// Implementation of AliHLTMUONCoreTracker::Reset
+
+       DebugTrace("SM5 state = " << fSm5state << " , SM4 state = " << fSm4state);
+       fSt5data.Clear();
+       fSt4points.Clear();
+       fSm4state = kSM4Idle;
+       fSm5state = kSM5Idle;
+       fRequestsCompleted = 0;
+}
+
+
+// Note: In the following ReceiveClustersXXX and EndOfClustersXXX methods we make
+// the state machine transitions before calls to RequestClusters, FoundTrack, 
+// NoTrackFound or EndOfClusterRequests. This is important since the callback
+// object will make recursive calls to the tracker's methods so we need to maintain
+// a consistant internal state.
+// The same would go for updating internal variables.
+// In general one should only call the callback methods at the end of any of the
+// following routines.
+
+void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7(
+               const AliHLTMUONCoreClusterPoint* clusters, UInt count, const AliTagData* data
+       )
+{
+// State change method for Station 4 state machine.
+
+       switch (fSm4state)
+       {
+       case kWaitChamber7:
+               fSm4state = kWaitMoreChamber7;
+       
+       case kWaitMoreChamber7:
+               for (UInt j = 0; j < count; j++)
+               {
+                       AliHLTMUONCoreClusterPoint cluster = clusters[j];
+                       // Check that the cluster actually is in our region of interest on station 4.
+                       if ( data->fRoi.Contains(cluster) )
+                       {
+                               DebugTrace("Adding cluster [" << cluster.X() << ", " << cluster.Y() << "] from chamber 7.");
+                               AliStation4Data* newdata = fSt4points.New();
+                               newdata->fClusterPoint = cluster;
+                               newdata->fSt5tag = data;
+                       }
+               }
+               break;
+       
+       default:
+               DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7!");
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8(
+               const AliHLTMUONCoreClusterPoint* clusters, UInt count, const AliTagData* data
+       )
+{
+// State change method for Station 4 state machine.
+
+       switch (fSm4state)
+       {
+       case kWaitChamber8:
+               fSm4state = kWaitMoreChamber8;
+               fSt4z = fgZ8;
+               fSt4chamber = kChamber8;
+       
+       case kWaitMoreChamber8:
+               for (UInt j = 0; j < count; j++)
+               {
+                       AliHLTMUONCoreClusterPoint cluster = clusters[j];
+                       // Check that the cluster actually is in our region of interest on station 4.
+                       if ( data->fRoi.Contains(cluster) )
+                       {
+                               DebugTrace("Adding cluster [" << cluster.X() << ", " << cluster.Y() << "] from chamber 8.");
+                               AliStation4Data* newdata = fSt4points.New();
+                               newdata->fClusterPoint = cluster;
+                               newdata->fSt5tag = data;
+                       }
+               }
+               break;
+               
+       default:
+               DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8!");
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9(const AliHLTMUONCoreClusterPoint* clusters, UInt count)
+{
+// State change method for Station 5 state machine.
+
+       switch (fSm5state)
+       {
+       case kWaitChamber9:
+               fSm5state = kWaitMoreChamber9;
+               fSm4state = kWaitChamber8;  // Start SM4.
+       
+       case kWaitMoreChamber9:
+               for (UInt j = 0; j < count; j++)
+               {
+                       AliHLTMUONCoreClusterPoint cluster = clusters[j];
+                       // Check that the cluster actually is in our region of interest on station 5.
+                       if ( fMc1.fRoi.Contains(cluster) )
+                       {
+                               DebugTrace("Adding cluster [" << cluster.X() << ", " << cluster.Y() << "] from chamber 9.");
+                               AliStation5Data* data = fSt5data.New();
+                               data->fClusterPoint = cluster;
+                               ProjectToStation4(data, fgZ9);  // This adds a new request for station 4.
+                       }
+               }
+               break;
+
+       default:
+               DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9!");
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10(const AliHLTMUONCoreClusterPoint* clusters, UInt count)
+{
+// State change method for Station 5 state machine.
+
+       switch (fSm5state)
+       {
+       case kWaitChamber10:
+               fSm5state = kWaitMoreChamber10;
+               fSt5z = fgZ10;
+               fSm4state = kWaitChamber8;  // Start SM4.
+       
+       case kWaitMoreChamber10:
+               for (UInt j = 0; j < count; j++)
+               {
+                       AliHLTMUONCoreClusterPoint cluster = clusters[j];
+                       // Check that the cluster actually is in our region of interest on station 5.
+                       if ( fMc1.fRoi.Contains(cluster) )
+                       {
+                               DebugTrace(4, "Adding cluster [" << cluster.X() << ", " << cluster.Y() << "] from chamber 10.");
+                               AliStation5Data* data = fSt5data.New();
+                               data->fClusterPoint = cluster;
+                               ProjectToStation4(data, fgZ10);  // This adds a new request for station 4.
+                       }
+               }
+               break;
+
+       default:
+               DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10!");
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7()
+{
+// State change method for Station 4 state machine.
+
+       fRequestsCompleted++;  // Increment the number of requests completed for station 4.
+       DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
+
+       switch (fSm4state)
+       {
+       case kWaitChamber7:
+               // If all data from station 5 is received and no data found on
+               // chambers 7 or 8 then we can not find a track.
+               if (fSm5state == kSM5Done) NoTrackFound();
+               break;
+       
+       case kWaitMoreChamber7:
+               if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
+                       ProcessClusters();
+               break;
+       
+       default:
+               DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber7!");
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8()
+{
+// State change method for Station 4 state machine.
+
+       fRequestsCompleted++;  // Increment the number of requests completed for station 4.
+       DebugTrace("fRequestsCompleted = " << fRequestsCompleted );
+
+       switch (fSm4state)
+       {
+       case kWaitChamber7:
+               // Ignore. The requests for chamber 8 are already re-requested below.
+               break;
+               
+       case kWaitChamber8:
+               {
+               fSm4state = kWaitChamber7;
+               fSt4z = fgZ7;
+               fSt4chamber = kChamber7;
+       
+               // We need to resend the requests for chamber 8, but change the request
+               // to get data for chamber 7 instead:
+               UInt reqlistsize = fSt5data.Count();
+               DebugTrace("Re-requesting clusters from chamber 7... reqlistsize = " << reqlistsize);
+
+               Station5List::Iterator rec = fSt5data.First();
+               for (UInt i = 0; i < reqlistsize; i++, rec++)
+               {
+                       // Need to create a new st5 data block for the request.
+                       AliStation5Data* data = fSt5data.New();
+                       data->fClusterPoint = rec->fClusterPoint;
+                       data->fTag.fLine = rec->fTag.fLine;
+
+                       // Rebuild a region of interest for chamber 7.
+                       // Remember the parameters a and b are station specific.
+                       AliHLTMUONCorePoint p7 = data->fTag.fLine.FindIntersectWithXYPlain( fgZ7 );
+                       data->fTag.fChamber = kChamber7;
+                       data->fTag.fRoi.Create(p7, fgA7, fgB7);
+                       
+                       AliHLTFloat32_t left, right, bottom, top;
+                       data->fTag.fRoi.GetBoundaryBox(left, right, bottom, top);
+                       // Make request for chamber 7 data.
+                       RequestClusters(left, right, bottom, top, kChamber7, &data->fTag);
+               }
+               }
+               break;
+       
+       case kWaitMoreChamber8:
+               if (fRequestsCompleted == fSt5data.Count() && fSm5state == kSM5Done)
+                       ProcessClusters();
+               break;
+       
+       default:
+               DebugTrace("ERROR: Unexpected state for SM4 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8!");
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9()
+{
+// State change method for Station 5 state machine.
+
+       switch (fSm5state)
+       {
+       case kWaitChamber9:
+               fSm5state = kSM5Done;
+               EndOfClusterRequests();
+               NoTrackFound();
+               break;
+               
+       case kWaitMoreChamber9:
+               fSm5state = kSM5Done;
+               EndOfClusterRequests();
+               if (fRequestsCompleted == fSt5data.Count())
+                       ProcessClusters();
+               break;
+
+       default:
+               DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber9!");
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10()
+{
+// State change method for Station 5 state machine.
+
+       switch (fSm5state)
+       {
+       case kWaitChamber10:
+               {
+               fSm5state = kWaitChamber9;
+               fSt5z = fgZ9;
+               
+               // No clusters found on chamber 10 so we need to make a request for
+               // clusters from chamber 9:
+               AliHLTMUONCorePoint p9 = fMc1.fLine.FindIntersectWithXYPlain( fgZ9 );
+
+               // Build a region of interest for tracking station 5 (chamber 9).
+               // Remember the parameters a and b are station specific.
+               fMc1.fChamber = kChamber9;
+               fMc1.fRoi.Create(p9, fgA9, fgB9);
+
+               AliHLTFloat32_t left, right, bottom, top;
+               fMc1.fRoi.GetBoundaryBox(left, right, bottom, top);
+               RequestClusters(left, right, bottom, top, kChamber9, &fMc1);
+               }
+               break;
+
+       case kWaitMoreChamber10:
+               fSm5state = kSM5Done;
+               EndOfClusterRequests();
+               if (fRequestsCompleted == fSt5data.Count())
+                       ProcessClusters();
+               break;
+
+       default:
+               DebugTrace("ERROR: Unexpected state for SM5 in AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10!");
+       }
+}
+
+
+void AliHLTMUONMansoTrackerFSM::ProjectToStation4(AliStation5Data* data, register AliHLTFloat32_t station5z)
+{
+       // Perform chamber specific operations:
+       // Since certain states of SM4 means that it is fetching for Chamber8
+       // and other states are for fetching from Chamber7. We need to make
+       // requests for the correct chamber.
+       Assert( fSm4state == kWaitChamber8 
+               || fSm4state == kWaitMoreChamber8
+               || fSm4state == kWaitChamber7
+               || fSm4state == kWaitMoreChamber7
+       );
+       AliTagData* tag = &data->fTag;
+       if (fSm4state == kWaitChamber8 || fSm4state == kWaitMoreChamber8)
+       {
+               // Form the vector line between trigger station 1 and tracking station 5,
+               // and find the intersection point of the line with station 4 (chamber8).
+               AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
+               AliHLTMUONCorePoint intercept = line51.FindIntersectWithXYPlain( fgZ8 );
+               tag->fLine = line51;
+               
+               // Build a region of interest for tracking station 4.
+               tag->fChamber = kChamber8;
+               tag->fRoi.Create(intercept, fgA8, fgB8);
+       }
+       else
+       {
+               // Form the vector line between trigger station 1 and tracking station 5,
+               // and find the intersection point of the line with station 4 (chamber7).
+               AliLine line51( AliVertex(data->fClusterPoint, station5z), fV1 );
+               AliHLTMUONCorePoint intercept = line51.FindIntersectWithXYPlain( fgZ7 );
+               tag->fLine = line51;
+               
+               // Build a region of interest for tracking station 4.
+               tag->fChamber = kChamber7;
+               tag->fRoi.Create(intercept, fgA7, fgB7);
+       }
+
+       // Make the request for clusters from station 4.
+       AliHLTFloat32_t left, right, bottom, top;
+       tag->fRoi.GetBoundaryBox(left, right, bottom, top);
+       RequestClusters(left, right, bottom, top, tag->fChamber, tag);
+}
+
+
+void AliHLTMUONMansoTrackerFSM::ProcessClusters()
+{
+// Process clusters that have been received.
+// This is called once all clusters have been found.
+
+       DebugTrace("ProcessClusters...");
+       
+       // Check if the cluster point list on station 4 is empty.
+       // If it is then we have not found any tracks.
+       fFoundPoint = fSt4points.First();
+       if (fFoundPoint == fSt4points.End())
+       {
+               NoTrackFound();
+               return;
+       }
+       
+       fSt5rec = fSt5data.First();
+       if (fSt5rec != fSt5data.End())
+       {
+               // Only look at station 5 data records that are for the found chamber number.
+               // Note: either we only have chamber 8 data or we have chamber 7 data followed
+               // by chamber 8 data.
+               // Thus if we hit records that we are not interested in already then the list
+               // contains no interesting data and we can signal no track found.
+               if (fSt5rec->fTag.fChamber != fSt4chamber)
+               {
+                       NoTrackFound();
+                       return;
+               }
+                
+               // For all combinations of cluster point pairs from station 4 and 5
+               // signal a found track:
+               do
+               {
+                       DebugTrace("\tfSt5rec->fTag.chamber = " << fSt5rec->fTag.fChamber
+                               << " , fSt4chamber = " << fSt4chamber
+                       );
+
+                       for (fFoundPoint = fSt4points.First(); fFoundPoint != fSt4points.End(); fFoundPoint++)
+                       {
+                               if (fFoundPoint->fSt5tag == &fSt5rec->fTag)
+                                       FoundTrack();
+                       }
+
+                       fSt5rec++;  // Get next station 5 cluster point.
+               } while (fSt5rec != fSt5data.End() && fSt5rec->fTag.fChamber == fSt4chamber);
+       }
+       else
+               NoTrackFound();
+}
+
diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.h b/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.h
new file mode 100644 (file)
index 0000000..0d14741
--- /dev/null
@@ -0,0 +1,408 @@
+#ifndef ALIHLTMUONMANSOTRACKERFSM_H
+#define ALIHLTMUONMANSOTRACKERFSM_H
+/* Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Author: Artur Szostak
+// Email:  artur@alice.phy.uct.ac.za | artursz@iafrica.com
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "AliHLTMUONDataTypes.h"
+#include "AliHLTMUONList.h"
+#include "AliHLTMUONCountedList.h"
+#include "AliHLTMUONRecHitsBlockStruct.h"
+
+
+class AliHLTMUONMansoTrackerFSM : public AliHLTMUONCoreTracker
+{
+public:
+
+       AliHLTMUONMansoTrackerFSM();
+       virtual ~AliHLTMUONMansoTrackerFSM() {}
+
+
+       /* This is the starting point for the tracking algorithm. The tracker is 
+          called at this point with the specified trigger record. It needs to figure
+          out which cluster blocks it needs and request them with calls to
+          RequestClusters.
+          Any memory allocated at this point should be released in the Reset method.
+          
+          Note: Reset should be called for before calling FindTrack, for the
+          second or subsequent method calls to FindTrack.
+        */
+       virtual void FindTrack(const AliHLTMUONCoreTriggerRecord& trigger);
+       
+       /* When requested clusters have been found by the framework they are returned
+          to the tracker using this method.
+          This method should implement any processing of the cluster blocks. If more
+          more regions of interest are identified then appropriate request should me 
+          made using RequestClusters. The tag parameter will be the same one as was
+          passed to RequestClusters.
+        */
+       virtual void ReturnClusters(void* tag, const AliHLTMUONRecHitStruct* clusters, UInt count);
+       
+       /* When no more clusters are to be expected for the request with the corresponding
+          tag value, then this method is called.
+          Any final processing can be placed in here and when the track is found then
+          the algorithm can call FoundTrack otherwise NoTrackFound to indicate end of 
+          processing.
+        */
+       virtual void EndOfClusters(void* tag);
+       
+       /* Called to receive track information after receiving a FoundTrack call.
+          The tracker should fill the track data block with all relevant information.
+          Note: the track.triggerid field need not be filled in this method. It should
+          be overwritten by the caller. 
+        */
+       virtual void FillTrackData(AliHLTMUONCoreTrack& track);
+       
+       /* Called when the tracker should be reset to a initial state. 
+          All extra internal allocated data structured should be released.
+        */
+       virtual void Reset();
+       
+       /* To set the TrackerCallback callback object.
+        */
+       inline void SetCallback(AliHLTMUONCoreTrackerCallback* callback)
+       {
+               fCallback = callback;
+       };
+
+
+       /* Get and set methods for the a and b parameters used to build the region
+          of interests. Refer to MansoFilter() for details about a and b parameters.
+        */
+       static AliHLTFloat32_t GetA7()            { return fgA7; };
+       static void SetA7(AliHLTFloat32_t value)  { fgA7 = value; };
+       static AliHLTFloat32_t GetA8()            { return fgA8; };
+       static void SetA8(AliHLTFloat32_t value)  { fgA8 = value; };
+       static AliHLTFloat32_t GetA9()            { return fgA9; };
+       static void SetA9(AliHLTFloat32_t value)  { fgA9 = value; };
+       static AliHLTFloat32_t GetA10()           { return fgA10; };
+       static void SetA10(AliHLTFloat32_t value) { fgA10 = value; };
+
+       static AliHLTFloat32_t GetB7()            { return fgB7; };
+       static void SetB7(AliHLTFloat32_t value)  { fgB7 = value; };
+       static AliHLTFloat32_t GetB8()            { return fgB8; };
+       static void SetB8(AliHLTFloat32_t value)  { fgB8 = value; };
+       static AliHLTFloat32_t GetB9()            { return fgB9; };
+       static void SetB9(AliHLTFloat32_t value)  { fgB9 = value; };
+       static AliHLTFloat32_t GetB10()           { return fgB10; };
+       static void SetB10(AliHLTFloat32_t value) { fgB10 = value; };
+       
+       static AliHLTFloat32_t GetZ7()            { return fgZ7; };
+       static void SetZ7(AliHLTFloat32_t value)  { fgZ7 = value; };
+       static AliHLTFloat32_t GetZ8()            { return fgZ8; };
+       static void SetZ8(AliHLTFloat32_t value)  { fgZ8 = value; };
+       static AliHLTFloat32_t GetZ9()            { return fgZ9; };
+       static void SetZ9(AliHLTFloat32_t value)  { fgZ9 = value; };
+       static AliHLTFloat32_t GetZ10()           { return fgZ10; };
+       static void SetZ10(AliHLTFloat32_t value) { fgZ10 = value; };
+       static AliHLTFloat32_t GetZ11()           { return fgZ11; };
+       static void SetZ11(AliHLTFloat32_t value) { fgZ11 = value; };
+       static AliHLTFloat32_t GetZ13()           { return fgZ13; };
+       static void SetZ13(AliHLTFloat32_t value) { fgZ13 = value; };
+
+
+protected:
+
+       class AliRegionOfInterest
+       {
+       public:
+               
+               AliRegionOfInterest() : fCentre(), fRs(0.0) {};
+
+               AliRegionOfInterest(AliHLTMUONCorePoint p, AliHLTFloat32_t a, AliHLTFloat32_t b)
+                       : fCentre(), fRs(0)
+               {
+                       Create(p, a, b);
+               };
+
+               /* Creates a region of interest. In this implementation it is a
+                  circular disk.
+
+                  The point p is the intersecting point of the track with the chamber.
+                  For more details and for details about the parameters a and b refer to:
+                  "A first algorithm for dimuon High Level Trigger"
+                  Ref ID:  ALICE-INT-2002-04 version 1.0
+                  equation:
+                    Rs = a * Rp + b
+                  given on page 3 section 4.
+                */
+               void Create(AliHLTMUONCorePoint p, AliHLTFloat32_t a, AliHLTFloat32_t b);
+
+               /* Returns true if the point p is within the region of interest.
+                */
+               bool Contains(AliHLTMUONCorePoint p) const;
+
+               void GetBoundaryBox(AliHLTFloat32_t& left, AliHLTFloat32_t& right, AliHLTFloat32_t& bottom, AliHLTFloat32_t& top) const;
+
+       private:
+
+               AliHLTMUONCorePoint fCentre;  // The centre point of the region of interest.
+               AliHLTFloat32_t fRs;      // The redius of the region of interest around fcentre.
+       };
+
+
+       class AliVertex
+       {
+       public:
+
+               AliVertex(AliHLTFloat32_t x = 0.0, AliHLTFloat32_t y = 0.0, AliHLTFloat32_t z = 0.0);
+               AliVertex(AliHLTMUONCorePoint xy, AliHLTFloat32_t z);
+
+               AliHLTMUONCorePoint AsXYPoint() const
+               {
+                       return AliHLTMUONCorePoint(fX, fY);
+               };
+
+               // Get/set methods:
+               AliHLTFloat32_t X() const { return fX; };
+               AliHLTFloat32_t Y() const { return fY; };
+               AliHLTFloat32_t Z() const { return fZ; };
+               AliHLTFloat32_t& X() { return fX; };
+               AliHLTFloat32_t& Y() { return fY; };
+               AliHLTFloat32_t& Z() { return fZ; };
+               void X(AliHLTFloat32_t value) { fX = value; };
+               void Y(AliHLTFloat32_t value) { fY = value; };
+               void Z(AliHLTFloat32_t value) { fZ = value; };
+
+       private:
+
+               AliHLTFloat32_t fX, fY, fZ; // 3D coordinates.
+       };
+
+       
+       class AliLine
+       {
+       public:
+
+               /* Creates a vector line between points A and B.
+                  ax, ay, az are x, y and z coordinates for space point A respectively.
+                  simmilarly for B.
+                */
+               AliLine(
+                       AliHLTFloat32_t ax = 0.0, AliHLTFloat32_t ay = 0.0, AliHLTFloat32_t az = 0.0,
+                       AliHLTFloat32_t bx = 0.0, AliHLTFloat32_t by = 0.0, AliHLTFloat32_t bz = 0.0
+               );
+
+               /* Creates a vector line between vertices A and B.
+                */
+               AliLine(AliVertex a, AliVertex b);
+
+               /* Finds the intersection point with the xy plain specified by the z coordinate.
+                  The z coordiante would be the distance of the n'th chamber to the interaction
+                  vertex.
+                */
+               AliHLTMUONCorePoint FindIntersectWithXYPlain(AliHLTFloat32_t z) const;
+
+       private:
+
+               // Parameters for the vector line:  L = M*t + C
+               AliHLTFloat32_t fMx, fMy, fMz, fCx, fCy, fCz;  // line parameters.
+       };
+
+       
+       struct AliTagData
+       {
+               AliHLTMUONCoreChamberID fChamber;     // The chamber on which the region of interest lies.
+               AliRegionOfInterest fRoi;  // Region of interest on the next station.
+               AliLine fLine;             // line between a cluster point and the previous station.
+
+               AliTagData() : fChamber(kChamber1), fRoi(), fLine() {};
+       };
+       
+       struct AliStation5Data
+       {
+               AliHLTMUONCoreClusterPoint fClusterPoint;  // Cluster point found on station 5.
+               AliTagData fTag;  // Chamber, ROI and line data for station 5.
+
+               AliStation5Data() : fClusterPoint(), fTag() {};
+       };
+       
+       typedef AliHLTMUONCoreCountedList<AliStation5Data> Station5List;
+
+       struct AliStation4Data
+       {
+               AliHLTMUONCoreClusterPoint fClusterPoint;  // Cluster point found on station 4.
+               const AliTagData* fSt5tag;      // Corresponding station 5 tag.
+
+               AliStation4Data() : fClusterPoint(), fSt5tag() {};
+
+               AliStation4Data(const AliStation4Data& data) :
+                       fClusterPoint(data.fClusterPoint), fSt5tag(data.fSt5tag)
+               {};
+
+               AliStation4Data& operator = (const AliStation4Data& data)
+               {
+                       fClusterPoint = data.fClusterPoint;
+                       fSt5tag = data.fSt5tag;
+                       return *this;
+               };
+       };
+
+       typedef AliHLTMUONCoreList<AliStation4Data> Station4List;
+       
+       
+       void ReceiveClustersChamber7(const AliHLTMUONCoreClusterPoint* clusters, UInt count, const AliTagData* data);
+       void ReceiveClustersChamber8(const AliHLTMUONCoreClusterPoint* clusters, UInt count, const AliTagData* data);
+       void ReceiveClustersChamber9(const AliHLTMUONCoreClusterPoint* clusters, UInt count);
+       void ReceiveClustersChamber10(const AliHLTMUONCoreClusterPoint* clusters, UInt count);
+       void EndOfClustersChamber7();
+       void EndOfClustersChamber8();
+       void EndOfClustersChamber9();
+       void EndOfClustersChamber10();
+
+       void ProjectToStation4(AliStation5Data* data, register AliHLTFloat32_t station5z);
+       void ProcessClusters();
+
+#ifdef DEBUG
+public:
+#endif
+       // States for state machine 4 (SM4).
+       enum StatesSM4
+       {
+               kSM4Idle,
+               kWaitChamber8,
+               kWaitMoreChamber8,
+               kWaitChamber7,
+               kWaitMoreChamber7
+       };
+       
+       // States for state machine 5 (SM5).
+       enum StatesSM5
+       {
+               kSM5Idle,
+               kWaitChamber10,
+               kWaitMoreChamber10,
+               kWaitChamber9,
+               kWaitMoreChamber9,
+               kSM5Done
+       };
+       
+protected:
+
+       AliHLTMUONCoreTrackerCallback* fCallback;
+       
+       StatesSM4 fSm4state;  // State of SM4 used for fetching clusters on chambers 7 and 8.
+       StatesSM5 fSm5state;  // State of SM5 used for fetching clusters on chambers 9 and 10.
+       UInt fRequestsCompleted;  // Number of requests for station 4 that have completed.
+       AliHLTMUONCoreChamberID fSt4chamber;     // The chamber on station 4 that data was retreived from.
+       
+       AliVertex fV1;    // The impact (hit) vertex for trigger station 1.
+       AliTagData fMc1;  // Trigger station 1 data.
+
+       AliHLTFloat32_t fSt5z;   // The z coordinate to use for station 5.
+       Station5List fSt5data;  // List of found cluster points for station 5 and their tag data.
+       AliHLTFloat32_t fSt4z;   // The z coordinate to use for station 4.
+       Station4List fSt4points;  // The found cluster points for station 4.
+
+       // Iterators used in the FoundTrack, FillTrackData methods.
+       Station5List::Iterator fSt5rec;      // current station 5 record
+       Station4List::Iterator fFoundPoint;  // current found point
+       
+       
+       /* To request clusters from the boundary box specified by the 'left', 'right',
+          'top' and 'bottom' boundaries and on the given chamber use this method call.
+          Supply a tag parameter if you want the request uniquely identified. 
+          This is usefull to supply a pointer to some internal state data structure
+          to figure out where processing should continue in the ReturnClusters or
+          EndOfClusters methods.
+        */
+       inline void RequestClusters(
+                       AliHLTFloat32_t left, AliHLTFloat32_t right, AliHLTFloat32_t bottom, AliHLTFloat32_t top,
+                       AliHLTMUONCoreChamberID chamber, const void* tag = NULL
+               )
+       {
+               Assert( fCallback != NULL );
+               fCallback->RequestClusters(this, left, right, bottom, top, chamber, tag);
+       };
+
+       /* When no more cluster requests will be generated by this tracker then this
+          method should be called.
+          DO NOT request more clusters after calling this method.
+        */
+       inline void EndOfClusterRequests()
+       {
+               Assert( fCallback != NULL );
+               fCallback->EndOfClusterRequests(this);
+       };
+
+       /* When the tracker has found a track it should call this method to inform
+          the rest of the system. At this point all cluster blocks received with
+          ReturnClusters are to be considered released and MUST NOT be accessed.
+        */
+       inline void FoundTrack()
+       {
+               Assert( fCallback != NULL );
+               fCallback->FoundTrack(this);
+       };
+
+       /* If the tracker is finished processing the trigger record but has not found 
+          a track it should call this method to inform the rest of the system.
+          At this point all cluster blocks received with ReturnClusters are to be
+          considered released and MUST NOT be accessed.
+        */
+       inline void NoTrackFound()
+       {
+               Assert( fCallback != NULL );
+               fCallback->NoTrackFound(this);
+       };
+
+private:
+
+       // Not allowed to copy this object.
+       AliHLTMUONMansoTrackerFSM(const AliHLTMUONMansoTrackerFSM& tracker);
+       AliHLTMUONCoreTracker& operator = (const AliHLTMUONCoreTracker& tracker);
+
+       static AliHLTFloat32_t fgA7, fgB7;    // Parameters used to create a region of interest for the 7'th chamber.
+       static AliHLTFloat32_t fgA8, fgB8;    // Parameters used to create a region of interest for the 8'th chamber.
+       static AliHLTFloat32_t fgA9, fgB9;    // Parameters used to create a region of interest for the 9'th chamber.
+       static AliHLTFloat32_t fgA10, fgB10;  // Parameters used to create a region of interest for the 10'th chamber.
+       static AliHLTFloat32_t fgZ7, fgZ8, fgZ9, fgZ10, fgZ11, fgZ13;  // Z coordinates of chambers 7 to 10.
+
+};
+
+
+class AliHLTMUONMansoTrackerFSMCallback
+{
+public:
+
+       virtual ~AliHLTMUONMansoTrackerFSMCallback() {};
+       
+       /* All clusters that fall within the specified boundary box on the specified
+          chamber should be returned to the tracker, by calling the ReturnClusters
+          method of the given tracker. The same tag parameter must be passed on the 
+          ReturnClusters method's parameter list.
+        */
+       virtual void RequestClusters(
+                       AliHLTMUONCoreTracker* tracker,
+                       AliHLTFloat32_t left, AliHLTFloat32_t right, AliHLTFloat32_t bottom, AliHLTFloat32_t top,
+                       AliHLTMUONCoreChamberID chamber, const void* tag
+               ) = 0;
+
+       /* When this method is called then one knows no more RequestClusters method
+          calls are expected.
+        */
+       virtual void EndOfClusterRequests(AliHLTMUONCoreTracker* tracker) = 0;
+
+       /* This method is called when the tracker has found a track. The FillTrackData
+          method of the given tracker should be called to receive the track data.
+          At this point all cluster blocks can be released.
+        */
+       virtual void FoundTrack(AliHLTMUONCoreTracker* tracker) = 0;
+       
+       /* When the tracker is finished with its work but no track was found then
+          this method is called. At this point no more work should be performed by
+          the tracker and all cluster blocks can be released.
+        */
+       virtual void NoTrackFound(AliHLTMUONCoreTracker* tracker) = 0;
+};
+
+
+#endif // ALIHLTMUONMANSOTRACKERFSM_H