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