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