Adding AliHLTMUONTrack object to store ROOTified internal dHLT track data in new...
authoraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 16 Mar 2010 00:39:49 +0000 (00:39 +0000)
committeraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 16 Mar 2010 00:39:49 +0000 (00:39 +0000)
HLT/MUON/AliHLTMUONDecision.cxx
HLT/MUON/AliHLTMUONDecision.h
HLT/MUON/AliHLTMUONLinkDef.h
HLT/MUON/AliHLTMUONRecHit.cxx
HLT/MUON/AliHLTMUONTrack.cxx [new file with mode: 0644]
HLT/MUON/AliHLTMUONTrack.h [new file with mode: 0644]
HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.cxx
HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.h
HLT/libAliHLTMUON.pkg

index 5d74624..387866e 100644 (file)
@@ -27,6 +27,7 @@
 ///
 
 #include "AliHLTMUONDecision.h"
+#include "AliHLTMUONTrack.h"
 #include "AliHLTMUONMansoTrack.h"
 #include "AliLog.h"
 #include <cstring>
@@ -102,7 +103,7 @@ AliHLTMUONDecision::AliHLTMUONDecision(
 
 void AliHLTMUONDecision::AddDecision(
                Float_t pt, Bool_t passedLowCut, Bool_t passedHighCut,
-               const AliHLTMUONMansoTrack* track
+               const TObject* track
        )
 {
 /// Add a single track decision to the dHLT trigger.
@@ -131,8 +132,7 @@ void AliHLTMUONDecision::AddDecision(
                Float_t mass, Bool_t passedLowCut,
                Bool_t passedHighCut, Bool_t unlike,
                UChar_t lowPtCount, UChar_t highPtCount,
-               const AliHLTMUONMansoTrack* trackA,
-               const AliHLTMUONMansoTrack* trackB
+               const TObject* trackA, const TObject* trackB
        )
 {
 /// Add a track pair decision to the dHLT trigger.
@@ -210,13 +210,17 @@ void AliHLTMUONDecision::Print(Option_t* option) const
                        const AliTrackDecision* decision = SingleTrackDecision(i);
                        if (decision == NULL) continue;
                        
-                       if (decision->Track() == NULL)
+                       if (decision->MansoTrack() != NULL)
                        {
-                               cout << setw(10) << "-";
+                               cout << setw(10) << decision->MansoTrack()->Id();
+                       }
+                       else if (decision->FullTrack() != NULL)
+                       {
+                               cout << setw(10) << decision->FullTrack()->Id();
                        }
                        else
                        {
-                               cout << setw(10) << decision->Track()->Id();
+                               cout << setw(10) << "-";
                        }
                        
                        cout    << setw(12) << decision->Pt()
@@ -238,22 +242,30 @@ void AliHLTMUONDecision::Print(Option_t* option) const
                        const AliPairDecision* decision = TrackPairDecision(j);
                        if (decision == NULL) continue;
                        
-                       if (decision->TrackA() == NULL)
+                       if (decision->MansoTrackA() != NULL)
                        {
-                               cout << setw(10) << "-";
+                               cout << setw(10) << decision->MansoTrackA()->Id();
+                       }
+                       else if (decision->FullTrackA() != NULL)
+                       {
+                               cout << setw(10) << decision->FullTrackA()->Id();
                        }
                        else
                        {
-                               cout << setw(10) << decision->TrackA()->Id();
+                               cout << setw(10) << "-";
                        }
                        
-                       if (decision->TrackB() == NULL)
+                       if (decision->MansoTrackB() == NULL)
                        {
-                               cout << setw(10) << "-";
+                               cout << setw(10) << decision->MansoTrackB()->Id();
+                       }
+                       else if (decision->FullTrackB() == NULL)
+                       {
+                               cout << setw(10) << decision->FullTrackB()->Id();
                        }
                        else
                        {
-                               cout << setw(10) << decision->TrackB()->Id();
+                               cout << setw(10) << "-";
                        }
                        
                        cout    << setw(6) << (decision->LikeSign() ? "yes" : "no")
@@ -418,6 +430,26 @@ std::ostream& operator << (
 }
 
 
+const AliHLTMUONMansoTrack* AliHLTMUONDecision::AliTrackDecision::MansoTrack() const
+{
+/// Returns the associated track as a Manso track object and NULL if the track
+/// object is missing or not a Manso track object.
+
+       if (fTrack == NULL) return NULL;
+       return dynamic_cast<const AliHLTMUONMansoTrack*>(fTrack);
+}
+
+
+const AliHLTMUONTrack* AliHLTMUONDecision::AliTrackDecision::FullTrack() const
+{
+/// Returns the associated track as a full track object and NULL if the track
+/// object is missing or not a full track object.
+
+       if (fTrack == NULL) return NULL;
+       return dynamic_cast<const AliHLTMUONTrack*>(fTrack);
+}
+
+
 void AliHLTMUONDecision::AliTrackDecision::Print(Option_t* option) const
 {
 /// Prints the trigger decision to standard output (screen).
@@ -436,7 +468,10 @@ void AliHLTMUONDecision::AliTrackDecision::Print(Option_t* option) const
        }
        else if (strcmp(option, "detail") == 0)
        {
-               cout << "Trigger decision for track: " << fTrack->Id() << endl;
+               Int_t id = -1;
+               if (MansoTrack() != NULL) id = MansoTrack()->Id();
+               else if (FullTrack() != NULL) id = FullTrack()->Id();
+               cout << "Trigger decision for track: " << id << endl;
                cout << "pT = " << fPt << " GeV/c" << endl;
                cout << "pT cut | passed" << endl;
                cout << "-------+--------" << endl;
@@ -445,7 +480,10 @@ void AliHLTMUONDecision::AliTrackDecision::Print(Option_t* option) const
        }
        else if (strcmp(option, "all") == 0)
        {
-               cout << "Trigger decision for track: " << fTrack->Id() << endl;
+               Int_t id = -1;
+               if (MansoTrack() != NULL) id = MansoTrack()->Id();
+               else if (FullTrack() != NULL) id = FullTrack()->Id();
+               cout << "Trigger decision for track: " << id << endl;
                cout << "pT = " << fPt << " GeV/c" << endl;
                cout << "pT cut | passed" << endl;
                cout << "-------+--------" << endl;
@@ -512,6 +550,46 @@ std::ostream& operator << (
 }
 
 
+const AliHLTMUONMansoTrack* AliHLTMUONDecision::AliPairDecision::MansoTrackA() const
+{
+/// Returns the first associated track as a Manso track object and NULL if the
+/// track object is missing or not a Manso track object.
+
+       if (fTrackA == NULL) return NULL;
+       return dynamic_cast<const AliHLTMUONMansoTrack*>(fTrackA);
+}
+
+
+const AliHLTMUONTrack* AliHLTMUONDecision::AliPairDecision::FullTrackA() const
+{
+/// Returns the first associated track as a full track object and NULL if the
+/// track object is missing or not a full track object.
+
+       if (fTrackA == NULL) return NULL;
+       return dynamic_cast<const AliHLTMUONTrack*>(fTrackA);
+}
+
+
+const AliHLTMUONMansoTrack* AliHLTMUONDecision::AliPairDecision::MansoTrackB() const
+{
+/// Returns the second associated track as a Manso track object and NULL if the
+/// track object is missing or not a Manso track object.
+
+       if (fTrackB == NULL) return NULL;
+       return dynamic_cast<const AliHLTMUONMansoTrack*>(fTrackB);
+}
+
+
+const AliHLTMUONTrack* AliHLTMUONDecision::AliPairDecision::FullTrackB() const
+{
+/// Returns the second associated track as a full track object and NULL if the
+/// track object is missing or not a full track object.
+
+       if (fTrackB == NULL) return NULL;
+       return dynamic_cast<const AliHLTMUONTrack*>(fTrackB);
+}
+
+
 void AliHLTMUONDecision::AliPairDecision::Print(Option_t* option) const
 {
 /// Prints the trigger decision to standard output (screen).
@@ -530,8 +608,14 @@ void AliHLTMUONDecision::AliPairDecision::Print(Option_t* option) const
        }
        else if (strcmp(option, "detail") == 0)
        {
-               cout    << "Trigger decision for track pair: {" << fTrackA->Id()
-                       << ", " << fTrackB->Id() << "}" << endl;
+               Int_t id1 = -1;
+               if (MansoTrackA() != NULL) id1 = MansoTrackA()->Id();
+               else if (FullTrackA() != NULL) id1 = FullTrackA()->Id();
+               Int_t id2 = -1;
+               if (MansoTrackB() != NULL) id2 = MansoTrackB()->Id();
+               else if (FullTrackB() != NULL) id2 = FullTrackB()->Id();
+               cout    << "Trigger decision for track pair: {" << id1
+                       << ", " << id2 << "}" << endl;
                cout << "Invariant mass = " << fMass << " GeV/c^2" << endl;
                cout << "mass cut | passed" << endl;
                cout << "---------+--------" << endl;
@@ -543,8 +627,14 @@ void AliHLTMUONDecision::AliPairDecision::Print(Option_t* option) const
        }
        else if (strcmp(option, "all") == 0)
        {
-               cout    << "Trigger decision for track pair: {" << fTrackA->Id()
-                       << ", " << fTrackB->Id() << "}" << endl;
+               Int_t id1 = -1;
+               if (MansoTrackA() != NULL) id1 = MansoTrackA()->Id();
+               else if (FullTrackA() != NULL) id1 = FullTrackA()->Id();
+               Int_t id2 = -1;
+               if (MansoTrackB() != NULL) id2 = MansoTrackB()->Id();
+               else if (FullTrackB() != NULL) id2 = FullTrackB()->Id();
+               cout    << "Trigger decision for track pair: {" << id1
+                       << ", " << id2 << "}" << endl;
                cout << "Invariant mass = " << fMass << " GeV/c^2" << endl;
                cout << "mass cut | passed" << endl;
                cout << "---------+--------" << endl;
index 36ec21a..28b3539 100644 (file)
@@ -16,6 +16,7 @@
 #include "TObject.h"
 #include "TClonesArray.h"
 
+class AliHLTMUONTrack;
 class AliHLTMUONMansoTrack;
 
 /**
@@ -62,7 +63,7 @@ public:
                                Float_t pt = -1,
                                Bool_t passedLowCut = kFALSE,
                                Bool_t passedHighCut = kFALSE,
-                               const AliHLTMUONMansoTrack* track = NULL
+                               const TObject* track = NULL
                        ) :
                        TObject(), fTrack(track), fPt(pt),
                        fPassedLowCut(passedLowCut), fPassedHighCut(passedHighCut)
@@ -97,7 +98,19 @@ public:
                /**
                 * Returns the track associated with the trigger decision or NULL if none found.
                 */
-               const AliHLTMUONMansoTrack* Track() const { return fTrack; }
+               const TObject* Track() const { return fTrack; }
+               
+               /**
+                * Returns the track associated with the trigger decision as a Manso track object.
+                * NULL is returned if no track is found or the track object is not a Manso track.
+                */
+               const AliHLTMUONMansoTrack* MansoTrack() const;
+               
+               /**
+                * Returns the track associated with the trigger decision as a full track object.
+                * NULL is returned if no track is found or the track object is not a full track.
+                */
+               const AliHLTMUONTrack* FullTrack() const;
                
                /**
                 * Returns the calculated pT value used for the trigger decision.
@@ -136,12 +149,12 @@ public:
        
        private:
                
-               const AliHLTMUONMansoTrack* fTrack; ///< Track associated with this decision.
+               const TObject* fTrack; ///< Track associated with this decision.
                Float_t fPt; ///< Calculated pT value used for decision (GeV/c).
                Bool_t fPassedLowCut; ///< Indicates if the track passed the low pT cut.
                Bool_t fPassedHighCut; ///< Indicates if the track passed the high pT cut.
                
-               ClassDef(AliHLTMUONDecision::AliTrackDecision, 3); // A single track dHLT trigger decision object.
+               ClassDef(AliHLTMUONDecision::AliTrackDecision, 4); // A single track dHLT trigger decision object.
        };
        
        /**
@@ -173,8 +186,8 @@ public:
                                Float_t mass = -1, Bool_t passedLowCut = kFALSE,
                                Bool_t passedHighCut = kFALSE, Bool_t unlike = kFALSE,
                                UChar_t lowPtCount = 0, UChar_t highPtCount = 0,
-                               const AliHLTMUONMansoTrack* trackA = NULL,
-                               const AliHLTMUONMansoTrack* trackB = NULL
+                               const TObject* trackA = NULL,
+                               const TObject* trackB = NULL
                        ) :
                        TObject(), fTrackA(trackA), fTrackB(trackB), fMass(mass),
                        fPassedLowCut(passedLowCut), fPassedHighCut(passedHighCut),
@@ -212,13 +225,37 @@ public:
                 * Returns the first track associated with the track pair trigger decision
                 * or NULL if none found.
                 */
-               const AliHLTMUONMansoTrack* TrackA() const { return fTrackA; }
+               const TObject* TrackA() const { return fTrackA; }
+               
+               /**
+                * Returns the first track associated with the pair decision as a Manso track object.
+                * NULL is returned if no track is found or the track object is not a Manso track.
+                */
+               const AliHLTMUONMansoTrack* MansoTrackA() const;
+               
+               /**
+                * Returns the first track associated with the pair decision as a full track object.
+                * NULL is returned if no track is found or the track object is not a full track.
+                */
+               const AliHLTMUONTrack* FullTrackA() const;
                
                /**
                 * Returns the second track associated with the track pair trigger decision
                 * or NULL if none found.
                 */
-               const AliHLTMUONMansoTrack* TrackB() const { return fTrackB; }
+               const TObject* TrackB() const { return fTrackB; }
+               
+               /**
+                * Returns the second track associated with the pair decision as a Manso track object.
+                * NULL is returned if no track is found or the track object is not a Manso track.
+                */
+               const AliHLTMUONMansoTrack* MansoTrackB() const;
+               
+               /**
+                * Returns the second track associated with the pair decision as a full track object.
+                * NULL is returned if no track is found or the track object is not a full track.
+                */
+               const AliHLTMUONTrack* FullTrackB() const;
                
                /**
                 * Returns the calculated invariant mass value used for the trigger decision.
@@ -289,8 +326,8 @@ public:
        
        private:
                
-               const AliHLTMUONMansoTrack* fTrackA; ///< The first track associated with this pair decision.
-               const AliHLTMUONMansoTrack* fTrackB; ///< The second track associated with this pair decision.
+               const TObject* fTrackA; ///< The first track associated with this pair decision.
+               const TObject* fTrackB; ///< The second track associated with this pair decision.
                Float_t fMass;  ///< The invariant mass used for the trigger decision. (GeV/c^2)
                Bool_t fPassedLowCut; ///< Indicates if the track passed the low mass cut.
                Bool_t fPassedHighCut; ///< Indicates if the track passed the high mass cut.
@@ -298,7 +335,7 @@ public:
                UChar_t fLowPtCount; ///< The number of tracks in the pair that passed the low pT cut.
                UChar_t fHighPtCount; ///< The number of tracks in the pair that passed the high pT cut.
                
-               ClassDef(AliHLTMUONDecision::AliPairDecision, 3); // A track pair dHLT trigger decision object.
+               ClassDef(AliHLTMUONDecision::AliPairDecision, 4); // A track pair dHLT trigger decision object.
        };
 
        /**
@@ -418,7 +455,7 @@ public:
        /// Add a single track decision to the dHLT trigger.
        void AddDecision(
                        Float_t pt, Bool_t passedLowCut, Bool_t passedHighCut,
-                       const AliHLTMUONMansoTrack* track
+                       const TObject* track
                );
        
        /// Add a track pair decision to the dHLT trigger.
@@ -429,8 +466,7 @@ public:
                        Float_t mass, Bool_t passedLowCut,
                        Bool_t passedHighCut, Bool_t unlike,
                        UChar_t lowPtCount, UChar_t highPtCount,
-                       const AliHLTMUONMansoTrack* trackA,
-                       const AliHLTMUONMansoTrack* trackB
+                       const TObject* trackA, const TObject* trackB
                );
        
        /**
@@ -496,7 +532,7 @@ private:
        TClonesArray fTrackDecisions;  ///< Array of single track decision objects.
        TClonesArray fPairDecisions;  ///< Array of track pair decision objects.
 
-       ClassDef(AliHLTMUONDecision, 3); // Decision object containing data converted from raw internal dHLT data structures.
+       ClassDef(AliHLTMUONDecision, 4); // Decision object containing data converted from raw internal dHLT data structures.
 };
 
 #endif // ALIHLTMUONDECISION_H
index 6bbcd41..63607c6 100644 (file)
@@ -53,6 +53,7 @@
 #pragma link C++ class AliHLTMUONRecHit+;
 #pragma link C++ class AliHLTMUONRecHit::AliChannel+;
 #pragma link C++ class AliHLTMUONTriggerRecord+;
+#pragma link C++ class AliHLTMUONTrack+;
 #pragma link C++ class AliHLTMUONMansoTrack+;
 #pragma link C++ class AliHLTMUONDecision+;
 #pragma link C++ class AliHLTMUONDecision::AliTrackDecision+;
index fa702d3..cad852b 100644 (file)
@@ -81,7 +81,10 @@ Int_t AliHLTMUONRecHit::Chamber(bool warn) const
 /// \param warn  Indicates if any warning should be printed in case of problems.
 /// \returns The chamber number of this hit in the range [1..14] or -1 if not known.
 
-       if (fDetElemId != -1) return AliMpDEManager::GetChamberId(fDetElemId, warn);
+       //FIXME: 16 March 2010 AliMpDEManager::GetChamberId is not behaving as the
+       // documentation indicates anymore and now causes a segfault.
+       //if (fDetElemId != -1) return AliMpDEManager::GetChamberId(fDetElemId, warn);
+       if (fDetElemId != -1) return fDetElemId/100;
        
        if (warn)
        {
diff --git a/HLT/MUON/AliHLTMUONTrack.cxx b/HLT/MUON/AliHLTMUONTrack.cxx
new file mode 100644 (file)
index 0000000..4fa243c
--- /dev/null
@@ -0,0 +1,329 @@
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        *
+ * All rights reserved.                                                   *
+ *                                                                        *
+ * Primary Authors:                                                       *
+ *   Artur Szostak <artursz@iafrica.com>                                  *
+ *                                                                        *
+ * 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: AliHLTMUONTrack.cxx 37131 2009-11-23 11:08:09Z aszostak $
+
+///
+/// @file   AliHLTMUONTrack.cxx
+/// @author Indranil Das <indra.ehep@gmail.com> and Artur Szostak <artursz@iafrica.com>
+/// @date   10 March 2010
+/// @brief  Implementation of the AliHLTMUONTrack class.
+///
+/// The track class is used to store converted track data from dHLT raw internal
+/// data blocks as a ROOT object. This allows storing these in ROOT files.
+///
+
+#include "AliHLTMUONTrack.h"
+#include "AliHLTMUONRecHit.h"
+#include "AliHLTMUONTriggerRecord.h"
+#include "AliLog.h"
+#include "mapping/AliMpDEManager.h"
+#include <cstring>
+#include <iostream>
+#include <iomanip>
+
+ClassImp(AliHLTMUONTrack);
+
+
+std::ostream& operator << (
+               std::ostream& stream,
+               const AliHLTMUONTrack& track
+       )
+{
+/// Stream operator for std::ostream classes.
+/// \param stream  The output stream object being written to.
+/// \param track  The track object to print to the stream.
+/// \returns  the stream object that was written to, <i>stream</i>.
+
+       stream  << "ID: " << track.fId
+               << "; sign: " << track.fSign
+               << "; p = (" << track.Px()
+               << ", " << track.Py()
+               << ", " << track.Pz()
+               << "); chi^2: " << track.fChi2;
+       return stream;
+}
+
+
+AliHLTMUONTrack::AliHLTMUONTrack(
+               Int_t id, Int_t sign,
+               Float_t px, Float_t py, Float_t pz,
+               Float_t invmom, Float_t thetaX, Float_t thetaY,
+               Float_t x, Float_t y, Float_t z,
+               Float_t chi2,
+               const AliHLTMUONTriggerRecord* trigrec,
+               const AliHLTMUONRecHit* hits[16]
+       ) :
+       TObject(),
+       fId(id),
+       fSign(sign),
+       fInverseBendingMomentum(invmom),
+       fThetaX(thetaX),
+       fThetaY(thetaY),
+       fMomentum(px, py, pz),
+       fVertexDCA(x, y, z),
+       fChi2(chi2),
+       fTrigRec(trigrec)
+{
+/// Default constructor.
+/// @param id       The track ID number which must be unique for any event.
+/// @param sign     The particle's sign: -1, 1 or 0 if unknown.
+/// @param px       X component of the particle's momentum (GeV/c).
+/// @param py       Y component of the particle's momentum (GeV/c).
+/// @param pz       Z component of the particle's momentum (GeV/c).
+/// @param invmom   Inverse bending momentum (GeV/c).
+/// @param thetaX   The non-bending plane slope of the fitted track.
+/// @param thetaY   The bending plane slope of the fitted track.
+/// @param x        X coordinate of the particle's distance of closest
+///                 approach (DCA) position (cm).
+/// @param y        Y coordinate of the particle's DCA position (cm).
+/// @param z        Z coordinate of the particle's DCA position (cm).
+/// @param chi2     The chi squared of the track fit.
+/// @param trigrec  Corresponding trigger record used as a seed to find
+///                 this track.
+/// @param hits     The array of 16 hit coordinates found for the track.
+///                 If NULL then then all hit coordinates are set to empty.
+
+       if (sign < -1 or 1 < sign)
+       {
+               AliError(Form("Trying to set the sign to %d. This is outside the"
+                       " valid range of [-1..1]", sign
+               ));
+               fSign = 0;
+       }
+       
+       // Copy individual hit pointers if hits were set.
+       if (hits != NULL)
+       {
+               for (int i = 0; i < 16; ++i)
+               {
+                       fHit[i] = hits[i];
+               }
+       }
+}
+
+
+const AliHLTMUONRecHit* AliHLTMUONTrack::Hit(Int_t i) const
+{
+/// Returns the i'th hit.
+/// \param i  The number of the hit to return. Must be a value in the range [0..15].
+/// \returns  A pointer to the hit object else NULL if it does not exist.
+
+       if (0 <= i and i <= 15) return fHit[i];
+       AliError(Form("Hit index number %d is not in the valid range [0..15].", int(i)));
+       return NULL;
+}
+
+
+const AliHLTMUONRecHit* AliHLTMUONTrack::HitByChamber(Int_t chamber) const
+{
+/// Returns the first hit found for the specified chamber.
+/// \param chamber  The chamber to return the hit for. Must be a value in the range [1..14].
+/// \returns  A pointer to the hit object else NULL if it does not exist.
+
+       if (not (1 <= chamber and chamber <= 14))
+       {
+               AliError(Form(
+                       "Chamber number %d is not in the valid range [1..14].",
+                       int(chamber)
+               ));
+               return NULL;
+       }
+       
+       const AliHLTMUONRecHit* hit = NULL;
+       for (int i = 0; i < 16; ++i)
+       {
+               if (fHit[i] == NULL) continue;
+               if (fHit[i]->Chamber(false) == chamber)
+               {
+                       hit = fHit[i];
+                       break;
+               }
+       }
+       return hit;
+}
+
+
+void AliHLTMUONTrack::Print(Option_t* option) const
+{
+/// Prints the track information to standard output (screen).
+/// \param option  Can be one of the following:
+///           - "compact" - prints in a compact format.
+///           - "detail" - prints track information in a more detailed format.
+///           - "all" - prints a full dump of the track object.
+
+       using namespace std;
+       
+       if (    option == NULL or strcmp(option, "") == 0 or
+               strcmp(option, "compact") == 0
+          )
+       {
+               cout << *this << endl;
+       }
+       else if (strcmp(option, "detail") == 0)
+       {
+               cout << "Track ID = " << fId << "; sign = ";
+               if (fSign != 0)
+                       cout << fSign;
+               else
+                       cout << "unknown";
+               cout << "; momentum: (px = " << Px()
+                       << " GeV/c, py = " << Py()
+                       << " GeV/c, pz = " << Pz()
+                       << " GeV/c); vertex DCA: (x = " << X()
+                       << " cm, y = " << Y()
+                       << " cm, z = " << Z()
+                       << " cm); chi^2 = " << fChi2 << endl;
+               
+               streamsize w = cout.width();
+               ios::fmtflags f = cout.flags();
+               cout << setw(9) << "Hit no."
+                       << setw(9) << "Chamber"
+                       << setw(0) << "  Pos:"
+                       << setw(8) << "X (cm)"
+                       << setw(12) << "Y (cm)"
+                       << setw(12) << "Z (cm)" << endl;
+               for (int i = 0; i < 16; i++)
+               {
+                       cout << setw(9) << i;
+                       if (fHit[i] != NULL)
+                       {
+                               cout << setw(9) << fHit[i]->Chamber(false)
+                                       << setw(14) << fHit[i]->X()
+                                       << setw(12) << fHit[i]->Y()
+                                       << setw(12) << fHit[i]->Z();
+                       }
+                       else
+                       {
+                               cout << setw(9) << "-"
+                                       << setw(14) << "-"
+                                       << setw(12) << "-"
+                                       << setw(12) << "-";
+                       }
+                       cout << endl;
+               }
+               cout.width(w); // reset the field width to previous value.
+               cout.flags(f); // reset the flags to previous values.
+       }
+       else if (strcmp(option, "all") == 0)
+       {
+               cout << "Track ID = " << fId << "; sign = ";
+               if (fSign != 0)
+                       cout << fSign;
+               else
+                       cout << "unknown";
+               cout << "; momentum: (px = " << Px()
+                       << " GeV/c, py = " << Py()
+                       << " GeV/c, pz = " << Pz()
+                       << " GeV/c); vertex DCA: (x = " << X()
+                       << " cm, y = " << Y()
+                       << " cm, z = " << Z()
+                       << " cm); chi^2 = " << fChi2 << endl;
+               cout << "Inverse bending momentum = " << fInverseBendingMomentum
+                       << "; non-bending plane slope = " << fThetaX
+                       << "; bending plane slope = " << fThetaY << endl;
+               
+               streamsize w = cout.width();
+               ios::fmtflags f = cout.flags();
+               cout.width(w); // reset the field width to previous value.
+               cout.flags(f); // reset the flags to previous values.
+               
+               for (int i = 0; i < 16; i++)
+               {
+                       cout << "======== Hit " << i << " ========" << endl;
+                       if (fHit[i] != NULL)
+                               fHit[i]->Print("all");
+                       else
+                               cout << "No hit found." << endl;
+               }
+               
+               cout << "===== Trigger Record =====" << endl;
+               if (fTrigRec != NULL)
+                       fTrigRec->Print("all");
+               else
+                       cout << "No trigger record associated with track." << endl;
+       }
+       else
+       {
+               AliError("Unknown option specified. Can only be one of 'compact',"
+                       " 'detail' or 'all'."
+               );
+       }
+}
+
+
+Int_t AliHLTMUONTrack::Compare(const TObject* obj) const
+{
+/// We compare this object with 'obj' first by track ID, then by sign, then
+/// by momentum, then by DCA vertex and finally by chi2.
+/// \param obj  This is the object to compare to. It must be of type AliHLTMUONTrack.
+/// \returns  -1 if 'this' is smaller than 'obj', 1 if greater and zero if both
+///      objects are the same.
+
+       if (obj->IsA() == AliHLTMUONTrack::Class())
+       {
+               const AliHLTMUONTrack* t =
+                       static_cast<const AliHLTMUONTrack*>(obj);
+               if (fId < t->fId) return -1;
+               if (fId > t->fId) return 1;
+               if (fSign < t->fSign) return -1;
+               if (fSign > t->fSign) return 1;
+               if (Px() < t->Px()) return -1;
+               if (Px() > t->Px()) return 1;
+               if (Py() < t->Py()) return -1;
+               if (Py() > t->Py()) return 1;
+               if (Pz() < t->Pz()) return -1;
+               if (Pz() > t->Pz()) return 1;
+               if (X() < t->X()) return -1;
+               if (X() > t->X()) return 1;
+               if (Y() < t->Y()) return -1;
+               if (Y() > t->Y()) return 1;
+               if (Z() < t->Z()) return -1;
+               if (Z() > t->Z()) return 1;
+               if (fChi2 < t->fChi2) return -1;
+               if (fChi2 > t->fChi2) return 1;
+               return 0;
+       }
+       else
+       {
+               AliError(Form("Do not know how to compare %s to %s.",
+                       this->ClassName(),
+                       obj->ClassName()
+               ));
+               return -999;
+       }
+}
+
+
+bool AliHLTMUONTrack::operator == (const AliHLTMUONTrack& track) const
+{
+/// Comparison operator.
+/// \param track  The track object to compare to.
+/// \returns  true if 'this' object is identical to 'track' else false.
+
+                bool matched = true;
+               for (int i = 0; i < 16; i++){
+                 if(fHit[i] != track.fHit[i])
+                   matched = false;
+               }
+
+       return  fId == track.fId and fSign == track.fSign
+               and fMomentum == track.fMomentum
+               and fChi2 == track.fChi2 and fTrigRec == track.fTrigRec
+               and matched;
+               
+}
+
diff --git a/HLT/MUON/AliHLTMUONTrack.h b/HLT/MUON/AliHLTMUONTrack.h
new file mode 100644 (file)
index 0000000..d96eea4
--- /dev/null
@@ -0,0 +1,237 @@
+#ifndef ALIHLTMUONTRACK_H
+#define ALIHLTMUONTRACK_H
+/* This file is property of and copyright by the ALICE HLT Project        *
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ * See cxx source for full Copyright notice                               */
+
+///
+/// @file   AliHLTMUONTrack.h
+/// @author Indranil Das <indra.ehep@gmail.com> and Artur Szostak <artursz@iafrica.com>
+/// @date   10 March 2010
+/// @brief  Declaration of the track class used to store converted dHLT track data.
+///
+
+#include "TObject.h"
+#include "TVector3.h"
+
+class AliHLTMUONTriggerRecord;
+class AliHLTMUONRecHit;
+
+/**
+ * AliHLTMUONTrack stores converted dHLT raw track data from HLT raw data blocks
+ * as a ROOT object. This class is mainly for testing or as a helper object for
+ * dHLT specific analysis, since it is sometimes easier to store and handle ROOT
+ * objects than the raw data blocks.
+ */
+class AliHLTMUONTrack : public TObject
+{
+       /**
+        * Stream operator for usage with std::ostream classes.
+        * Allows usage such as:
+        *   AliHLTMUONTrack t; std::cout << t;
+        */
+       friend std::ostream& operator << (
+                       std::ostream& stream,
+                       const AliHLTMUONTrack& track
+               );
+
+public:
+
+       /**
+        * Constructor for creating a new track object.
+        * \note this class does not take ownership of the hit or trigger record
+        * objects and will not attempt to delete them. This must be done by the
+        * caller.
+        * @param id       The track ID number which must be unique for any event.
+        * @param sign     The particle's sign: -1, 1 or 0 if unknown.
+        * @param px       X component of the particle's momentum (GeV/c).
+        * @param py       Y component of the particle's momentum (GeV/c).
+        * @param pz       Z component of the particle's momentum (GeV/c).
+        * @param invmom   Inverse bending momentum (GeV/c).
+        * @param thetaX   The non-bending plane slope of the fitted track.
+        * @param thetaY   The bending plane slope of the fitted track.
+        * @param x        X coordinate of the particle's distance of closest
+        *                 approach (DCA) position (cm).
+        * @param y        Y coordinate of the particle's DCA position (cm).
+        * @param z        Z coordinate of the particle's DCA position (cm).
+        * @param chi2     The chi squared of the track fit.
+        * @param trigrec  Corresponding trigger record used as a seed to find
+        *                 this track.
+        * @param hits     The array of 16 hit coordinates found for the track.
+        *                 If NULL then then all hit coordinates are set to empty.
+        */
+       AliHLTMUONTrack(
+                       Int_t id = -1, Int_t sign = 0,
+                       Float_t px = 0, Float_t py = 0, Float_t pz = 0,
+                       Float_t invmom = 0, Float_t thetaX = 0, Float_t thetaY = 0,
+                       Float_t x = 0, Float_t y = 0, Float_t z = 0,
+                       Float_t chi2 = -1,
+                       const AliHLTMUONTriggerRecord* trigrec = NULL,
+                       const AliHLTMUONRecHit* hits[16] = NULL
+               );
+       
+       /**
+        * Default destructor.
+        */
+       virtual ~AliHLTMUONTrack() {}
+
+       /**
+        * Returns the track ID number, which should be unique for an event.
+        */
+       Int_t Id() const { return fId; }
+       
+       /**
+        * Returns the sign of the particle: -1, 1 or 0 if the sign is unknown.
+        */
+       Int_t Sign() const { return fSign; }
+       
+       /**
+        * Returns the inverse momentum in the bending plane, i.e. 1/p_yz, in units c/GeV.
+        */
+       Float_t InverseBendingMomentum() const { return fInverseBendingMomentum; }
+       
+       /**
+        * Returns the slope of the fitted track in the non-bending plane.
+        */
+       Float_t ThetaX() const { return fThetaX; }
+       
+       /**
+        * Returns the slope of the fitted track in the bending plane.
+        */
+       Float_t ThetaY() const { return fThetaY; }
+
+       /**
+        * Returns the momentum vector with components in GeV/c.
+        */
+       const TVector3& Momentum() const { return fMomentum; }
+
+       /**
+        * Returns the X component of the particle's momentum in GeV/c.
+        */
+       Double_t Px() const { return fMomentum.Px(); }
+
+       /**
+        * Returns the Y component of the particle's momentum in GeV/c.
+        */
+       Double_t Py() const { return fMomentum.Py(); }
+
+       /**
+        * Returns the Z component of the particle's momentum in GeV/c.
+        */
+       Double_t Pz() const { return fMomentum.Pz(); }
+
+       /**
+        * Returns the momentum magnitude of the particle in GeV/c.
+        */
+       Double_t P() const { return fMomentum.Mag(); }
+
+       /**
+        * Returns the transverse momentum of the particle in GeV/c.
+        */
+       Double_t Pt() const { return fMomentum.Pt(); }
+
+       /**
+        * Returns the polar angle of the momentum vector in radians.
+        */
+       Double_t Polar() const { return fMomentum.Theta(); }
+
+       /**
+        * Returns the azimuthal angle of the transverse momentum in radians.
+        */
+       Double_t Phi() const { return fMomentum.Phi(); }
+
+       /**
+        * Returns the distance of closest approach (DCA) position in centimetres.
+        */
+       const TVector3& VertexDCA() const { return fVertexDCA; }
+
+       /**
+        * Returns the non-bending plane coordinate for the distance of closest approach (DCA) in cm.
+        */
+       Double_t X() const { return fVertexDCA.X(); }
+
+       /**
+        * Returns the bending plane coordinate for the distance of closest approach (DCA) in cm.
+        */
+       Double_t Y() const { return fVertexDCA.Y(); }
+
+       /**
+        * Returns the z coordinate for the distance of closest approach (DCA) in cm.
+        */
+       Double_t Z() const { return fVertexDCA.Z(); }
+
+       /**
+        * Returns the chi squared of the track fit, indicating the quality of
+        * the fit.
+        */
+       Float_t Chi2() const { return fChi2; }
+
+       /**
+        * Returns the trigger record corresponding to this track.
+        * If NULL is returned then no trigger record was found or associated
+        * with the track.
+        */
+       const AliHLTMUONTriggerRecord* TriggerRecord() const { return fTrigRec; }
+
+       /**
+        * Returns the i'th hit set for this track.
+        * If NULL is returned then no hit was found or set for that hit position.
+        * @param i  Specifies the number of the hit to return.
+        *           Valid values are in the range [0..15].
+        */
+       const AliHLTMUONRecHit* Hit(Int_t i) const;
+
+       /**
+        * Returns the first hit found on the specified tracking chamber.
+        * If NULL is returned then no hit was found or set for that chamber.
+        * @param chamber  Specifies the chamber for which to return the hit.
+        *                 Valid values are in the range [1..14].
+        */
+       const AliHLTMUONRecHit* HitByChamber(Int_t chamber) const;
+       
+       /**
+        * Prints the details of the track.
+        * @param option  A case sensitive string that can contain one of the
+        *     following strings:
+        *       "compact" - Prints just the momentum, sign and ID of the track
+        *                   in a terse format.
+        *       "detail" - Prints also the hit information.
+        *       "all" - Prints all known information about this track.
+        *     If the string contains an empty option or NULL then the default is
+        *     to print compactly.
+        */
+       virtual void Print(Option_t* option = NULL) const;
+       
+       // Methods inherited from TObject
+       virtual Bool_t IsSortable() const { return kTRUE; }
+       Int_t Compare(const TObject* obj) const;
+
+       // Implement comparison operators.
+       bool operator == (const AliHLTMUONTrack& track) const;
+
+       bool operator != (const AliHLTMUONTrack& track) const
+       {
+               return not this->operator == (track);
+       }
+
+private:
+
+       // Do not allow copying of this class.
+       AliHLTMUONTrack(const AliHLTMUONTrack& track);
+       AliHLTMUONTrack& operator = (const AliHLTMUONTrack& track);
+       
+       Int_t fId; ///< Track ID number which is unique for a particular event.
+       Int_t fSign;  ///< The sign of the particle.
+       Float_t fInverseBendingMomentum; ///< One over the momentum of the fitted track in GeV/c.
+       Float_t fThetaX; ///< The slope of the fitted track in the non-bending plane.
+       Float_t fThetaY; ///< The slope of the fitted track in the bending plane.
+       TVector3 fMomentum; ///< Momentum vector of the particle in GeV/c.
+       TVector3 fVertexDCA; ///< The position for the distance of closest approach to the vertex in cm.
+       Float_t fChi2; ///< Chi squared of fit.
+       const AliHLTMUONTriggerRecord* fTrigRec;  ///< Corresponding trigger record.
+       const AliHLTMUONRecHit* fHit[16];   ///< Particle hits on tracking chambers 7 to 10.
+
+       ClassDef(AliHLTMUONTrack, 1); // Track object containing data converted from a dHLT internal track structure.
+};
+
+#endif // ALIHLTMUONTRACK_H
index f4d7771..6f0e916 100644 (file)
@@ -31,6 +31,7 @@
 #include "AliHLTMUONRecHit.h"
 #include "AliHLTMUONTriggerRecord.h"
 #include "AliHLTMUONMansoTrack.h"
+#include "AliHLTMUONTrack.h"
 #include "AliHLTMUONDecision.h"
 #include "AliMUONTriggerDDLDecoderEventHandler.h"
 #include "TClonesArray.h"
@@ -620,10 +621,33 @@ int AliHLTMUONRootifierComponent::DoEvent(
                }
        }
        
-       std::map<AliHLTInt32_t, AliHLTMUONMansoTrack*> trackMap;
-       
        // Now we can look for tracks to add. We needed the ROOT trigger records
        // and reco hits created before we can create track objects.
+       
+       std::map<AliHLTInt32_t, AliHLTMUONTrack*> trackMap;
+       
+       for (block = GetFirstInputBlock(AliHLTMUONConstants::TracksBlockDataType());
+            block != NULL;
+            block = GetNextInputBlock()
+           )
+       {
+               specification |= block->fSpecification;
+               AliHLTMUONTracksBlockReader inblock(block->fPtr, block->fSize);
+               if (not BlockStructureOk(inblock))
+               {
+                       if (DumpDataOnError()) DumpEvent(evtData, trigData);
+                       continue;
+               }
+               
+               for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
+               {
+                       const AliHLTMUONTrackStruct& t = inblock[n];
+                       trackMap[t.fId] = AddTrack(event, t);
+               }
+       }
+
+       std::map<AliHLTInt32_t, AliHLTMUONMansoTrack*> mansoTrackMap;
+       
        for (block = GetFirstInputBlock(AliHLTMUONConstants::MansoTracksBlockDataType());
             block != NULL;
             block = GetNextInputBlock()
@@ -640,7 +664,7 @@ int AliHLTMUONRootifierComponent::DoEvent(
                for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
                {
                        const AliHLTMUONMansoTrackStruct& t = inblock[n];
-                       trackMap[t.fId] = AddTrack(event, t);
+                       mansoTrackMap[t.fId] = AddTrack(event, t);
                }
        }
        
@@ -661,7 +685,7 @@ int AliHLTMUONRootifierComponent::DoEvent(
                for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
                {
                        const AliHLTMUONMansoCandidateStruct& tc = inblock[n];
-                       AliHLTMUONMansoTrack* mtrack = trackMap[tc.fTrack.fId];
+                       AliHLTMUONMansoTrack* mtrack = mansoTrackMap[tc.fTrack.fId];
                        if (mtrack == NULL)
                        {
                                // If we got here then we could not find the corresponding Manso
@@ -708,20 +732,9 @@ int AliHLTMUONRootifierComponent::DoEvent(
                        bool highPt, lowPt;
                        AliHLTMUONUtils::UnpackTrackDecisionBits(t.fTriggerBits, highPt, lowPt);
                        
-                       // Try find the corresponding track in the 'event'.
-                       const AliHLTMUONMansoTrack* track = NULL;
-                       for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
-                       {
-                               if (event.Array()[k]->IsA() != AliHLTMUONMansoTrack::Class())
-                                       continue;
-                               const AliHLTMUONMansoTrack* tk =
-                                       static_cast<const AliHLTMUONMansoTrack*>(event.Array()[k]);
-                               if (tk->Id() == t.fTrackId)
-                               {
-                                       track = tk;
-                                       break;
-                               }
-                       }
+                       // Try find the corresponding track.
+                       const TObject* track = trackMap[t.fTrackId];
+                       if (track == NULL) track = mansoTrackMap[t.fTrackId];
                        
                        // If the track was not found then create a dummy one.
                        if (track == NULL)
@@ -784,19 +797,11 @@ int AliHLTMUONRootifierComponent::DoEvent(
                                        highPtCount, lowPtCount
                                );
                        
-                       // Try find the corresponding tracks in the 'event'.
-                       const AliHLTMUONMansoTrack* trackA = NULL;
-                       const AliHLTMUONMansoTrack* trackB = NULL;
-                       for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
-                       {
-                               if (event.Array()[k]->IsA() != AliHLTMUONMansoTrack::Class())
-                                       continue;
-                               const AliHLTMUONMansoTrack* tk =
-                                       static_cast<const AliHLTMUONMansoTrack*>(event.Array()[k]);
-                               if (tk->Id() == t.fTrackAId) trackA = tk;
-                               if (tk->Id() == t.fTrackBId) trackB = tk;
-                               if (trackA != NULL and trackB != NULL) break;
-                       }
+                       // Try find the corresponding tracks.
+                       const TObject* trackA = trackMap[t.fTrackAId];
+                       if (trackA == NULL) trackA = mansoTrackMap[t.fTrackAId];
+                       const TObject* trackB = trackMap[t.fTrackBId];
+                       if (trackB == NULL) trackB = mansoTrackMap[t.fTrackBId];
                        
                        // If either of the tracks was not found then create a dummy one.
                        if (trackA == NULL)
@@ -944,3 +949,71 @@ AliHLTMUONMansoTrack* AliHLTMUONRootifierComponent::AddTrack(
        event.Add(tr);
        return tr;
 }
+
+
+AliHLTMUONTrack* AliHLTMUONRootifierComponent::AddTrack(
+               AliHLTMUONEvent& event, const AliHLTMUONTrackStruct& track
+       )
+{
+       // Converts the track structure and adds it to the event object.
+       
+       AliHLTMUONParticleSign sign;
+       bool hitset[16];
+       AliHLTMUONUtils::UnpackTrackFlags(
+                       track.fFlags, sign, hitset
+               );
+       
+       // Try find the trigger record in 'event'.
+       const AliHLTMUONTriggerRecord* trigrec = NULL;
+       for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
+       {
+               if (event.Array()[k]->IsA() != AliHLTMUONTriggerRecord::Class())
+                       continue;
+               const AliHLTMUONTriggerRecord* tk =
+                       static_cast<const AliHLTMUONTriggerRecord*>(event.Array()[k]);
+               if (tk->Id() == track.fTrigRec)
+               {
+                       trigrec = tk;
+                       break;
+               }
+       }
+       
+       // Now try find the hits in 'event'.
+       // If they cannot be found then create new ones.
+       const AliHLTMUONRecHit* hits[16];
+       for (int i = 0; i < 16; ++i) hits[i] = NULL;
+       for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
+       {
+               if (event.Array()[k]->IsA() != AliHLTMUONRecHit::Class())
+                       continue;
+               const AliHLTMUONRecHit* h =
+                       static_cast<const AliHLTMUONRecHit*>(event.Array()[k]);
+               for (int i = 0; i < 16; ++i)
+               {
+                       if (hitset[i] and h->X() == track.fHit[i].fX and h->Y() == track.fHit[i].fY
+                           and h->Z() == track.fHit[i].fZ)
+                       {
+                               hits[i] = h;
+                       }
+               }
+       }
+       AliHLTMUONRecHit* newhit;
+       for (int i = 0; i < 16; ++i)
+       {
+               if (hitset[i] and hits[i] == NULL)
+               {
+                       newhit = new AliHLTMUONRecHit(track.fHit[i].fX, track.fHit[i].fY, track.fHit[i].fZ);
+                       event.Add(newhit);
+                       hits[i] = newhit;
+               }
+       }
+
+       AliHLTMUONTrack* tr = new AliHLTMUONTrack(
+                       track.fId, sign, track.fPx, track.fPy, track.fPz,
+                       track.fInverseBendingMomentum, track.fThetaX, track.fThetaY,
+                       track.fX, track.fY, track.fZ, track.fChi2,
+                       trigrec, hits
+               );
+       event.Add(tr);
+       return tr;
+}
index 6fc0cd4..2719458 100644 (file)
@@ -17,6 +17,7 @@
 
 class AliHLTMUONEvent;
 class AliHLTMUONMansoTrack;
+class AliHLTMUONTrack;
 extern "C" struct AliHLTMUONMansoTrackStruct;
 
 /**
@@ -105,6 +106,14 @@ private:
         */
        AliHLTMUONMansoTrack* AddTrack(AliHLTMUONEvent& event, const AliHLTMUONMansoTrackStruct& track);
        
+       /**
+        * This method creates a AliHLTMUONTrack object from the given track structure
+        * and adds it to the dHLT event object.
+        * \param event  The dHLT event object.
+        * \param track  The track structure to convert and add to the event.
+        */
+       AliHLTMUONTrack* AddTrack(AliHLTMUONEvent& event, const AliHLTMUONTrackStruct& track);
+       
        bool fWarnForUnexpecedBlock;  /// Flag indicating if we should log a warning if we got a block of an unexpected type.
 
        ClassDef(AliHLTMUONRootifierComponent, 0); // Converter component of dHLT raw data.
index f6232f9..6f21e0f 100644 (file)
@@ -24,6 +24,7 @@ CLASS_HDRS :=         AliHLTMUONUtils.h \
                AliHLTMUONProcessor.h \
                AliHLTMUONRecHit.h \
                AliHLTMUONTriggerRecord.h \
+               AliHLTMUONTrack.h \
                AliHLTMUONMansoTrack.h \
                AliHLTMUONDecision.h \
                AliHLTMUONEvent.h