Update master to aliroot
[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 "AliHLTMUONTrack.h"
31 #include "AliHLTMUONMansoTrack.h"
32 #include "AliLog.h"
33 #include <cstring>
34 #include <iostream>
35 #include <iomanip>
36
37 ClassImp(AliHLTMUONDecision);
38 ClassImp(AliHLTMUONDecision::AliTrackDecision);
39 ClassImp(AliHLTMUONDecision::AliPairDecision);
40
41
42 std::ostream& operator << (
43                 std::ostream& stream,
44                 const AliHLTMUONDecision& decision
45         )
46 {
47 /// Stream operator for std::ostream classes.
48 /// \param stream  The output stream object being written to.
49 /// \param track  The dHLT decision object to print to the stream.
50 /// \returns  Returns 'stream'.
51
52         stream  << "No. low/high pT: [" << decision.fNlowPt
53                 << ", " << decision.fNhighPt
54                 << "]; No. any/low/high unlike: [" << decision.fNunlikeAnyPt
55                 << ", " << decision.fNunlikeLowPt
56                 << ", " << decision.fNunlikeHighPt
57                 << "]; No. any/low/high like = " << decision.fNlikeAnyPt
58                 << ", " << decision.fNlikeLowPt
59                 << ", " << decision.fNlikeHighPt
60                 << "]; No. any/low/high mass = " << decision.fNmassAny
61                 << ", " << decision.fNmassLow
62                 << ", " << decision.fNmassHigh
63                 << "]";
64         return stream;
65 }
66
67
68 AliHLTMUONDecision::AliHLTMUONDecision(
69                 UInt_t nLowPt, UInt_t nHiPt,
70                 UInt_t nUnlikeAnyPt, UInt_t nUnlikeLowPt, UInt_t nUnlikeHighPt,
71                 UInt_t nLikeAnyPt, UInt_t nLikeLowPt, UInt_t nLikeHighPt,
72                 UInt_t nMassAny, UInt_t nMassLow, UInt_t nMassHigh
73         ) :
74         TObject(),
75         fNlowPt(nLowPt),
76         fNhighPt(nHiPt),
77         fNunlikeAnyPt(nUnlikeAnyPt),
78         fNunlikeLowPt(nUnlikeLowPt),
79         fNunlikeHighPt(nUnlikeHighPt),
80         fNlikeAnyPt(nLikeAnyPt),
81         fNlikeLowPt(nLikeLowPt),
82         fNlikeHighPt(nLikeHighPt),
83         fNmassAny(nMassAny),
84         fNmassLow(nMassLow),
85         fNmassHigh(nMassHigh),
86         fTrackDecisions("AliHLTMUONDecision::AliTrackDecision"),
87         fPairDecisions("AliHLTMUONDecision::AliPairDecision")
88 {
89 /// Constructor for creating a dHLT decision object.
90 /// \param nLowPt  Number of tracks above low pT cut.
91 /// \param nHiPt   Number of tracks above high pT cut.
92 /// \param nUnlikeAnyPt  Number of track pairs with unlike sign.
93 /// \param nUnlikeLowPt  Number of unlike sign track pairs with pT > low cut.
94 /// \param nUnlikeHighPt Number of unlike sign track pairs with pT > high cut.
95 /// \param nLikeAnyPt   Number of track pairs with like sign.
96 /// \param nLikeLowPt   Number of like sign track pairs with pT > low cut.
97 /// \param nLikeHighPt  Number of like sign track pairs with pT > high cut.
98 /// \param nMassAny   Number of unlike sign track pairs with invariant mass > low cut.
99 /// \param nMassLow   Number of unlike sign track pairs with invariant mass > low mass cut and pT > low pT cut.
100 /// \param nMassHigh  Number of unlike sign track pairs with invariant mass > high mass cut and pT > high pT cut.
101 }
102
103
104 void AliHLTMUONDecision::AddDecision(
105                 Float_t pt, Bool_t passedLowCut, Bool_t passedHighCut,
106                 const TObject* track
107         )
108 {
109 /// Add a single track decision to the dHLT trigger.
110 /// \param pt  The calculated pT value used for the trigger decision.
111 /// \param passedLowCut  Flag indicating if the track passed the low pT cut.
112 /// \param passedHighCut  Flag indicating if the track passed the high pT cut.
113 /// \param track  Pointer to the associated track object.
114
115         new (fTrackDecisions[fTrackDecisions.GetEntriesFast()])
116                 AliTrackDecision(
117                         pt, passedLowCut, passedHighCut, track
118                 );
119 }
120
121
122 void AliHLTMUONDecision::AddDecision(const AliTrackDecision* decision)
123 {
124 /// Add a single track decision to the dHLT trigger.
125
126         new (fTrackDecisions[fTrackDecisions.GetEntriesFast()])
127                 AliTrackDecision(*decision);
128 }
129
130
131 void AliHLTMUONDecision::AddDecision(
132                 Float_t mass, Bool_t passedLowCut,
133                 Bool_t passedHighCut, Bool_t unlike,
134                 UChar_t lowPtCount, UChar_t highPtCount,
135                 const TObject* trackA, const TObject* 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->MansoTrack() != NULL)
214                         {
215                                 cout << setw(10) << decision->MansoTrack()->Id();
216                         }
217                         else if (decision->FullTrack() != NULL)
218                         {
219                                 cout << setw(10) << decision->FullTrack()->Id();
220                         }
221                         else
222                         {
223                                 cout << setw(10) << "-";
224                         }
225                         
226                         cout    << setw(12) << decision->Pt()
227                                 << setw(6) << (decision->PassedLowPtCut() ? "yes" : "no")
228                                 << setw(3) << "   "
229                                 << setw(6) << (decision->PassedHighPtCut() ? "yes" : "no")
230                                 << endl;
231                 }
232                 cout << "Triggers for track pairs:" << endl;
233                 cout    << setw(20) << "Track pair" << setw(6) << "Like" << setw(12) << "mass  "
234                         << setw(17) << "Passed mass cut"
235                         << setw(20) << "No. with pT > than" << endl;
236                 cout    << setw(10) << "track A" << setw(10) << "track B"
237                         << setw(6) << "sign" << setw(12) << "(GeV/c^2)"
238                         << setw(8) << "low " << setw(3) << " | " << setw(6) << "high"
239                         << setw(11) << "low " << setw(3) << " | " << setw(6) << "high" << endl;
240                 for (Int_t j = 0; j < NumberOfPairs(); j++)
241                 {
242                         const AliPairDecision* decision = TrackPairDecision(j);
243                         if (decision == NULL) continue;
244                         
245                         if (decision->MansoTrackA() != NULL)
246                         {
247                                 cout << setw(10) << decision->MansoTrackA()->Id();
248                         }
249                         else if (decision->FullTrackA() != NULL)
250                         {
251                                 cout << setw(10) << decision->FullTrackA()->Id();
252                         }
253                         else
254                         {
255                                 cout << setw(10) << "-";
256                         }
257                         
258                         if (decision->MansoTrackB() != NULL)
259                         {
260                                 cout << setw(10) << decision->MansoTrackB()->Id();
261                         }
262                         else if (decision->FullTrackB() != NULL)
263                         {
264                                 cout << setw(10) << decision->FullTrackB()->Id();
265                         }
266                         else
267                         {
268                                 cout << setw(10) << "-";
269                         }
270                         
271                         cout    << setw(6) << (decision->LikeSign() ? "yes" : "no")
272                                 << setw(12) << decision->Mass()
273                                 << setw(8) << (decision->PassedLowMassCut() ? "yes" : "no")
274                                 << setw(3) << "   "
275                                 << setw(6) << (decision->PassedHighMassCut() ? "yes" : "no")
276                                 << setw(11) << Int_t(decision->NumberPassedLowPtCut())
277                                 << setw(3) << "   "
278                                 << setw(6) << Int_t(decision->NumberPassedHighPtCut())
279                                 << endl;
280                 }
281                 cout.width(w); // reset the field width to previous value.
282                 cout.flags(f); // reset the flags to previous values.
283         }
284         else if (strcmp(option, "all") == 0)
285         {
286                 cout << "dHLT trigger decision scalars:" << endl;
287                 cout << "No. tracks passed pT cut," << endl;
288                 cout << "  low = " << fNlowPt << endl;
289                 cout << " high = " << fNhighPt << endl;
290                 cout << "No. unlike sign pairs," << endl;
291                 cout << "          total = " << fNunlikeAnyPt << endl;
292                 cout << "   pT > low cut = " << fNunlikeLowPt << endl;
293                 cout << "  pT > high cut = " << fNunlikeHighPt << endl;
294                 cout << "No. like sign pairs," << endl;
295                 cout << "          total = " << fNlikeAnyPt << endl;
296                 cout << "   pT > low cut = " << fNlikeLowPt << endl;
297                 cout << "  pT > high cut = " << fNlikeHighPt << endl;
298                 cout << "No. pairs with," << endl;
299                 cout << "          invariant mass > low cut = " << fNmassAny << endl;
300                 cout << "   invariant mass and pT > low cut = " << fNmassLow << endl;
301                 cout << "  invariant mass and pT > high cut = " << fNmassHigh << endl;
302                 
303                 cout << "===============================================" << endl;
304                 cout << "========== Triggers for single tracks: ========" << endl;
305                 for (Int_t i = 0; i < NumberOfTracks(); i++)
306                 {
307                         const AliTrackDecision* decision = SingleTrackDecision(i);
308                         if (decision == NULL) continue;
309                         decision->Print("all");
310                 }
311                 if (NumberOfTracks() == 0) cout << "(None)" << endl;
312                 cout << "===============================================" << endl;
313                 cout << "========== Triggers for track pairs: ==========" << endl;
314                 for (Int_t j = 0; j < NumberOfPairs(); j++)
315                 {
316                         const AliPairDecision* decision = TrackPairDecision(j);
317                         if (decision == NULL) continue;
318                         decision->Print("all");
319                 }
320                 if (NumberOfPairs() == 0) cout << "(None)" << endl;
321         }
322         else
323         {
324                 AliError("Unknown option specified. Can only be one of 'compact',"
325                         " 'detail' or 'all'."
326                 );
327         }
328 }
329
330
331 Int_t AliHLTMUONDecision::Compare(const TObject* obj) const
332 {
333 /// We compare this object with 'obj' first by the trigger scalars and then
334 /// by the signle track and track pair decision lists.
335 /// \param obj  This is the object to compare to. It must be of type AliHLTMUONDecision.
336 /// \returns  -1 if 'this' is smaller than 'obj', 1 if greater and zero if both
337 ///      objects are the same.
338
339         if (obj->IsA() == AliHLTMUONDecision::Class())
340         {
341                 const AliHLTMUONDecision* d =
342                         static_cast<const AliHLTMUONDecision*>(obj);
343                 if (fNlowPt < d->fNlowPt) return -1;
344                 if (fNlowPt > d->fNlowPt) return 1;
345                 if (fNhighPt < d->fNhighPt) return -1;
346                 if (fNhighPt > d->fNhighPt) return 1;
347                 if (fNunlikeAnyPt < d->fNunlikeAnyPt) return -1;
348                 if (fNunlikeAnyPt > d->fNunlikeAnyPt) return 1;
349                 if (fNunlikeLowPt < d->fNunlikeLowPt) return -1;
350                 if (fNunlikeLowPt > d->fNunlikeLowPt) return 1;
351                 if (fNunlikeHighPt < d->fNunlikeHighPt) return -1;
352                 if (fNunlikeHighPt > d->fNunlikeHighPt) return 1;
353                 if (fNlikeAnyPt < d->fNlikeAnyPt) return -1;
354                 if (fNlikeAnyPt > d->fNlikeAnyPt) return 1;
355                 if (fNlikeLowPt < d->fNlikeLowPt) return -1;
356                 if (fNlikeLowPt > d->fNlikeLowPt) return 1;
357                 if (fNlikeHighPt < d->fNlikeHighPt) return -1;
358                 if (fNlikeHighPt > d->fNlikeHighPt) return 1;
359                 if (fNmassAny < d->fNmassAny) return -1;
360                 if (fNmassAny > d->fNmassAny) return 1;
361                 if (fNmassLow < d->fNmassLow) return -1;
362                 if (fNmassLow > d->fNmassLow) return 1;
363                 if (fNmassHigh < d->fNmassHigh) return -1;
364                 if (fNmassHigh > d->fNmassHigh) return 1;
365                 
366                 // Now check the track decision arrays.
367                 if (NumberOfTracks() < d->NumberOfTracks()) return -1;
368                 if (NumberOfTracks() > d->NumberOfTracks()) return 1;
369                 for (Int_t i = 0; i < NumberOfTracks(); i++)
370                 {
371                         Int_t result = SingleTrackDecision(i)->Compare( d->SingleTrackDecision(i) );
372                         if (result != 0) return result;
373                 }
374                 if (NumberOfPairs() < d->NumberOfPairs()) return -1;
375                 if (NumberOfPairs() > d->NumberOfPairs()) return 1;
376                 for (Int_t j = 0; j < NumberOfPairs(); j++)
377                 {
378                         Int_t result = TrackPairDecision(j)->Compare( d->TrackPairDecision(j) );
379                         if (result != 0) return result;
380                 }
381                 
382                 // At this point everything was equal so return 0 to indicate this fact.
383                 return 0;
384         }
385         else
386         {
387                 AliError(Form("Do not know how to compare %s to %s.",
388                         this->ClassName(),
389                         obj->ClassName()
390                 ));
391                 return -999;
392         }
393 }
394
395
396 bool AliHLTMUONDecision::operator == (const AliHLTMUONDecision& decision) const
397 {
398 /// Comparison operator just compares if the scalars are the same.
399 /// \param decision  The trigger decision object to compare to.
400 /// \returns  true if 'this' object has the same scalars as 'decision', else false.
401
402         return  fNlowPt == decision.fNlowPt
403                 and fNhighPt == decision.fNhighPt
404                 and fNunlikeAnyPt == decision.fNunlikeAnyPt
405                 and fNunlikeLowPt == decision.fNunlikeLowPt
406                 and fNunlikeHighPt == decision.fNunlikeHighPt
407                 and fNlikeAnyPt == decision.fNlikeAnyPt
408                 and fNlikeLowPt == decision.fNlikeLowPt
409                 and fNlikeHighPt == decision.fNlikeHighPt
410                 and fNmassAny == decision.fNmassAny
411                 and fNmassLow == decision.fNmassLow
412                 and fNmassHigh == decision.fNmassHigh;
413 }
414
415
416 std::ostream& operator << (
417                 std::ostream& stream,
418                 const AliHLTMUONDecision::AliTrackDecision& decision
419         )
420 {
421 /// Stream operator for std::ostream classes.
422 /// \param stream  The output stream object being written to.
423 /// \param track  The dHLT decision object to print to the stream.
424 /// \returns  Returns 'stream'.
425
426         stream  << "Passed low/high pT cut: [" << (decision.fPassedLowCut ? "yes" : "no")
427                 << ", " << (decision.fPassedHighCut ? "yes" : "no")
428                 << "]; with pT = " << decision.fPt;
429         return stream;
430 }
431
432
433 const AliHLTMUONMansoTrack* AliHLTMUONDecision::AliTrackDecision::MansoTrack() const
434 {
435 /// Returns the associated track as a Manso track object and NULL if the track
436 /// object is missing or not a Manso track object.
437
438         if (fTrack == NULL) return NULL;
439         return dynamic_cast<const AliHLTMUONMansoTrack*>(fTrack);
440 }
441
442
443 const AliHLTMUONTrack* AliHLTMUONDecision::AliTrackDecision::FullTrack() const
444 {
445 /// Returns the associated track as a full track object and NULL if the track
446 /// object is missing or not a full track object.
447
448         if (fTrack == NULL) return NULL;
449         return dynamic_cast<const AliHLTMUONTrack*>(fTrack);
450 }
451
452
453 void AliHLTMUONDecision::AliTrackDecision::Print(Option_t* option) const
454 {
455 /// Prints the trigger decision to standard output (screen).
456 /// \param option  Can be one of the following:
457 ///      - "compact" - prints in a compact format.
458 ///      - "detail" - prints trigger information in a more detailed format.
459 ///      - "all" - prints a full dump of the trigger object.
460
461         using namespace std;
462         
463         if (option == NULL or strcmp(option, "") == 0 or
464             strcmp(option, "compact") == 0
465            )
466         {
467                 cout << *this << endl;
468         }
469         else if (strcmp(option, "detail") == 0)
470         {
471                 Int_t id = -1;
472                 if (MansoTrack() != NULL) id = MansoTrack()->Id();
473                 else if (FullTrack() != NULL) id = FullTrack()->Id();
474                 cout << "Trigger decision for track: " << id << endl;
475                 cout << "pT = " << fPt << " GeV/c" << endl;
476                 cout << "pT cut | passed" << endl;
477                 cout << "-------+--------" << endl;
478                 cout << "  low  |  " << (fPassedLowCut ? "yes" : "no") << endl;
479                 cout << " high  |  " << (fPassedHighCut ? "yes" : "no") << endl;
480         }
481         else if (strcmp(option, "all") == 0)
482         {
483                 Int_t id = -1;
484                 if (MansoTrack() != NULL) id = MansoTrack()->Id();
485                 else if (FullTrack() != NULL) id = FullTrack()->Id();
486                 cout << "Trigger decision for track: " << id << endl;
487                 cout << "pT = " << fPt << " GeV/c" << endl;
488                 cout << "pT cut | passed" << endl;
489                 cout << "-------+--------" << endl;
490                 cout << "  low  |  " << (fPassedLowCut ? "yes" : "no") << endl;
491                 cout << " high  |  " << (fPassedHighCut ? "yes" : "no") << endl;
492                 cout << "===== Track details =====" << endl;
493                 fTrack->Print("all");
494         }
495         else
496         {
497                 AliError("Unknown option specified. Can only be one of 'compact',"
498                         " 'detail' or 'all'."
499                 );
500         }
501 }
502
503
504 Int_t AliHLTMUONDecision::AliTrackDecision::Compare(const TObject* obj) const
505 {
506 /// We compare this object with 'obj' field by field.
507 /// \param obj  This is the object to compare to. It must be of type
508 ///      AliHLTMUONDecision::AliTrackDecision.
509 /// \returns  -1 if 'this' is smaller than 'obj', 1 if greater and zero if both
510 ///      objects are the same.
511
512         if (obj->IsA() == AliHLTMUONDecision::Class())
513         {
514                 const AliHLTMUONDecision::AliTrackDecision* d =
515                         static_cast<const AliHLTMUONDecision::AliTrackDecision*>(obj);
516                 if (fPt < d->fPt) return -1;
517                 if (fPt > d->fPt) return 1;
518                 if (fPassedLowCut < d->fPassedLowCut) return -1;
519                 if (fPassedLowCut > d->fPassedLowCut) return 1;
520                 if (fPassedHighCut < d->fPassedHighCut) return -1;
521                 if (fPassedHighCut > d->fPassedHighCut) return 1;
522                 return fTrack->Compare(d->fTrack);
523         }
524         else
525         {
526                 AliError(Form("Do not know how to compare %s to %s.",
527                         this->ClassName(),
528                         obj->ClassName()
529                 ));
530                 return -999;
531         }
532 }
533
534
535 std::ostream& operator << (
536                 std::ostream& stream,
537                 const AliHLTMUONDecision::AliPairDecision& decision
538         )
539 {
540 /// Stream operator for std::ostream classes.
541 /// \param stream  The output stream object being written to.
542 /// \param track  The dHLT decision object to print to the stream.
543 /// \returns  Returns 'stream'.
544
545         stream  << (decision.fUnlike ? "Unlike" : "Like")
546                 << " sign pair passed low/high mass cut: [" << (decision.fPassedLowCut ? "yes" : "no")
547                 << ", " << (decision.fPassedHighCut ? "yes" : "no")
548                 << "]; with mass = " << decision.fMass;
549         return stream;
550 }
551
552
553 const AliHLTMUONMansoTrack* AliHLTMUONDecision::AliPairDecision::MansoTrackA() const
554 {
555 /// Returns the first associated track as a Manso track object and NULL if the
556 /// track object is missing or not a Manso track object.
557
558         if (fTrackA == NULL) return NULL;
559         return dynamic_cast<const AliHLTMUONMansoTrack*>(fTrackA);
560 }
561
562
563 const AliHLTMUONTrack* AliHLTMUONDecision::AliPairDecision::FullTrackA() const
564 {
565 /// Returns the first associated track as a full track object and NULL if the
566 /// track object is missing or not a full track object.
567
568         if (fTrackA == NULL) return NULL;
569         return dynamic_cast<const AliHLTMUONTrack*>(fTrackA);
570 }
571
572
573 const AliHLTMUONMansoTrack* AliHLTMUONDecision::AliPairDecision::MansoTrackB() const
574 {
575 /// Returns the second associated track as a Manso track object and NULL if the
576 /// track object is missing or not a Manso track object.
577
578         if (fTrackB == NULL) return NULL;
579         return dynamic_cast<const AliHLTMUONMansoTrack*>(fTrackB);
580 }
581
582
583 const AliHLTMUONTrack* AliHLTMUONDecision::AliPairDecision::FullTrackB() const
584 {
585 /// Returns the second associated track as a full track object and NULL if the
586 /// track object is missing or not a full track object.
587
588         if (fTrackB == NULL) return NULL;
589         return dynamic_cast<const AliHLTMUONTrack*>(fTrackB);
590 }
591
592
593 void AliHLTMUONDecision::AliPairDecision::Print(Option_t* option) const
594 {
595 /// Prints the trigger decision to standard output (screen).
596 /// \param option  Can be one of the following:
597 ///      - "compact" - prints in a compact format.
598 ///      - "detail" - prints trigger information in a more detailed format.
599 ///      - "all" - prints a full dump of the trigger object.
600
601         using namespace std;
602         
603         if (option == NULL or strcmp(option, "") == 0 or
604             strcmp(option, "compact") == 0
605            )
606         {
607                 cout << *this << endl;
608         }
609         else if (strcmp(option, "detail") == 0)
610         {
611                 Int_t id1 = -1;
612                 if (MansoTrackA() != NULL) id1 = MansoTrackA()->Id();
613                 else if (FullTrackA() != NULL) id1 = FullTrackA()->Id();
614                 Int_t id2 = -1;
615                 if (MansoTrackB() != NULL) id2 = MansoTrackB()->Id();
616                 else if (FullTrackB() != NULL) id2 = FullTrackB()->Id();
617                 cout    << "Trigger decision for track pair: {" << id1
618                         << ", " << id2 << "}" << endl;
619                 cout << "Invariant mass = " << fMass << " GeV/c^2" << endl;
620                 cout << "mass cut | passed" << endl;
621                 cout << "---------+--------" << endl;
622                 cout << "   low   |  " << (fPassedLowCut ? "yes" : "no") << endl;
623                 cout << "  high   |  " << (fPassedHighCut ? "yes" : "no") << endl;
624                 cout << "Number of tracks in pair that passed," << endl;
625                 cout << "   low pT cut = " << Int_t(fLowPtCount) << endl;
626                 cout << "  high pT cut = " << Int_t(fHighPtCount) << endl;
627         }
628         else if (strcmp(option, "all") == 0)
629         {
630                 Int_t id1 = -1;
631                 if (MansoTrackA() != NULL) id1 = MansoTrackA()->Id();
632                 else if (FullTrackA() != NULL) id1 = FullTrackA()->Id();
633                 Int_t id2 = -1;
634                 if (MansoTrackB() != NULL) id2 = MansoTrackB()->Id();
635                 else if (FullTrackB() != NULL) id2 = FullTrackB()->Id();
636                 cout    << "Trigger decision for track pair: {" << id1
637                         << ", " << id2 << "}" << endl;
638                 cout << "Invariant mass = " << fMass << " GeV/c^2" << endl;
639                 cout << "mass cut | passed" << endl;
640                 cout << "---------+--------" << endl;
641                 cout << "   low   |  " << (fPassedLowCut ? "yes" : "no") << endl;
642                 cout << "  high   |  " << (fPassedHighCut ? "yes" : "no") << endl;
643                 cout << "Number of tracks in pair that passed," << endl;
644                 cout << "   low pT cut = " << Int_t(fLowPtCount) << endl;
645                 cout << "  high pT cut = " << Int_t(fHighPtCount) << endl;
646                 cout << "===== First track details =====" << endl;
647                 fTrackA->Print("all");
648                 cout << "===== Second track details =====" << endl;
649                 fTrackB->Print("all");
650         }
651         else
652         {
653                 AliError("Unknown option specified. Can only be one of 'compact',"
654                         " 'detail' or 'all'."
655                 );
656         }
657 }
658
659
660 Int_t AliHLTMUONDecision::AliPairDecision::Compare(const TObject* obj) const
661 {
662 /// We compare this object with 'obj' field by field.
663 /// \param obj  This is the object to compare to. It must be of type
664 ///      AliHLTMUONDecision::AliPairDecision.
665 /// \returns  -1 if 'this' is smaller than 'obj', 1 if greater and zero if both
666 ///      objects are the same.
667
668         if (obj->IsA() == AliHLTMUONDecision::Class())
669         {
670                 const AliHLTMUONDecision::AliPairDecision* d =
671                         static_cast<const AliHLTMUONDecision::AliPairDecision*>(obj);
672                 if (fMass < d->fMass) return -1;
673                 if (fMass > d->fMass) return 1;
674                 if (fPassedLowCut < d->fPassedLowCut) return -1;
675                 if (fPassedLowCut > d->fPassedLowCut) return 1;
676                 if (fPassedHighCut < d->fPassedHighCut) return -1;
677                 if (fPassedHighCut > d->fPassedHighCut) return 1;
678                 if (fUnlike < d->fUnlike) return -1;
679                 if (fUnlike > d->fUnlike) return 1;
680                 if (fLowPtCount < d->fLowPtCount) return -1;
681                 if (fLowPtCount > d->fLowPtCount) return 1;
682                 if (fHighPtCount < d->fHighPtCount) return -1;
683                 if (fHighPtCount > d->fHighPtCount) return 1;
684                 Int_t result = fTrackA->Compare(d->fTrackA);
685                 if (result != 0) return result;
686                 return fTrackB->Compare(d->fTrackB);
687         }
688         else
689         {
690                 AliError(Form("Do not know how to compare %s to %s.",
691                         this->ClassName(),
692                         obj->ClassName()
693                 ));
694                 return -999;
695         }
696 }
697