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