]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/mapping/AliMpNeighboursPadIterator.cxx
Mapping files of bending PCBs of station345
[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 // Included in AliRoot: 2003/05/02
8 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
9
10 #include <TVector2.h>
11
12 #include "AliMpNeighboursPadIterator.h"
13 #include "AliMpIntPair.h"
14 #include "AliMpSectorSegmentation.h"
15 #include "AliMpRow.h"
16 #include "AliMpConstants.h"
17
18 ClassImp(AliMpNeighboursPadIterator)
19
20 const UInt_t AliMpNeighboursPadIterator::fgkInvalidIndex = 9999; 
21                                                    //never so much neighbours...
22
23 //______________________________________________________________________________
24 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator()
25   : AliMpVPadIterator(),
26     fkSegmentation(0),
27     fCenterPad(AliMpPad::Invalid()),
28     fPads(),
29     fIndex(fgkInvalidIndex)
30 {
31 // default constructor, set the current position to "invalid"
32 }
33
34 //______________________________________________________________________________
35 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
36                                  const AliMpSectorSegmentation* segmentation,
37                                  const AliMpPad& centerPad,
38                                  Bool_t includeCenter)
39   : AliMpVPadIterator(),
40     fkSegmentation(segmentation),
41     fCenterPad(centerPad),
42     fIndex(fgkInvalidIndex)
43 {
44 // normal constructor, set *this to invalid position
45
46     FillPadsVector(includeCenter);
47 }
48
49 //______________________________________________________________________________
50 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
51                                  const AliMpNeighboursPadIterator& right)
52   : AliMpVPadIterator(right)
53 {
54 // copy constructor
55
56   *this = right;
57 }
58
59 //______________________________________________________________________________
60 AliMpNeighboursPadIterator::~AliMpNeighboursPadIterator()
61 {
62 // destructor
63
64 #ifdef WITH_ROOT
65   fPads.Delete();
66 #endif
67 }
68
69 // operators
70
71 //______________________________________________________________________________
72 AliMpNeighboursPadIterator& 
73 AliMpNeighboursPadIterator::operator = (const AliMpNeighboursPadIterator& right)
74 {
75 // assignement operator
76 // if the right hand iterator isn't of good type
77 // the current operator is invalidated
78
79   // check assignement to self
80   if (this == &right) return *this;
81
82   // base class assignement
83   AliMpVPadIterator::operator=(right);
84
85 #ifdef WITH_STL
86   fkSegmentation = right.fkSegmentation;
87   fCenterPad     = right.fCenterPad;
88   fPads          = right.fPads;
89   fIndex         = right.fIndex;
90 #endif
91 #ifdef WITH_ROOT
92   Fatal("operator=", "Not allowed assignment for TObjArray");
93 #endif
94
95   return *this;
96
97
98 //private methods
99
100 //______________________________________________________________________________
101 Bool_t AliMpNeighboursPadIterator::IsNeighbours(const AliMpPad& pad) const
102 {
103 // true if the pad located by <padIndice> is a neighbours of those
104 // located at <fCenterPad>
105
106     
107     TVector2 relPos  = pad.Position()   - fCenterPad.Position();
108     TVector2 bounds  = pad.Dimensions() + fCenterPad.Dimensions();
109     return (TMath::Abs(relPos.X())- bounds.X()<AliMpConstants::LengthTolerance()) && 
110            (TMath::Abs(relPos.Y())- bounds.Y()<AliMpConstants::LengthTolerance());
111
112 }
113
114 #ifdef WITH_STL
115 //______________________________________________________________________________
116 PadVector AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
117                                            const AliMpIntPair& direction) const
118 {
119 // Fill  a new vector with all pads which have common
120 // parts with the pad located at <fCenterPad>, in a given line
121 // starting from <from> and moving by <direction>
122
123     AliMpPad current = from;
124     PadVector ans;
125     Bool_t cont=kTRUE;
126     do {
127         if (IsNeighbours(current))
128             ans.push_back(current);
129         else
130             cont=kFALSE;
131         TVector2 nextPos = current.Position() + TVector2(
132           current.Dimensions().X()*(AliMpConstants::LengthStep()+1.)*direction.GetFirst(),
133           current.Dimensions().Y()*(AliMpConstants::LengthStep()+1.)*direction.GetSecond());
134         current = fkSegmentation->PadByPosition(nextPos);
135     } while (cont);
136     return ans;
137 }
138
139 //______________________________________________________________________________
140 void  AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal, 
141                                                  const PadVector& from) const
142 {
143 // Add pads from pad vector to the total set 
144 // only if they are not yet included
145
146     setTotal.insert(from.begin(),from.end());
147 }    
148
149 #endif
150 #ifdef WITH_ROOT
151 //______________________________________________________________________________
152 PadVector* AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
153                                            const AliMpIntPair& direction) const
154 {
155 // Fill  a new vector with all pads which have common
156 // parts with the pad located at <fCenterPad>, in a given line
157 // starting from <from> and moving by <direction>
158
159     AliMpPad current = from;
160     PadVector* ans = new PadVector();
161     Bool_t cont=kTRUE;
162     do {
163         if (IsNeighbours(current))
164             ans->Add(new AliMpPad(current));
165         else
166             cont=kFALSE;
167         TVector2 nextPos = current.Position() + TVector2(
168           current.Dimensions().X()*(AliMpConstants::LengthStep()+1.)*direction.GetFirst(),
169           current.Dimensions().Y()*(AliMpConstants::LengthStep()+1.)*direction.GetSecond());
170         current = fkSegmentation->PadByPosition(nextPos);
171     } while (cont);
172     return ans;
173 }
174
175 //______________________________________________________________________________
176 void  AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal, 
177                                                  PadVector* from) const
178 {
179 // Add pads from pad vector to the total set 
180 // only if they are not yet included and deletes the pad vector
181
182     for (Int_t i=0; i<from->GetEntriesFast(); i++) {
183       AliMpPad* candidate = (AliMpPad*)from->At(i);
184       
185       Bool_t isInSetTotal = false;
186       for (Int_t j=0; j<setTotal.GetEntriesFast(); j++) {
187          AliMpPad* pad = (AliMpPad*)setTotal.At(j);
188          
189          if (pad->GetIndices() == candidate->GetIndices()) {
190            isInSetTotal = true;
191            break;
192          }       
193       }
194       if (!isInSetTotal) 
195         setTotal.Add(candidate);
196       else
197         delete candidate;       
198     }
199     delete from;
200
201
202 #endif
203
204 //______________________________________________________________________________
205 void AliMpNeighboursPadIterator::FillPadsVector(Bool_t includeCenter)
206 {
207 // Fill the indices vector with all indices of pads which have common
208 // parts with the pad located at <fCenterPad>
209
210     if (!fkSegmentation || !fCenterPad.IsValid()) return;
211     
212     
213     AliMpPad from;
214     AliMpIntPair direction;
215 #ifdef WITH_STL
216     PadVector found;
217 #endif
218 #ifdef WITH_ROOT
219     PadVector* found;
220 #endif
221     
222     // repare a unique simple associative container
223     // --> no doublons, rapid insersion
224     PadSet setTotal;
225
226   /////////////  Left side
227   
228   ////////////////// up direction
229     
230     from = fkSegmentation->PadsLeft(fCenterPad).GetFirst();
231     direction = AliMpIntPair(0,1);
232     found = PadVectorLine(from,direction);
233     UpdateTotalSet(setTotal, found);
234
235   ////////////////// down direction
236
237     from = fkSegmentation->PadsDown(from).GetFirst(); // the Pad down is already added
238     direction = AliMpIntPair(0,-1);
239     found = PadVectorLine(from,direction);
240     UpdateTotalSet(setTotal, found);
241     
242   /////////////  Up side
243   
244   ////////////////// right direction
245
246     from = fkSegmentation->PadsUp(fCenterPad).GetFirst();
247     direction = AliMpIntPair(1,0);
248     found = PadVectorLine(from,direction);
249     UpdateTotalSet(setTotal, found);
250     
251   ////////////////// left direction
252
253     from = fkSegmentation->PadsLeft(from).GetFirst(); // the pad up is already added
254     direction = AliMpIntPair(-1,0);
255     found = PadVectorLine(from,direction);
256     UpdateTotalSet(setTotal, found);
257     
258   /////////////  Right side
259   
260   ////////////////// Up direction
261     
262     from = fkSegmentation->PadsRight(fCenterPad).GetFirst();
263     direction = AliMpIntPair(0,1);
264     found = PadVectorLine(from,direction);
265     UpdateTotalSet(setTotal, found);
266     
267   ////////////////// down direction
268
269     from = fkSegmentation->PadsDown(from).GetFirst(); // the pad right is already added
270     direction = AliMpIntPair(0,-1);
271     found = PadVectorLine(from,direction);
272     UpdateTotalSet(setTotal, found);
273     
274   /////////////  Down side
275   
276   ////////////////// Right direction
277
278     from = fkSegmentation->PadsDown(fCenterPad).GetFirst();
279     direction = AliMpIntPair(1,0);
280     found = PadVectorLine(from,direction);
281     UpdateTotalSet(setTotal, found);
282     
283   ////////////////// left direction
284     
285     from = fkSegmentation->PadsLeft(from).GetFirst(); // the pad down is already added
286     direction = AliMpIntPair(-1,0);
287     found = PadVectorLine(from,direction);
288     UpdateTotalSet(setTotal, found);
289
290     // fill the fIndices vector with the set (-->pass from a rapid insertion,
291     // to rapid and indexed access, for the rest of the job)
292
293 #ifdef WITH_STL
294     fPads.clear();
295     // include the center pad if requiered
296     if (includeCenter) fPads.push_back(fCenterPad);
297     //fPads.insert(fPads.end(),setTotal.begin(),setTotal.end());
298     
299     PadSetIterator it;
300     for (it = setTotal.begin(); it != setTotal.end(); it++)
301       fPads.push_back((*it));
302 #endif
303
304 #ifdef WITH_ROOT
305     fPads.Delete();
306     // include the center pad if requiered
307     if (includeCenter) fPads.Add(new AliMpPad(fCenterPad));
308
309     for (Int_t i = 0; i<setTotal.GetEntriesFast(); i++)
310       fPads.Add(setTotal.At(i));
311 #endif
312 }
313
314 //______________________________________________________________________________
315 Bool_t AliMpNeighboursPadIterator::IsValid() const
316 {
317 // Is the iterator in a valid position?
318     return (fkSegmentation!=0 && fIndex!=fgkInvalidIndex);
319
320
321 //public methods
322
323 //______________________________________________________________________________
324 void AliMpNeighboursPadIterator::First()
325 {
326 // Reset the iterator, so that it points to the first available
327 // pad in the sector
328
329 #ifdef WITH_STL
330     if ((fkSegmentation != 0) && (fPads.size() != 0)) 
331 #endif
332 #ifdef WITH_ROOT
333     if ((fkSegmentation != 0) && (fPads.GetEntriesFast() != 0)) 
334 #endif
335       fIndex=0; 
336     else 
337       fIndex=fgkInvalidIndex;
338
339 }
340
341 //______________________________________________________________________________
342 void AliMpNeighboursPadIterator::Next()
343 {
344 // pre-increment operator. Should be used by default for iterating over
345 // pads
346
347
348   if (!IsValid()) return;
349   
350 #ifdef WITH_STL
351   if (fIndex < fPads.size()-1) 
352 #endif
353 #ifdef WITH_ROOT
354   if (Int_t(fIndex) < fPads.GetEntriesFast()-1) 
355 #endif
356     fIndex++; 
357   else 
358     Invalidate();
359 }
360
361 //______________________________________________________________________________
362 Bool_t AliMpNeighboursPadIterator::IsDone() const
363 {
364 // 
365   return !IsValid();
366 }
367
368 //______________________________________________________________________________
369 AliMpPad AliMpNeighboursPadIterator::CurrentItem() const 
370 {
371 // dereferencement operator
372   if (!IsValid())
373     return AliMpPad::Invalid();
374   else
375 #ifdef WITH_STL
376     return fPads[fIndex];
377 #endif
378 #ifdef WITH_ROOT
379     return *((AliMpPad*)fPads[fIndex]);
380 #endif
381 }
382
383 //______________________________________________________________________________
384 void AliMpNeighboursPadIterator::Invalidate()
385 {
386 // Let the iterator points to the invalid position
387     fIndex=fgkInvalidIndex;
388 }
389