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