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 // 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
26 #include "AliMpNeighboursPadIterator.h"
27 #include "AliMpIntPair.h"
28 #include "AliMpVSegmentation.h"
30 #include "AliMpConstants.h"
37 ClassImp(AliMpNeighboursPadIterator)
40 const UInt_t AliMpNeighboursPadIterator::fgkInvalidIndex = 9999;
41 //never so much neighbours...
43 //______________________________________________________________________________
44 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator()
45 : AliMpVPadIterator(),
47 fCenterPad(AliMpPad::Invalid()),
49 fIndex(fgkInvalidIndex)
51 /// Default constructor, set the current position to "invalid"
54 //______________________________________________________________________________
55 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
56 const AliMpVSegmentation* segmentation,
57 const AliMpPad& centerPad,
59 : AliMpVPadIterator(),
60 fkSegmentation(segmentation),
61 fCenterPad(centerPad),
63 fIndex(fgkInvalidIndex)
65 /// Standard constructor, set *this to invalid position
67 FillPadsVector(includeCenter);
70 //______________________________________________________________________________
71 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
72 const AliMpNeighboursPadIterator& right)
73 : AliMpVPadIterator(right),
75 fCenterPad(AliMpPad::Invalid()),
77 fIndex(fgkInvalidIndex)
84 //______________________________________________________________________________
85 AliMpNeighboursPadIterator::~AliMpNeighboursPadIterator()
96 //______________________________________________________________________________
97 AliMpNeighboursPadIterator&
98 AliMpNeighboursPadIterator::operator = (const AliMpNeighboursPadIterator& right)
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.
105 // check assignment to self
106 if (this == &right) return *this;
108 // base class assignment
109 AliMpVPadIterator::operator=(right);
112 fkSegmentation = right.fkSegmentation;
113 fCenterPad = right.fCenterPad;
115 fIndex = right.fIndex;
118 AliFatal("Not allowed assignment for TObjArray");
128 //______________________________________________________________________________
129 Bool_t AliMpNeighboursPadIterator::IsNeighbour(const AliMpPad& pad) const
131 /// Return true if the pad located by \a pad is a neighbour of those
132 /// located at a\ fCenterPad
134 if ( !pad.IsValid() ) return kFALSE;
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());
144 //______________________________________________________________________________
145 AliMpNeighboursPadIterator::PadVector
146 AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
147 const AliMpIntPair& direction) const
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
153 AliMpPad current = from;
157 if (IsNeighbour(current))
158 ans.push_back(current);
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);
169 //______________________________________________________________________________
170 void AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal,
171 const PadVector& from) const
173 /// Add pads from pad vector to the total set
174 /// only if they are not yet included
176 setTotal.insert(from.begin(),from.end());
181 //______________________________________________________________________________
182 AliMpNeighboursPadIterator::PadVector*
183 AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
184 const AliMpIntPair& direction) const
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
190 AliMpPad current = from;
191 PadVector* ans = new PadVector();
194 if (IsNeighbour(current))
195 ans->Add(new AliMpPad(current));
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);
206 //______________________________________________________________________________
207 void AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal,
208 PadVector* from) const
210 /// Add pads from pad vector to the total set
211 /// only if they are not yet included and deletes the pad vector
213 for (Int_t i=0; i<from->GetEntriesFast(); i++) {
214 AliMpPad* candidate = (AliMpPad*)from->At(i);
216 Bool_t isInSetTotal = false;
217 for (Int_t j=0; j<setTotal.GetEntriesFast(); j++) {
218 AliMpPad* pad = (AliMpPad*)setTotal.At(j);
220 if (pad->GetIndices() == candidate->GetIndices()) {
226 setTotal.Add(candidate);
235 //______________________________________________________________________________
236 void AliMpNeighboursPadIterator::FillPadsVector(Bool_t includeCenter)
238 /// Fill the indices vector with all indices of pads which have common
239 /// parts with the pad located at \a fCenterPad
241 if (!fkSegmentation || !fCenterPad.IsValid()) return;
245 AliMpIntPair direction;
253 // repare a unique simple associative container
254 // --> no doublons, rapid insersion
257 ///////////// Left side
259 ////////////////// up direction
261 from = fkSegmentation->PadsLeft(fCenterPad).GetFirst();
262 direction = AliMpIntPair(0,1);
263 found = PadVectorLine(from,direction);
264 UpdateTotalSet(setTotal, found);
266 ////////////////// down direction
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);
273 ///////////// Up side
275 ////////////////// right direction
277 from = fkSegmentation->PadsUp(fCenterPad).GetFirst();
278 direction = AliMpIntPair(1,0);
279 found = PadVectorLine(from,direction);
280 UpdateTotalSet(setTotal, found);
282 ////////////////// left direction
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);
289 ///////////// Right side
291 ////////////////// Up direction
293 from = fkSegmentation->PadsRight(fCenterPad).GetFirst();
294 direction = AliMpIntPair(0,1);
295 found = PadVectorLine(from,direction);
296 UpdateTotalSet(setTotal, found);
298 ////////////////// down direction
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);
305 ///////////// Down side
307 ////////////////// Right direction
309 from = fkSegmentation->PadsDown(fCenterPad).GetFirst();
310 direction = AliMpIntPair(1,0);
311 found = PadVectorLine(from,direction);
312 UpdateTotalSet(setTotal, found);
314 ////////////////// left direction
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);
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)
326 // include the center pad if requiered
327 if (includeCenter) fPads.push_back(fCenterPad);
328 //fPads.insert(fPads.end(),setTotal.begin(),setTotal.end());
331 for (it = setTotal.begin(); it != setTotal.end(); it++)
332 fPads.push_back((*it));
337 // include the center pad if requiered
338 if (includeCenter) fPads.Add(new AliMpPad(fCenterPad));
340 for (Int_t i = 0; i<setTotal.GetEntriesFast(); i++)
341 fPads.Add(setTotal.At(i));
345 //______________________________________________________________________________
346 Bool_t AliMpNeighboursPadIterator::IsValid() const
348 /// Is the iterator in a valid position?
350 return (fkSegmentation!=0 && fIndex!=fgkInvalidIndex);
355 //______________________________________________________________________________
356 void AliMpNeighboursPadIterator::First()
358 /// Reset the iterator, so that it points to the first available
359 /// pad in the sector
362 if ((fkSegmentation != 0) && (fPads.size() != 0))
365 if ((fkSegmentation != 0) && (fPads.GetEntriesFast() != 0))
369 fIndex=fgkInvalidIndex;
373 //______________________________________________________________________________
374 void AliMpNeighboursPadIterator::Next()
376 /// Pre-increment operator. Should be used by default for iterating over
380 if (!IsValid()) return;
383 if (fIndex < fPads.size()-1)
386 if (Int_t(fIndex) < fPads.GetEntriesFast()-1)
393 //______________________________________________________________________________
394 Bool_t AliMpNeighboursPadIterator::IsDone() const
396 /// Is the iterator in the end?
401 //______________________________________________________________________________
402 AliMpPad AliMpNeighboursPadIterator::CurrentItem() const
404 /// Dereferencement function
407 return AliMpPad::Invalid();
410 return fPads[fIndex];
413 return *((AliMpPad*)fPads[fIndex]);
417 //______________________________________________________________________________
418 void AliMpNeighboursPadIterator::Invalidate()
420 /// Let the iterator point to the invalid position
422 fIndex=fgkInvalidIndex;