1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 // $MpId: AliMpNeighboursPadIterator.cxx,v 1.12 2006/05/24 13:58:46 ivana Exp $
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 //-----------------------------------------------------------------------------
28 #include "AliMpNeighboursPadIterator.h"
29 #include "AliMpIntPair.h"
30 #include "AliMpVSegmentation.h"
32 #include "AliMpConstants.h"
39 ClassImp(AliMpNeighboursPadIterator)
42 const UInt_t AliMpNeighboursPadIterator::fgkInvalidIndex = 9999;
43 //never so much neighbours...
45 //______________________________________________________________________________
46 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator()
47 : AliMpVPadIterator(),
49 fCenterPad(AliMpPad::Invalid()),
51 fIndex(fgkInvalidIndex)
53 /// Default constructor, set the current position to "invalid"
56 //______________________________________________________________________________
57 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
58 const AliMpVSegmentation* segmentation,
59 const AliMpPad& centerPad,
61 : AliMpVPadIterator(),
62 fkSegmentation(segmentation),
63 fCenterPad(centerPad),
65 fIndex(fgkInvalidIndex)
67 /// Standard constructor, set *this to invalid position
69 FillPadsVector(includeCenter);
72 //______________________________________________________________________________
73 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
74 const AliMpNeighboursPadIterator& right)
75 : AliMpVPadIterator(right),
77 fCenterPad(AliMpPad::Invalid()),
79 fIndex(fgkInvalidIndex)
86 //______________________________________________________________________________
87 AliMpNeighboursPadIterator::~AliMpNeighboursPadIterator()
98 //______________________________________________________________________________
99 AliMpNeighboursPadIterator&
100 AliMpNeighboursPadIterator::operator = (const AliMpNeighboursPadIterator& right)
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.
107 // check assignment to self
108 if (this == &right) return *this;
110 // base class assignment
111 AliMpVPadIterator::operator=(right);
114 fkSegmentation = right.fkSegmentation;
115 fCenterPad = right.fCenterPad;
117 fIndex = right.fIndex;
120 AliFatal("Not allowed assignment for TObjArray");
130 //______________________________________________________________________________
131 Bool_t AliMpNeighboursPadIterator::IsNeighbour(const AliMpPad& pad) const
133 /// Return true if the pad located by \a pad is a neighbour of those
134 /// located at a\ fCenterPad
136 if ( !pad.IsValid() ) return kFALSE;
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());
146 //______________________________________________________________________________
147 AliMpNeighboursPadIterator::PadVector
148 AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
149 const AliMpIntPair& direction) const
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
155 AliMpPad current = from;
159 if (IsNeighbour(current))
160 ans.push_back(current);
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);
171 //______________________________________________________________________________
172 void AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal,
173 const PadVector& from) const
175 /// Add pads from pad vector to the total set
176 /// only if they are not yet included
178 setTotal.insert(from.begin(),from.end());
183 //______________________________________________________________________________
184 AliMpNeighboursPadIterator::PadVector*
185 AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
186 const AliMpIntPair& direction) const
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
192 AliMpPad current = from;
193 PadVector* ans = new PadVector();
196 if (IsNeighbour(current))
197 ans->Add(new AliMpPad(current));
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);
208 //______________________________________________________________________________
209 void AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal,
210 PadVector* from) const
212 /// Add pads from pad vector to the total set
213 /// only if they are not yet included and deletes the pad vector
215 for (Int_t i=0; i<from->GetEntriesFast(); i++) {
216 AliMpPad* candidate = (AliMpPad*)from->At(i);
218 Bool_t isInSetTotal = false;
219 for (Int_t j=0; j<setTotal.GetEntriesFast(); j++) {
220 AliMpPad* pad = (AliMpPad*)setTotal.At(j);
222 if (pad->GetIndices() == candidate->GetIndices()) {
228 setTotal.Add(candidate);
237 //______________________________________________________________________________
238 void AliMpNeighboursPadIterator::FillPadsVector(Bool_t includeCenter)
240 /// Fill the indices vector with all indices of pads which have common
241 /// parts with the pad located at \a fCenterPad
243 if (!fkSegmentation || !fCenterPad.IsValid()) return;
247 AliMpIntPair direction;
255 // repare a unique simple associative container
256 // --> no doublons, rapid insersion
259 ///////////// Left side
261 ////////////////// up direction
263 from = fkSegmentation->PadsLeft(fCenterPad).GetFirst();
264 direction = AliMpIntPair(0,1);
265 found = PadVectorLine(from,direction);
266 UpdateTotalSet(setTotal, found);
268 ////////////////// down direction
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);
275 ///////////// Up side
277 ////////////////// right direction
279 from = fkSegmentation->PadsUp(fCenterPad).GetFirst();
280 direction = AliMpIntPair(1,0);
281 found = PadVectorLine(from,direction);
282 UpdateTotalSet(setTotal, found);
284 ////////////////// left direction
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);
291 ///////////// Right side
293 ////////////////// Up direction
295 from = fkSegmentation->PadsRight(fCenterPad).GetFirst();
296 direction = AliMpIntPair(0,1);
297 found = PadVectorLine(from,direction);
298 UpdateTotalSet(setTotal, found);
300 ////////////////// down direction
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);
307 ///////////// Down side
309 ////////////////// Right direction
311 from = fkSegmentation->PadsDown(fCenterPad).GetFirst();
312 direction = AliMpIntPair(1,0);
313 found = PadVectorLine(from,direction);
314 UpdateTotalSet(setTotal, found);
316 ////////////////// left direction
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);
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)
328 // include the center pad if requiered
329 if (includeCenter) fPads.push_back(fCenterPad);
330 //fPads.insert(fPads.end(),setTotal.begin(),setTotal.end());
333 for (it = setTotal.begin(); it != setTotal.end(); it++)
334 fPads.push_back((*it));
339 // include the center pad if requiered
340 if (includeCenter) fPads.Add(new AliMpPad(fCenterPad));
342 for (Int_t i = 0; i<setTotal.GetEntriesFast(); i++)
343 fPads.Add(setTotal.At(i));
347 //______________________________________________________________________________
348 Bool_t AliMpNeighboursPadIterator::IsValid() const
350 /// Is the iterator in a valid position?
352 return (fkSegmentation!=0 && fIndex!=fgkInvalidIndex);
357 //______________________________________________________________________________
358 void AliMpNeighboursPadIterator::First()
360 /// Reset the iterator, so that it points to the first available
361 /// pad in the sector
364 if ((fkSegmentation != 0) && (fPads.size() != 0))
367 if ((fkSegmentation != 0) && (fPads.GetEntriesFast() != 0))
371 fIndex=fgkInvalidIndex;
375 //______________________________________________________________________________
376 void AliMpNeighboursPadIterator::Next()
378 /// Pre-increment operator. Should be used by default for iterating over
382 if (!IsValid()) return;
385 if (fIndex < fPads.size()-1)
388 if (Int_t(fIndex) < fPads.GetEntriesFast()-1)
395 //______________________________________________________________________________
396 Bool_t AliMpNeighboursPadIterator::IsDone() const
398 /// Is the iterator in the end?
403 //______________________________________________________________________________
404 AliMpPad AliMpNeighboursPadIterator::CurrentItem() const
406 /// Dereferencement function
409 return AliMpPad::Invalid();
412 return fPads[fIndex];
415 return *((AliMpPad*)fPads[fIndex]);
419 //______________________________________________________________________________
420 void AliMpNeighboursPadIterator::Invalidate()
422 /// Let the iterator point to the invalid position
424 fIndex=fgkInvalidIndex;