- Disentangle masks effect from trigger chamber efficiency estimation.
[u/mrichter/AliRoot.git] / MUON / AliMUONNode.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 // $Id$
17
18 /// \class AliMUONNode
19 /// 
20 /// A node of a segment tree
21 ///
22 /// For the details of the meaning of cardinality and potent data
23 /// members, please see Diane L. Souvaine and Iliana Bjorling-Sachs,
24 /// Proceedings of the IEEE, Vol. 80, No. 9, September 1992, p. 1449
25 ///
26 /// 
27 /// \author Laurent Aphecetche, Subatech
28
29 #include "AliMUONNode.h"
30
31 #include "AliLog.h"
32 #include "AliMUONSegment.h"
33 #include "Riostream.h"
34 #include "TMath.h"
35 #include "TObjArray.h"
36 #include "TString.h"
37
38 ///\cond CLASSIMP
39 ClassImp(AliMUONNode)
40 ///\endcond
41
42 //_____________________________________________________________________________
43 AliMUONNode::AliMUONNode(Double_t a, Double_t b, Double_t midpoint)
44 : fLeftNode(0x0), fRightNode(0x0), fMin(a), fMax(b), fMidPoint(midpoint), fC(0), fP(0)
45 {
46   /// ctor
47 }
48
49 //_____________________________________________________________________________
50 AliMUONNode::~AliMUONNode()
51 {
52   /// dtor
53   delete fLeftNode;
54   delete fRightNode;
55 }
56
57 //_____________________________________________________________________________
58 void 
59 AliMUONNode::Print(const char* opt) const
60 {
61   /// Printout
62   cout << opt << Form("[%7.2f,%7.2f]",fMin,fMax);
63   if ( !TMath::IsNaN(fMidPoint) ) cout << Form(" (%7.2f)",fMidPoint);
64   cout << endl;
65   
66   TString sopt(opt);
67   sopt += "   ";
68   
69   if ( fLeftNode ) 
70   {
71     fLeftNode->Print(sopt.Data());
72   }
73   if ( fRightNode ) 
74   {
75     fRightNode->Print(sopt.Data());
76   }
77 }
78
79 //_____________________________________________________________________________
80 void 
81 AliMUONNode::Contribution(Double_t b, Double_t e, TObjArray& stack)
82 {
83   /// Contribution of an edge (b,e) to the final contour
84   if ( fMax < fMin ) 
85   {
86     AliError(Form("fMax(%10.5f) < fMin(%10.5f",fMax,fMin));
87   }
88   
89   if ( fC == 0 ) 
90   {
91     if ( IsFullyContained(b,e) && fP == 0 ) 
92     {
93       AliMUONSegment* back = static_cast<AliMUONSegment*>(stack.Last());
94
95       if ( back && AliMUONSegment::AreEqual(back->EndY(),fMin) )
96       {
97         // merge to existing segment
98         Double_t y(back->StartY());
99         back->Set(0.0,y,0.0,fMax);
100       }
101       else
102       {
103         // add a new segment
104         stack.Add(new AliMUONSegment(0.0,fMin,0.0,fMax));
105       }
106     }
107     else
108     {
109       if ( b < fMidPoint ) 
110       {
111         fLeftNode->Contribution(b,e,stack);
112       }
113       if ( fMidPoint < e ) 
114       {
115         fRightNode->Contribution(b,e,stack);
116       }
117     }
118   }
119 }
120
121 //_____________________________________________________________________________
122 Bool_t 
123 AliMUONNode::IsFullyContained(Double_t b, Double_t e) const
124 {
125   /// Whether this node's interval is fully contained into [b,e]
126   
127   return ( ( b < fMin || AliMUONSegment::AreEqual(b,fMin) ) && ( fMax < e || AliMUONSegment::AreEqual(e,fMax)) );
128 }
129
130 //_____________________________________________________________________________
131 void 
132 AliMUONNode::InsertInterval(Double_t b, Double_t e, TObjArray& stack)
133 {
134   /// Insert an interval
135   if ( IsFullyContained(b,e) ) 
136   {
137     C(1);
138   }
139   else
140   {
141     if ( b < fMidPoint ) 
142     {
143       fLeftNode->InsertInterval(b,e,stack);
144     }
145     if ( fMidPoint <  e ) 
146     {
147       fRightNode->InsertInterval(b,e,stack);
148     }
149   }
150   Update();
151 }
152
153 //_____________________________________________________________________________
154 void 
155 AliMUONNode::DeleteInterval(Double_t b, Double_t e, TObjArray& stack)
156 {
157   /// Delete an interval
158   if ( IsFullyContained(b,e) ) 
159   {
160     C(-1);
161   }
162   else
163   {
164     if ( fC > 0 ) Demote();
165     if ( b < fMidPoint )
166     {
167       fLeftNode->DeleteInterval(b,e,stack);
168     }
169     
170     if ( fMidPoint < e ) 
171     {
172       fRightNode->DeleteInterval(b,e,stack);
173     }
174   }
175   Update();
176 }
177
178 //_____________________________________________________________________________
179 void 
180 AliMUONNode::Update()
181 {
182   /// Update internal values
183   if ( !fLeftNode ) 
184   {
185     fP = 0;
186   }
187   else
188   {
189     if (fLeftNode->C() > 0 && fRightNode->C() > 0 )
190     {
191       Promote();
192     }
193     if (fLeftNode->C()==0 && fRightNode->C()==0 && fLeftNode->P()==0 && fRightNode->P()==0 ) 
194     {
195       fP = 0;
196     }
197     else
198     {
199       fP = 1;
200     }
201   }
202 }
203
204 //_____________________________________________________________________________
205 void 
206 AliMUONNode::Promote()
207 {
208   /// Promote node
209   fLeftNode->C(-1);
210   fRightNode->C(-1);
211   C(+1);
212 }
213
214 //_____________________________________________________________________________
215 void 
216 AliMUONNode::Demote()
217 {
218   /// Demote node
219   fLeftNode->C(+1);
220   fRightNode->C(+1);
221   C(-1);
222   fP = 1;
223 }
224