]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/mapping/AliMpNeighboursPadIterator.cxx
Code for MUON Station1 (I.Hrivnacova)
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpNeighboursPadIterator.cxx
1 // $Id$
2 // Category: sector
3 //
4 // Class AliMpNeighboursPadIterator
5 // --------------------------------
6 // Class, which defines an iterator over the pads surrounding a given pad
7 //
8 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
9
10 #include <set>
11
12 #include <TVector2.h>
13
14 #include "AliMpNeighboursPadIterator.h"
15 #include "AliMpIntPair.h"
16 #include "AliMpSectorSegmentation.h"
17 #include "AliMpRow.h"
18 #include "AliMpConstants.h"
19
20 ClassImp(AliMpNeighboursPadIterator)
21
22 const UInt_t AliMpNeighboursPadIterator::fgkInvalidIndex = 9999; 
23                                                    //never so much neighbours...
24
25 //______________________________________________________________________________
26 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator()
27   : AliMpVPadIterator(),
28     fkSegmentation(0),
29     fCenterPad(AliMpPad::Invalid()),
30     fPads(),
31     fIndex(fgkInvalidIndex)
32 {
33 // default constructor, set the current position to "invalid"
34 }
35
36 //______________________________________________________________________________
37 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
38                                  const AliMpSectorSegmentation* segmentation,
39                                  const AliMpPad& centerPad,
40                                  Bool_t includeCenter)
41   : AliMpVPadIterator(),
42     fkSegmentation(segmentation),
43     fCenterPad(centerPad),
44     fIndex(fgkInvalidIndex)
45 {
46 // normal constructor, set *this to invalid position
47
48     FillPadsVector(includeCenter);
49 }
50
51 //______________________________________________________________________________
52 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
53                                  const AliMpNeighboursPadIterator& right)
54   : AliMpVPadIterator(right)
55 {
56 // copy constructor
57
58   *this = right;
59 }
60
61 //______________________________________________________________________________
62 AliMpNeighboursPadIterator::~AliMpNeighboursPadIterator()
63 {
64 // destructor
65 }
66
67 // operators
68
69 //______________________________________________________________________________
70 AliMpNeighboursPadIterator& 
71 AliMpNeighboursPadIterator::operator = (const AliMpNeighboursPadIterator& right)
72 {
73 // assignement operator
74 // if the right hand iterator isn't of good type
75 // the current operator is invalidated
76
77   // check assignement to self
78   if (this == &right) return *this;
79
80   // base class assignement
81   AliMpVPadIterator::operator=(right);
82
83   fkSegmentation = right.fkSegmentation;
84   fCenterPad     = right.fCenterPad;
85   fPads          = right.fPads;
86   fIndex         = right.fIndex;
87     
88
89   return *this;
90
91
92 //private methods
93
94 //______________________________________________________________________________
95 Bool_t AliMpNeighboursPadIterator::IsNeighbours(const AliMpPad& pad) const
96 {
97 // true if the pad located by <padIndice> is a neighbours of those
98 // located at <fCenterPad>
99
100     
101     TVector2 relPos  = pad.Position()   - fCenterPad.Position();
102     TVector2 bounds  = pad.Dimensions() + fCenterPad.Dimensions();
103     return (TMath::Abs(relPos.X())- bounds.X()<AliMpConstants::LengthTolerance()) && 
104            (TMath::Abs(relPos.Y())- bounds.Y()<AliMpConstants::LengthTolerance());
105
106 }
107
108 //______________________________________________________________________________
109 PadVector AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
110                                            const AliMpIntPair& direction) const
111 {
112 // Fill  a new vector with all pads which have common
113 // parts with the pad located at <fCenterPad>, in a given line
114 // starting from <from> and moving by <direction>
115
116     AliMpPad current = from;
117     PadVector ans;
118     Bool_t cont=kTRUE;
119     do {
120         if (IsNeighbours(current))
121             ans.push_back(current);
122         else
123             cont=kFALSE;
124         TVector2 nextPos = current.Position() + TVector2(
125           current.Dimensions().X()*(AliMpConstants::LengthStep()+1.)*direction.GetFirst(),
126           current.Dimensions().Y()*(AliMpConstants::LengthStep()+1.)*direction.GetSecond());
127         current = fkSegmentation->PadByPosition(nextPos);
128     } while (cont);
129     return ans;
130 }
131
132 //______________________________________________________________________________
133 void AliMpNeighboursPadIterator::FillPadsVector(Bool_t includeCenter)
134 {
135 // Fill the indices vector with all indices of pads which have common
136 // parts with the pad located at <fCenterPad>
137
138     if (!fkSegmentation || !fCenterPad.IsValid()) return;
139     
140     
141     AliMpPad from;
142     AliMpIntPair direction;
143     PadVector found;
144     
145     // repare a unique simple associative container
146     // --> no doublons, rapid insersion
147     PadSet setTotal;
148
149   /////////////  Left side
150   
151   ////////////////// up direction
152     
153     from = fkSegmentation->PadsLeft(fCenterPad).GetFirst();
154     direction = AliMpIntPair(0,1);
155     found = PadVectorLine(from,direction);
156     setTotal.insert(found.begin(),found.end());
157
158
159   ////////////////// down direction
160
161     from = fkSegmentation->PadsDown(from).GetFirst(); // the Pad down is already added
162     direction = AliMpIntPair(0,-1);
163     found = PadVectorLine(from,direction);
164     setTotal.insert(found.begin(),found.end());
165     
166   /////////////  Up side
167   
168   ////////////////// right direction
169
170     from = fkSegmentation->PadsUp(fCenterPad).GetFirst();
171     direction = AliMpIntPair(1,0);
172     found = PadVectorLine(from,direction);
173     setTotal.insert(found.begin(),found.end());
174     
175   ////////////////// left direction
176
177     from = fkSegmentation->PadsLeft(from).GetFirst(); // the pad up is already added
178     direction = AliMpIntPair(-1,0);
179     found = PadVectorLine(from,direction);
180     setTotal.insert(found.begin(),found.end());
181     
182   /////////////  Right side
183   
184   ////////////////// Up direction
185     
186     from = fkSegmentation->PadsRight(fCenterPad).GetFirst();
187     direction = AliMpIntPair(0,1);
188     found = PadVectorLine(from,direction);
189     setTotal.insert(found.begin(),found.end());
190     
191   ////////////////// down direction
192
193     from = fkSegmentation->PadsDown(from).GetFirst(); // the pad right is already added
194     direction = AliMpIntPair(0,-1);
195     found = PadVectorLine(from,direction);
196     setTotal.insert(found.begin(),found.end());
197     
198   /////////////  Down side
199   
200   ////////////////// Right direction
201
202     from = fkSegmentation->PadsDown(fCenterPad).GetFirst();
203     direction = AliMpIntPair(1,0);
204     found = PadVectorLine(from,direction);
205     setTotal.insert(found.begin(),found.end());
206     
207   ////////////////// left direction
208     
209     from = fkSegmentation->PadsLeft(from).GetFirst(); // the pad down is already added
210     direction = AliMpIntPair(-1,0);
211     found = PadVectorLine(from,direction);
212     setTotal.insert(found.begin(),found.end());
213     
214
215     // fill the fIndices vector with the set (-->pass from a rapid insertion,
216     // to rapid and indexed access, for the rest of the job)
217
218     fPads.clear();
219     // include the center pad if requiered
220     if (includeCenter) fPads.push_back(fCenterPad);
221     //fPads.insert(fPads.end(),setTotal.begin(),setTotal.end());
222     
223     PadSetIterator it;
224     for (it = setTotal.begin(); it != setTotal.end(); it++)
225       fPads.push_back((*it));
226 }
227
228 //______________________________________________________________________________
229 Bool_t AliMpNeighboursPadIterator::IsValid() const
230 {
231 // Is the iterator in a valid position?
232     return (fkSegmentation!=0 && fIndex!=fgkInvalidIndex);
233
234
235 //public methods
236
237 //______________________________________________________________________________
238 void AliMpNeighboursPadIterator::First()
239 {
240 // Reset the iterator, so that it points to the first available
241 // pad in the sector
242
243     if ((fkSegmentation != 0) && (fPads.size() != 0)) 
244       fIndex=0; 
245     else 
246       fIndex=fgkInvalidIndex;
247
248 }
249
250 //______________________________________________________________________________
251 void AliMpNeighboursPadIterator::Next()
252 {
253 // pre-increment operator. Should be used by default for iterating over
254 // pads
255
256
257   if (!IsValid()) return;
258   
259   if (fIndex < fPads.size()-1) 
260     fIndex++; 
261   else 
262     Invalidate();
263 }
264
265 //______________________________________________________________________________
266 Bool_t AliMpNeighboursPadIterator::IsDone() const
267 {
268 // 
269   return !IsValid();
270 }
271
272 //______________________________________________________________________________
273 AliMpPad AliMpNeighboursPadIterator::CurrentItem() const 
274 {
275 // dereferencement operator
276   if (!IsValid())
277     return AliMpPad::Invalid();
278   else
279     return fPads[fIndex];
280 }
281
282 //______________________________________________________________________________
283 void AliMpNeighboursPadIterator::Invalidate()
284 {
285 // Let the iterator points to the invalid position
286     fIndex=fgkInvalidIndex;
287 }
288