]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/AliHLTMUONDecision.cxx
Fixes to trigger reconstruction component to handle real data better.
[u/mrichter/AliRoot.git] / HLT / MUON / AliHLTMUONDecision.cxx
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        * 
3  * All rights reserved.                                                   *
4  *                                                                        *
5  * Primary Authors:                                                       *
6  *   Artur Szostak <artursz@iafrica.com>                                  *
7  *                                                                        *
8  * Permission to use, copy, modify and distribute this software and its   *
9  * documentation strictly for non-commercial purposes is hereby granted   *
10  * without fee, provided that the above copyright notice appears in all   *
11  * copies and that both the copyright notice and this permission notice   *
12  * appear in the supporting documentation. The authors make no claims     *
13  * about the suitability of this software for any purpose. It is          * 
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16
17 // $Id: $
18
19 ///
20 /// @file   AliHLTMUONDecision.cxx
21 /// @author Artur Szostak <artursz@iafrica.com>
22 /// @date   12 May 2008
23 /// @brief  Implementation of the AliHLTMUONDecision class.
24 ///
25 /// The class is used to store the dHLT decision in a more convenient ROOT
26 /// object format for testing and analysis.
27 ///
28
29 #include "AliHLTMUONDecision.h"
30 #include "AliHLTMUONMansoTrack.h"
31 #include "AliLog.h"
32 #include <cstring>
33 #include <iostream>
34 #include <iomanip>
35
36 ClassImp(AliHLTMUONDecision);
37 ClassImp(AliHLTMUONDecision::AliTrackDecision);
38 ClassImp(AliHLTMUONDecision::AliPairDecision);
39
40
41 std::ostream& operator << (
42                 std::ostream& stream,
43                 const AliHLTMUONDecision& decision
44         )
45 {
46 /// Stream operator for std::ostream classes.
47 /// \param stream  The output stream object being written to.
48 /// \param track  The dHLT decision object to print to the stream.
49 /// \returns  Returns 'stream'.
50
51         stream  << "No. low/high pT: [" << decision.fNlowPt
52                 << ", " << decision.fNhighPt
53                 << "]; No. any/low/high unlike: [" << decision.fNunlikeAnyPt
54                 << ", " << decision.fNunlikeLowPt
55                 << ", " << decision.fNunlikeHighPt
56                 << "]; No. any/low/high like = " << decision.fNlikeAnyPt
57                 << ", " << decision.fNlikeLowPt
58                 << ", " << decision.fNlikeHighPt
59                 << "]; No. any/low/high mass = " << decision.fNmassAny
60                 << ", " << decision.fNmassLow
61                 << ", " << decision.fNmassHigh
62                 << "]";
63         return stream;
64 }
65
66
67 AliHLTMUONDecision::AliHLTMUONDecision(
68                 UInt_t nLowPt, UInt_t nHiPt,
69                 UInt_t nUnlikeAnyPt, UInt_t nUnlikeLowPt, UInt_t nUnlikeHighPt,
70                 UInt_t nLikeAnyPt, UInt_t nLikeLowPt, UInt_t nLikeHighPt,
71                 UInt_t nMassAny, UInt_t nMassLow, UInt_t nMassHigh
72         ) :
73         TObject(),
74         fNlowPt(nLowPt),
75         fNhighPt(nHiPt),
76         fNunlikeAnyPt(nUnlikeAnyPt),
77         fNunlikeLowPt(nUnlikeLowPt),
78         fNunlikeHighPt(nUnlikeHighPt),
79         fNlikeAnyPt(nLikeAnyPt),
80         fNlikeLowPt(nLikeLowPt),
81         fNlikeHighPt(nLikeHighPt),
82         fNmassAny(nMassAny),
83         fNmassLow(nMassLow),
84         fNmassHigh(nMassHigh),
85         fTrackDecisions("AliHLTMUONDecision::AliTrackDecision"),
86         fPairDecisions("AliHLTMUONDecision::AliPairDecision")
87 {
88 /// Constructor for creating a dHLT decision object.
89 /// \param nLowPt  Number of tracks above low pT cut.
90 /// \param nHiPt   Number of tracks above high pT cut.
91 /// \param nUnlikeAnyPt  Number of track pairs with unlike sign.
92 /// \param nUnlikeLowPt  Number of unlike sign track pairs with pT > low cut.
93 /// \param nUnlikeHighPt Number of unlike sign track pairs with pT > high cut.
94 /// \param nLikeAnyPt   Number of track pairs with like sign.
95 /// \param nLikeLowPt   Number of like sign track pairs with pT > low cut.
96 /// \param nLikeHighPt  Number of like sign track pairs with pT > high cut.
97 /// \param nMassAny   Number of unlike sign track pairs with invariant mass > low cut.
98 /// \param nMassLow   Number of unlike sign track pairs with invariant mass > low mass cut and pT > low pT cut.
99 /// \param nMassHigh  Number of unlike sign track pairs with invariant mass > high mass cut and pT > high pT cut.
100 }
101
102
103 void AliHLTMUONDecision::AddDecision(
104                 Float_t pt, Bool_t passedLowCut, Bool_t passedHighCut,
105                 const AliHLTMUONMansoTrack* track
106         )
107 {
108 /// Add a single track decision to the dHLT trigger.
109 /// \param pt  The calculated pT value used for the trigger decision.
110 /// \param passedLowCut  Flag indicating if the track passed the low pT cut.
111 /// \param passedHighCut  Flag indicating if the track passed the high pT cut.
112 /// \param track  Pointer to the associated track object.
113
114         new (fTrackDecisions[fTrackDecisions.GetEntriesFast()])
115                 AliTrackDecision(
116                         pt, passedLowCut, passedHighCut, track
117                 );
118 }
119
120
121 void AliHLTMUONDecision::AddDecision(const AliTrackDecision* decision)
122 {
123 /// Add a single track decision to the dHLT trigger.
124
125         new (fTrackDecisions[fTrackDecisions.GetEntriesFast()])
126                 AliTrackDecision(*decision);
127 }
128
129
130 void AliHLTMUONDecision::AddDecision(
131                 Float_t mass, Bool_t passedLowCut,
132                 Bool_t passedHighCut, Bool_t unlike,
133                 UChar_t lowPtCount, UChar_t highPtCount,
134                 const AliHLTMUONMansoTrack* trackA,
135                 const AliHLTMUONMansoTrack* trackB
136         )
137 {
138 /// Add a track pair decision to the dHLT trigger.
139 /// \param mass   The invariant mass of the track pair.
140 /// \param passedLowCut  Indicates if the pair passed the low mass cut.
141 /// \param passedHighCut  Indicates if the pair passed the high mass cut.
142 /// \param unlike   Indicates if the tracks have opposite sign.
143 /// \param lowPtCount  The number of tracks in the pair that passed the low pT cut.
144 ///            Should be in the range [0..2].
145 /// \param highPtCount  The number of tracks in the pair that passed the high pT cut.
146 ///            Should be in the range [0..2].
147 /// \param trackA  Pointer to the first associated track object.
148 /// \param trackB  Pointer to the second associated track object.
149
150         new (fPairDecisions[fPairDecisions.GetEntriesFast()])
151                 AliPairDecision(
152                         mass, passedLowCut, passedHighCut, unlike,
153                         lowPtCount, highPtCount, trackA, trackB
154                 );
155 }
156
157
158 void AliHLTMUONDecision::AddDecision(const AliPairDecision* decision)
159 {
160 /// Add a track pair decision to the dHLT trigger.
161
162         new (fPairDecisions[fPairDecisions.GetEntriesFast()])
163                 AliPairDecision(*decision);
164 }
165
166
167 void AliHLTMUONDecision::Print(Option_t* option) const
168 {
169 /// Prints the trigger decision information to standard output (screen).
170 /// \param option  Can be one of the following:
171 ///      - "compact" - prints in a compact format.
172 ///      - "detail" - prints trigger information in a more detailed format.
173 ///      - "all" - prints a full dump of the trigger object.
174
175         using namespace std;
176         
177         if (option == NULL or strcmp(option, "") == 0 or
178             strcmp(option, "compact") == 0
179            )
180         {
181                 cout << *this << endl;
182         }
183         else if (strcmp(option, "detail") == 0)
184         {
185                 cout << "dHLT trigger decision scalars:" << endl;
186                 cout << "No. tracks passed pT cut," << endl;
187                 cout << "  low = " << fNlowPt << endl;
188                 cout << " high = " << fNhighPt << endl;
189                 cout << "No. unlike sign pairs," << endl;
190                 cout << "          total = " << fNunlikeAnyPt << endl;
191                 cout << "   pT > low cut = " << fNunlikeLowPt << endl;
192                 cout << "  pT > high cut = " << fNunlikeHighPt << endl;
193                 cout << "No. like sign pairs," << endl;
194                 cout << "          total = " << fNlikeAnyPt << endl;
195                 cout << "   pT > low cut = " << fNlikeLowPt << endl;
196                 cout << "  pT > high cut = " << fNlikeHighPt << endl;
197                 cout << "No. pairs with," << endl;
198                 cout << "          invariant mass > low cut = " << fNmassAny << endl;
199                 cout << "   invariant mass and pT > low cut = " << fNmassLow << endl;
200                 cout << "  invariant mass and pT > high cut = " << fNmassHigh << endl;
201                 
202                 streamsize w = cout.width();
203                 ios::fmtflags f = cout.flags();
204                 cout << "Triggers for single tracks:" << endl;
205                 cout << setw(10) << "" << setw(12) << "pT  " << setw(15) << "Passed pT cut" << endl;
206                 cout    << setw(10) << "Track" << setw(12) << "(GeV/c)" << setw(6) << "low "
207                         << setw(3) << " | " << setw(6) << "high" << endl;
208                 for (Int_t i = 0; i < NumberOfTracks(); i++)
209                 {
210                         const AliTrackDecision* decision = SingleTrackDecision(i);
211                         if (decision == NULL) continue;
212                         
213                         if (decision->Track() == NULL)
214                         {
215                                 cout << setw(10) << "-";
216                         }
217                         else
218                         {
219                                 cout << setw(10) << decision->Track()->Id();
220                         }
221                         
222                         cout    << setw(12) << decision->Pt()
223                                 << setw(6) << (decision->PassedLowPtCut() ? "yes" : "no")
224                                 << setw(3) << "   "
225                                 << setw(6) << (decision->PassedHighPtCut() ? "yes" : "no")
226                                 << endl;
227                 }
228                 cout << "Triggers for track pairs:" << endl;
229                 cout    << setw(20) << "Track pair" << setw(6) << "Like" << setw(12) << "mass  "
230                         << setw(17) << "Passed mass cut"
231                         << setw(20) << "No. with pT > than" << endl;
232                 cout    << setw(10) << "track A" << setw(10) << "track B"
233                         << setw(6) << "sign" << setw(12) << "(GeV/c^2)"
234                         << setw(8) << "low " << setw(3) << " | " << setw(6) << "high"
235                         << setw(11) << "low " << setw(3) << " | " << setw(6) << "high" << endl;
236                 for (Int_t j = 0; j < NumberOfPairs(); j++)
237                 {
238                         const AliPairDecision* decision = TrackPairDecision(j);
239                         if (decision == NULL) continue;
240                         
241                         if (decision->TrackA() == NULL)
242                         {
243                                 cout << setw(10) << "-";
244                         }
245                         else
246                         {
247                                 cout << setw(10) << decision->TrackA()->Id();
248                         }
249                         
250                         if (decision->TrackB() == NULL)
251                         {
252                                 cout << setw(10) << "-";
253                         }
254                         else
255                         {
256                                 cout << setw(10) << decision->TrackB()->Id();
257                         }
258                         
259                         cout    << setw(6) << (decision->LikeSign() ? "yes" : "no")
260                                 << setw(12) << decision->Mass()
261                                 << setw(8) << (decision->PassedLowMassCut() ? "yes" : "no")
262                                 << setw(3) << "   "
263                                 << setw(6) << (decision->PassedHighMassCut() ? "yes" : "no")
264                                 << setw(11) << Int_t(decision->NumberPassedLowPtCut())
265                                 << setw(3) << "   "
266                                 << setw(6) << Int_t(decision->NumberPassedHighPtCut())
267                                 << endl;
268                 }
269                 cout.width(w); // reset the field width to previous value.
270                 cout.flags(f); // reset the flags to previous values.
271         }
272         else if (strcmp(option, "all") == 0)
273         {
274                 cout << "dHLT trigger decision scalars:" << endl;
275                 cout << "No. tracks passed pT cut," << endl;
276                 cout << "  low = " << fNlowPt << endl;
277                 cout << " high = " << fNhighPt << endl;
278                 cout << "No. unlike sign pairs," << endl;
279                 cout << "          total = " << fNunlikeAnyPt << endl;
280                 cout << "   pT > low cut = " << fNunlikeLowPt << endl;
281                 cout << "  pT > high cut = " << fNunlikeHighPt << endl;
282                 cout << "No. like sign pairs," << endl;
283                 cout << "          total = " << fNlikeAnyPt << endl;
284                 cout << "   pT > low cut = " << fNlikeLowPt << endl;
285                 cout << "  pT > high cut = " << fNlikeHighPt << endl;
286                 cout << "No. pairs with," << endl;
287                 cout << "          invariant mass > low cut = " << fNmassAny << endl;
288                 cout << "   invariant mass and pT > low cut = " << fNmassLow << endl;
289                 cout << "  invariant mass and pT > high cut = " << fNmassHigh << endl;
290                 
291                 cout << "===============================================" << endl;
292                 cout << "========== Triggers for single tracks: ========" << endl;
293                 for (Int_t i = 0; i < NumberOfTracks(); i++)
294                 {
295                         const AliTrackDecision* decision = SingleTrackDecision(i);
296                         if (decision == NULL) continue;
297                         decision->Print("all");
298                 }
299                 if (NumberOfTracks() == 0) cout << "(None)" << endl;
300                 cout << "===============================================" << endl;
301                 cout << "========== Triggers for track pairs: ==========" << endl;
302                 for (Int_t j = 0; j < NumberOfPairs(); j++)
303                 {
304                         const AliPairDecision* decision = TrackPairDecision(j);
305                         if (decision == NULL) continue;
306                         decision->Print("all");
307                 }
308                 if (NumberOfPairs() == 0) cout << "(None)" << endl;
309         }
310         else
311         {
312                 AliError("Unknown option specified. Can only be one of 'compact',"
313                         " 'detail' or 'all'."
314                 );
315         }
316 }
317
318
319 Int_t AliHLTMUONDecision::Compare(const TObject* obj) const
320 {
321 /// We compare this object with 'obj' first by the trigger scalars and then
322 /// by the signle track and track pair decision lists.
323 /// \param obj  This is the object to compare to. It must be of type AliHLTMUONDecision.
324 /// \returns  -1 if 'this' is smaller than 'obj', 1 if greater and zero if both
325 ///      objects are the same.
326
327         if (obj->IsA() == AliHLTMUONDecision::Class())
328         {
329                 const AliHLTMUONDecision* d =
330                         static_cast<const AliHLTMUONDecision*>(obj);
331                 if (fNlowPt < d->fNlowPt) return -1;
332                 if (fNlowPt > d->fNlowPt) return 1;
333                 if (fNhighPt < d->fNhighPt) return -1;
334                 if (fNhighPt > d->fNhighPt) return 1;
335                 if (fNunlikeAnyPt < d->fNunlikeAnyPt) return -1;
336                 if (fNunlikeAnyPt > d->fNunlikeAnyPt) return 1;
337                 if (fNunlikeLowPt < d->fNunlikeLowPt) return -1;
338                 if (fNunlikeLowPt > d->fNunlikeLowPt) return 1;
339                 if (fNunlikeHighPt < d->fNunlikeHighPt) return -1;
340                 if (fNunlikeHighPt > d->fNunlikeHighPt) return 1;
341                 if (fNlikeAnyPt < d->fNlikeAnyPt) return -1;
342                 if (fNlikeAnyPt > d->fNlikeAnyPt) return 1;
343                 if (fNlikeLowPt < d->fNlikeLowPt) return -1;
344                 if (fNlikeLowPt > d->fNlikeLowPt) return 1;
345                 if (fNlikeHighPt < d->fNlikeHighPt) return -1;
346                 if (fNlikeHighPt > d->fNlikeHighPt) return 1;
347                 if (fNmassAny < d->fNmassAny) return -1;
348                 if (fNmassAny > d->fNmassAny) return 1;
349                 if (fNmassLow < d->fNmassLow) return -1;
350                 if (fNmassLow > d->fNmassLow) return 1;
351                 if (fNmassHigh < d->fNmassHigh) return -1;
352                 if (fNmassHigh > d->fNmassHigh) return 1;
353                 
354                 // Now check the track decision arrays.
355                 if (NumberOfTracks() < d->NumberOfTracks()) return -1;
356                 if (NumberOfTracks() > d->NumberOfTracks()) return 1;
357                 for (Int_t i = 0; i < NumberOfTracks(); i++)
358                 {
359                         Int_t result = SingleTrackDecision(i)->Compare( d->SingleTrackDecision(i) );
360                         if (result != 0) return result;
361                 }
362                 if (NumberOfPairs() < d->NumberOfPairs()) return -1;
363                 if (NumberOfPairs() > d->NumberOfPairs()) return 1;
364                 for (Int_t j = 0; j < NumberOfPairs(); j++)
365                 {
366                         Int_t result = TrackPairDecision(j)->Compare( d->TrackPairDecision(j) );
367                         if (result != 0) return result;
368                 }
369                 
370                 // At this point everything was equal so return 0 to indicate this fact.
371                 return 0;
372         }
373         else
374         {
375                 AliError(Form("Do not know how to compare %s to %s.",
376                         this->ClassName(),
377                         obj->ClassName()
378                 ));
379                 return -999;
380         }
381 }
382
383
384 bool AliHLTMUONDecision::operator == (const AliHLTMUONDecision& decision) const
385 {
386 /// Comparison operator just compares if the scalars are the same.
387 /// \param decision  The trigger decision object to compare to.
388 /// \returns  true if 'this' object has the same scalars as 'decision', else false.
389
390         return  fNlowPt == decision.fNlowPt
391                 and fNhighPt == decision.fNhighPt
392                 and fNunlikeAnyPt == decision.fNunlikeAnyPt
393                 and fNunlikeLowPt == decision.fNunlikeLowPt
394                 and fNunlikeHighPt == decision.fNunlikeHighPt
395                 and fNlikeAnyPt == decision.fNlikeAnyPt
396                 and fNlikeLowPt == decision.fNlikeLowPt
397                 and fNlikeHighPt == decision.fNlikeHighPt
398                 and fNmassAny == decision.fNmassAny
399                 and fNmassLow == decision.fNmassLow
400                 and fNmassHigh == decision.fNmassHigh;
401 }
402
403
404 std::ostream& operator << (
405                 std::ostream& stream,
406                 const AliHLTMUONDecision::AliTrackDecision& decision
407         )
408 {
409 /// Stream operator for std::ostream classes.
410 /// \param stream  The output stream object being written to.
411 /// \param track  The dHLT decision object to print to the stream.
412 /// \returns  Returns 'stream'.
413
414         stream  << "Passed low/high pT cut: [" << (decision.fPassedLowCut ? "yes" : "no")
415                 << ", " << (decision.fPassedHighCut ? "yes" : "no")
416                 << "]; with pT = " << decision.fPt;
417         return stream;
418 }
419
420
421 void AliHLTMUONDecision::AliTrackDecision::Print(Option_t* option) const
422 {
423 /// Prints the trigger decision to standard output (screen).
424 /// \param option  Can be one of the following:
425 ///      - "compact" - prints in a compact format.
426 ///      - "detail" - prints trigger information in a more detailed format.
427 ///      - "all" - prints a full dump of the trigger object.
428
429         using namespace std;
430         
431         if (option == NULL or strcmp(option, "") == 0 or
432             strcmp(option, "compact") == 0
433            )
434         {
435                 cout << *this << endl;
436         }
437         else if (strcmp(option, "detail") == 0)
438         {
439                 cout << "Trigger decision for track: " << fTrack->Id() << endl;
440                 cout << "pT = " << fPt << " GeV/c" << endl;
441                 cout << "pT cut | passed" << endl;
442                 cout << "-------+--------" << endl;
443                 cout << "  low  |  " << (fPassedLowCut ? "yes" : "no") << endl;
444                 cout << " high  |  " << (fPassedHighCut ? "yes" : "no") << endl;
445         }
446         else if (strcmp(option, "all") == 0)
447         {
448                 cout << "Trigger decision for track: " << fTrack->Id() << endl;
449                 cout << "pT = " << fPt << " GeV/c" << endl;
450                 cout << "pT cut | passed" << endl;
451                 cout << "-------+--------" << endl;
452                 cout << "  low  |  " << (fPassedLowCut ? "yes" : "no") << endl;
453                 cout << " high  |  " << (fPassedHighCut ? "yes" : "no") << endl;
454                 cout << "===== Track details =====" << endl;
455                 fTrack->Print("all");
456         }
457         else
458         {
459                 AliError("Unknown option specified. Can only be one of 'compact',"
460                         " 'detail' or 'all'."
461                 );
462         }
463 }
464
465
466 Int_t AliHLTMUONDecision::AliTrackDecision::Compare(const TObject* obj) const
467 {
468 /// We compare this object with 'obj' field by field.
469 /// \param obj  This is the object to compare to. It must be of type
470 ///      AliHLTMUONDecision::AliTrackDecision.
471 /// \returns  -1 if 'this' is smaller than 'obj', 1 if greater and zero if both
472 ///      objects are the same.
473
474         if (obj->IsA() == AliHLTMUONDecision::Class())
475         {
476                 const AliHLTMUONDecision::AliTrackDecision* d =
477                         static_cast<const AliHLTMUONDecision::AliTrackDecision*>(obj);
478                 if (fPt < d->fPt) return -1;
479                 if (fPt > d->fPt) return 1;
480                 if (fPassedLowCut < d->fPassedLowCut) return -1;
481                 if (fPassedLowCut > d->fPassedLowCut) return 1;
482                 if (fPassedHighCut < d->fPassedHighCut) return -1;
483                 if (fPassedHighCut > d->fPassedHighCut) return 1;
484                 return fTrack->Compare(d->fTrack);
485         }
486         else
487         {
488                 AliError(Form("Do not know how to compare %s to %s.",
489                         this->ClassName(),
490                         obj->ClassName()
491                 ));
492                 return -999;
493         }
494 }
495
496
497 std::ostream& operator << (
498                 std::ostream& stream,
499                 const AliHLTMUONDecision::AliPairDecision& decision
500         )
501 {
502 /// Stream operator for std::ostream classes.
503 /// \param stream  The output stream object being written to.
504 /// \param track  The dHLT decision object to print to the stream.
505 /// \returns  Returns 'stream'.
506
507         stream  << (decision.fUnlike ? "Unlike" : "Like")
508                 << " sign pair passed low/high mass cut: [" << (decision.fPassedLowCut ? "yes" : "no")
509                 << ", " << (decision.fPassedHighCut ? "yes" : "no")
510                 << "]; with mass = " << decision.fMass;
511         return stream;
512 }
513
514
515 void AliHLTMUONDecision::AliPairDecision::Print(Option_t* option) const
516 {
517 /// Prints the trigger decision to standard output (screen).
518 /// \param option  Can be one of the following:
519 ///      - "compact" - prints in a compact format.
520 ///      - "detail" - prints trigger information in a more detailed format.
521 ///      - "all" - prints a full dump of the trigger object.
522
523         using namespace std;
524         
525         if (option == NULL or strcmp(option, "") == 0 or
526             strcmp(option, "compact") == 0
527            )
528         {
529                 cout << *this << endl;
530         }
531         else if (strcmp(option, "detail") == 0)
532         {
533                 cout    << "Trigger decision for track pair: {" << fTrackA->Id()
534                         << ", " << fTrackB->Id() << "}" << endl;
535                 cout << "Invariant mass = " << fMass << " GeV/c^2" << endl;
536                 cout << "mass cut | passed" << endl;
537                 cout << "---------+--------" << endl;
538                 cout << "   low   |  " << (fPassedLowCut ? "yes" : "no") << endl;
539                 cout << "  high   |  " << (fPassedHighCut ? "yes" : "no") << endl;
540                 cout << "Number of tracks in pair that passed," << endl;
541                 cout << "   low pT cut = " << Int_t(fLowPtCount) << endl;
542                 cout << "  high pT cut = " << Int_t(fHighPtCount) << endl;
543         }
544         else if (strcmp(option, "all") == 0)
545         {
546                 cout    << "Trigger decision for track pair: {" << fTrackA->Id()
547                         << ", " << fTrackB->Id() << "}" << endl;
548                 cout << "Invariant mass = " << fMass << " GeV/c^2" << endl;
549                 cout << "mass cut | passed" << endl;
550                 cout << "---------+--------" << endl;
551                 cout << "   low   |  " << (fPassedLowCut ? "yes" : "no") << endl;
552                 cout << "  high   |  " << (fPassedHighCut ? "yes" : "no") << endl;
553                 cout << "Number of tracks in pair that passed," << endl;
554                 cout << "   low pT cut = " << Int_t(fLowPtCount) << endl;
555                 cout << "  high pT cut = " << Int_t(fHighPtCount) << endl;
556                 cout << "===== First track details =====" << endl;
557                 fTrackA->Print("all");
558                 cout << "===== Second track details =====" << endl;
559                 fTrackB->Print("all");
560         }
561         else
562         {
563                 AliError("Unknown option specified. Can only be one of 'compact',"
564                         " 'detail' or 'all'."
565                 );
566         }
567 }
568
569
570 Int_t AliHLTMUONDecision::AliPairDecision::Compare(const TObject* obj) const
571 {
572 /// We compare this object with 'obj' field by field.
573 /// \param obj  This is the object to compare to. It must be of type
574 ///      AliHLTMUONDecision::AliPairDecision.
575 /// \returns  -1 if 'this' is smaller than 'obj', 1 if greater and zero if both
576 ///      objects are the same.
577
578         if (obj->IsA() == AliHLTMUONDecision::Class())
579         {
580                 const AliHLTMUONDecision::AliPairDecision* d =
581                         static_cast<const AliHLTMUONDecision::AliPairDecision*>(obj);
582                 if (fMass < d->fMass) return -1;
583                 if (fMass > d->fMass) return 1;
584                 if (fPassedLowCut < d->fPassedLowCut) return -1;
585                 if (fPassedLowCut > d->fPassedLowCut) return 1;
586                 if (fPassedHighCut < d->fPassedHighCut) return -1;
587                 if (fPassedHighCut > d->fPassedHighCut) return 1;
588                 if (fUnlike < d->fUnlike) return -1;
589                 if (fUnlike > d->fUnlike) return 1;
590                 if (fLowPtCount < d->fLowPtCount) return -1;
591                 if (fLowPtCount > d->fLowPtCount) return 1;
592                 if (fHighPtCount < d->fHighPtCount) return -1;
593                 if (fHighPtCount > d->fHighPtCount) return 1;
594                 Int_t result = fTrackA->Compare(d->fTrackA);
595                 if (result != 0) return result;
596                 return fTrackB->Compare(d->fTrackB);
597         }
598         else
599         {
600                 AliError(Form("Do not know how to compare %s to %s.",
601                         this->ClassName(),
602                         obj->ClassName()
603                 ));
604                 return -999;
605         }
606 }
607