Adding CreateIterator(void) and GetNeighbours() pure virtual methods,
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpVSegmentation.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 // $MpId: AliMpVSegmentation.cxx,v 1.5 2006/05/24 13:58:29 ivana Exp $
18 // Category: basic
19 //
20 // Class AliMpVSegmentation
21 // ------------------------
22 // The abstract base class for the segmentation.
23 // Provides methods related to pads:
24 // conversion between pad indices, pad location, pad position;
25 // finding pad neighbour.
26 //
27 // Included in AliRoot: 2003/05/02
28 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
29 //         Laurent Aphecetche, SUBATECH
30
31 #include "AliMpVSegmentation.h"
32 #include "AliMpArea.h"
33 #include "AliMpConstants.h"
34
35 #include "AliLog.h"
36
37 #include "TVector2.h"
38 #include "TObjArray.h"
39
40 /// \cond CLASSIMP
41 ClassImp(AliMpVSegmentation)
42 /// \endcond
43
44 //_____________________________________________________________________________
45 AliMpVSegmentation::AliMpVSegmentation() 
46   : TObject()
47 {
48 /// Default constructor
49 }
50
51 //_____________________________________________________________________________
52 AliMpVSegmentation::~AliMpVSegmentation() 
53 {
54 /// Destructor 
55 }
56
57 //_____________________________________________________________________________
58 AliMpVPadIterator* 
59 AliMpVSegmentation::CreateIterator() const
60 {
61   /// This is a default implementation, that *might* be used
62   /// by child classes. But if they come up with better options,
63   /// let it be ;-)
64   
65   AliMpArea area(TVector2(0.0,0.0),Dimensions());
66   return CreateIterator(area);
67 }
68
69 //_____________________________________________________________________________
70 AliMpPadPair AliMpVSegmentation::FindPads(const TVector2& position1, 
71                                           const TVector2& position2) const
72 {
73 /// Return a pair of pads with specified position.
74 /// If both pads are identical, the second pad in pair is set to invalid.
75
76   AliMpPad pad1 = PadByPosition(position1, false);
77   AliMpPad pad2 = PadByPosition(position2, false);
78                                      
79   if (pad1 == pad2) pad2 = AliMpPad::Invalid();                              
80
81   return AliMpPadPair(pad1, pad2);
82 }  
83
84 //_____________________________________________________________________________
85 Int_t 
86 AliMpVSegmentation::GetNeighbours(const AliMpPad& pad, 
87                                   TObjArray& neighbours,
88                                   Bool_t includeSelf,
89                                   Bool_t includeVoid) const
90 {
91   /// Returns the list of neighbours of pad
92   static TVector2* testPositions(0x0);
93   static const Int_t kNofTestPositions(11);
94   static const Double_t kEpsilon(AliMpConstants::LengthTolerance()*2.0);
95   static Int_t centerIndex(-1);
96   
97   // testPositions are the positions (L,T,R,B) relative to pad's center (O)
98   // were we'll try to get a neighbouring pad, by getting a little
99   // bit outside the pad itself.
100   // Note that it's not symmetric as we assume that pad density
101   // can always decrease when going from left to right.
102   //
103   // L-T-T-R
104   // |     |
105   // L     |
106   // |  O  R
107   // L     |
108   // |     |
109   // L--B--R
110   //
111   // The order in which we actually test the positions has some importance,
112   // i.e. when using this information to compute status map later on. Here's
113   // the sequence :
114   //
115   // 4-5-6- 7
116   // |      |
117   // 3      |
118   // |  0   8
119   // 2      |
120   // |      |
121   // 1--10--9
122   
123   neighbours.Delete();
124   neighbours.SetOwner(kTRUE);
125   
126   if (!pad.IsValid()) return 0;
127   
128   if (!testPositions)
129   {
130     testPositions = new TVector2[kNofTestPositions];
131     Int_t n(0); 
132     // starting center
133     centerIndex = 0;
134     testPositions[n++] = TVector2(0,0); // O (pad center)
135     // then left column (L), starting from bottom
136     testPositions[n++] = TVector2(-1,-1);
137     testPositions[n++] = TVector2(-1,-1/3.0);
138     testPositions[n++] = TVector2(-1,1/3.0);
139     testPositions[n++] = TVector2(-1,1);
140     // top (T), starting from left
141     testPositions[n++] = TVector2(-1/3.0,1);
142     testPositions[n++] = TVector2(1/3.0,1);
143     // right column (R), starting from top
144     testPositions[n++] = TVector2(1,1);
145     testPositions[n++] = TVector2(1,0);
146     testPositions[n++] = TVector2(1,-1);
147     // bottom (B)
148     testPositions[n++] = TVector2(0,-1);
149     // pad center
150     if ( n != kNofTestPositions ) {
151       AliError("Test on number of test positions failed.");
152     }  
153   }
154   
155   Int_t n(0);
156   
157   AliMpPad previous(AliMpPad::Invalid());
158   
159   for ( Int_t i = 0; i < kNofTestPositions; ++i ) 
160   {
161     if ( i == centerIndex && !includeSelf )
162     {
163       if ( includeVoid ) 
164       {
165         previous = AliMpPad::Invalid();
166         neighbours.Add(new AliMpPad(previous));
167         ++n;
168       }
169       continue;
170     }
171     
172     TVector2 shift = testPositions[i];
173     TVector2 pos = pad.Position();
174     pos += TVector2((pad.Dimensions().X()+kEpsilon)*shift.X(),
175                     (pad.Dimensions().Y()+kEpsilon)*shift.Y());
176
177     
178     AliMpPad p = PadByPosition(pos,kFALSE);
179     
180     if ( !p.IsValid() && !includeVoid ) continue;
181     
182     if ( p != previous || !previous.IsValid() ) 
183     {
184       previous = p;
185       neighbours.Add(new AliMpPad(p));
186       ++n;
187     }
188   }
189   return n;
190 }
191
192 //
193 // public methods
194 //
195
196 //_____________________________________________________________________________
197 AliMpPadPair AliMpVSegmentation::PadsUp(const AliMpPad& pad) const
198 {
199 /// Return a pair of pads neighbouring up to the specified pad.
200 /// If there is only one neighbouring pad,
201 /// the second pad in pair is invalid.
202
203   TVector2 position1 
204     = pad.Position()+ TVector2((-1.)*AliMpConstants::LengthStep(), 
205                                pad.Dimensions().Y()+ AliMpConstants::LengthStep());
206   TVector2 position2 
207     = pad.Position()+ TVector2(AliMpConstants::LengthStep(), 
208                                pad.Dimensions().Y()+ AliMpConstants::LengthStep());
209                                
210   return FindPads(position1, position2);
211 }
212
213 //_____________________________________________________________________________
214 AliMpPadPair AliMpVSegmentation::PadsDown(const AliMpPad& pad) const
215 {
216 /// Return a pair of pads neighbouring down to the specified pad.
217 /// If there is only one neighbouring pad,
218 /// the second pad in pair is invalid.
219
220   TVector2 position1 
221     = pad.Position()- TVector2(AliMpConstants::LengthStep(), 
222                                pad.Dimensions().Y()+ AliMpConstants::LengthStep());
223
224   TVector2 position2
225     = pad.Position()- TVector2((-1.)*AliMpConstants::LengthStep(), 
226                                pad.Dimensions().Y()+ AliMpConstants::LengthStep());
227                                      
228   return FindPads(position1, position2);
229 }
230
231 //_____________________________________________________________________________
232 AliMpPadPair AliMpVSegmentation::PadsLeft(const AliMpPad& pad) const
233 {
234 /// Return a pair of pads neighbouring left to the specified pad.
235 /// If there is only one neighbouring pad,
236 /// the second in pair is invalid.
237
238   TVector2 position1 
239     = pad.Position() - TVector2(pad.Dimensions().X() + AliMpConstants::LengthStep(),
240                                 AliMpConstants::LengthStep()); 
241   TVector2 position2
242     = pad.Position() - TVector2(pad.Dimensions().X() + AliMpConstants::LengthStep(),
243                                 (-1.)*AliMpConstants::LengthStep()); 
244
245   return FindPads(position1, position2);
246 }
247
248 //_____________________________________________________________________________
249 AliMpPadPair AliMpVSegmentation::PadsRight(const AliMpPad& pad) const
250 {
251 /// Return a pair of pads neighbouring right to the specified pad.
252 /// If there is only one neighbouring pad,
253 /// the second in pair is invalid.
254
255   TVector2 position1 
256     = pad.Position() + TVector2(pad.Dimensions().X() + AliMpConstants::LengthStep(),
257                                 (-1.)*AliMpConstants::LengthStep()); 
258   TVector2 position2
259     = pad.Position() + TVector2(pad.Dimensions().X() + AliMpConstants::LengthStep(),
260                                 AliMpConstants::LengthStep()); 
261                                      
262   return FindPads(position1, position2);
263 }
264