]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONNode.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[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 using std::cout;
39 using std::endl;
40 ///\cond CLASSIMP
41 ClassImp(AliMUONNode)
42 ///\endcond
43
44 //_____________________________________________________________________________
45 AliMUONNode::AliMUONNode(Double_t a, Double_t b, Double_t midpoint)
46 : fLeftNode(0x0), fRightNode(0x0), fMin(a), fMax(b), fMidPoint(midpoint), fC(0), fP(0)
47 {
48   /// ctor
49 }
50
51 //_____________________________________________________________________________
52 AliMUONNode::~AliMUONNode()
53 {
54   /// dtor
55   delete fLeftNode;
56   delete fRightNode;
57 }
58
59 //_____________________________________________________________________________
60 void 
61 AliMUONNode::Print(const char* opt) const
62 {
63   /// Printout
64   cout << opt << Form("[%7.2f,%7.2f]",fMin,fMax);
65   if ( !TMath::IsNaN(fMidPoint) ) cout << Form(" (%7.2f)",fMidPoint);
66   cout << endl;
67   
68   TString sopt(opt);
69   sopt += "   ";
70   
71   if ( fLeftNode ) 
72   {
73     fLeftNode->Print(sopt.Data());
74   }
75   if ( fRightNode ) 
76   {
77     fRightNode->Print(sopt.Data());
78   }
79 }
80
81 //_____________________________________________________________________________
82 void 
83 AliMUONNode::Contribution(Double_t b, Double_t e, TObjArray& stack)
84 {
85   /// Contribution of an edge (b,e) to the final contour
86   if ( fMax < fMin ) 
87   {
88     AliError(Form("fMax(%10.5f) < fMin(%10.5f",fMax,fMin));
89   }
90   
91   if ( fC == 0 ) 
92   {
93     if ( IsFullyContained(b,e) && fP == 0 ) 
94     {
95       AliMUONSegment* back = static_cast<AliMUONSegment*>(stack.Last());
96
97       if ( back && AliMUONSegment::AreEqual(back->EndY(),fMin) )
98       {
99         // merge to existing segment
100         Double_t y(back->StartY());
101         back->Set(0.0,y,0.0,fMax);
102       }
103       else
104       {
105         // add a new segment
106         stack.Add(new AliMUONSegment(0.0,fMin,0.0,fMax));
107       }
108     }
109     else
110     {
111       if ( b < fMidPoint ) 
112       {
113         fLeftNode->Contribution(b,e,stack);
114       }
115       if ( fMidPoint < e ) 
116       {
117         fRightNode->Contribution(b,e,stack);
118       }
119     }
120   }
121 }
122
123 //_____________________________________________________________________________
124 Bool_t 
125 AliMUONNode::IsFullyContained(Double_t b, Double_t e) const
126 {
127   /// Whether this node's interval is fully contained into [b,e]
128   
129   return ( ( b < fMin || AliMUONSegment::AreEqual(b,fMin) ) && ( fMax < e || AliMUONSegment::AreEqual(e,fMax)) );
130 }
131
132 //_____________________________________________________________________________
133 void 
134 AliMUONNode::InsertInterval(Double_t b, Double_t e, TObjArray& stack)
135 {
136   /// Insert an interval
137   if ( IsFullyContained(b,e) ) 
138   {
139     C(1);
140   }
141   else
142   {
143     if ( b < fMidPoint ) 
144     {
145       fLeftNode->InsertInterval(b,e,stack);
146     }
147     if ( fMidPoint <  e ) 
148     {
149       fRightNode->InsertInterval(b,e,stack);
150     }
151   }
152   Update();
153 }
154
155 //_____________________________________________________________________________
156 void 
157 AliMUONNode::DeleteInterval(Double_t b, Double_t e, TObjArray& stack)
158 {
159   /// Delete an interval
160   if ( IsFullyContained(b,e) ) 
161   {
162     C(-1);
163   }
164   else
165   {
166     if ( fC > 0 ) Demote();
167     if ( b < fMidPoint )
168     {
169       fLeftNode->DeleteInterval(b,e,stack);
170     }
171     
172     if ( fMidPoint < e ) 
173     {
174       fRightNode->DeleteInterval(b,e,stack);
175     }
176   }
177   Update();
178 }
179
180 //_____________________________________________________________________________
181 void 
182 AliMUONNode::Update()
183 {
184   /// Update internal values
185   if ( !fLeftNode ) 
186   {
187     fP = 0;
188   }
189   else
190   {
191     if (fLeftNode->C() > 0 && fRightNode->C() > 0 )
192     {
193       Promote();
194     }
195     if (fLeftNode->C()==0 && fRightNode->C()==0 && fLeftNode->P()==0 && fRightNode->P()==0 ) 
196     {
197       fP = 0;
198     }
199     else
200     {
201       fP = 1;
202     }
203   }
204 }
205
206 //_____________________________________________________________________________
207 void 
208 AliMUONNode::Promote()
209 {
210   /// Promote node
211   fLeftNode->C(-1);
212   fRightNode->C(-1);
213   C(+1);
214 }
215
216 //_____________________________________________________________________________
217 void 
218 AliMUONNode::Demote()
219 {
220   /// Demote node
221   fLeftNode->C(+1);
222   fRightNode->C(+1);
223   C(-1);
224   fP = 1;
225 }
226