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 "AliMpSectorSegmentation.h"
30 #include "AliMpConstants.h"
35 ClassImp(AliMpNeighboursPadIterator)
38 const UInt_t AliMpNeighboursPadIterator::fgkInvalidIndex = 9999;
39 //never so much neighbours...
41 //______________________________________________________________________________
42 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator()
43 : AliMpVPadIterator(),
45 fCenterPad(AliMpPad::Invalid()),
47 fIndex(fgkInvalidIndex)
49 /// Default constructor, set the current position to "invalid"
52 //______________________________________________________________________________
53 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
54 const AliMpSectorSegmentation* segmentation,
55 const AliMpPad& centerPad,
57 : AliMpVPadIterator(),
58 fkSegmentation(segmentation),
59 fCenterPad(centerPad),
61 fIndex(fgkInvalidIndex)
63 /// Standard constructor, set *this to invalid position
65 FillPadsVector(includeCenter);
68 //______________________________________________________________________________
69 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
70 const AliMpNeighboursPadIterator& right)
71 : AliMpVPadIterator(right),
73 fCenterPad(AliMpPad::Invalid()),
75 fIndex(fgkInvalidIndex)
82 //______________________________________________________________________________
83 AliMpNeighboursPadIterator::~AliMpNeighboursPadIterator()
94 //______________________________________________________________________________
95 AliMpNeighboursPadIterator&
96 AliMpNeighboursPadIterator::operator = (const AliMpNeighboursPadIterator& right)
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.
103 // check assignment to self
104 if (this == &right) return *this;
106 // base class assignment
107 AliMpVPadIterator::operator=(right);
110 fkSegmentation = right.fkSegmentation;
111 fCenterPad = right.fCenterPad;
113 fIndex = right.fIndex;
116 AliFatal("Not allowed assignment for TObjArray");
126 //______________________________________________________________________________
127 Bool_t AliMpNeighboursPadIterator::IsNeighbour(const AliMpPad& pad) const
129 /// Return true if the pad located by \a pad is a neighbour of those
130 /// located at a\ fCenterPad
132 if ( !pad.IsValid() ) return kFALSE;
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());
142 //______________________________________________________________________________
143 AliMpNeighboursPadIterator::PadVector
144 AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
145 const AliMpIntPair& direction) const
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
151 AliMpPad current = from;
155 if (IsNeighbour(current))
156 ans.push_back(current);
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);
167 //______________________________________________________________________________
168 void AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal,
169 const PadVector& from) const
171 /// Add pads from pad vector to the total set
172 /// only if they are not yet included
174 setTotal.insert(from.begin(),from.end());
179 //______________________________________________________________________________
180 AliMpNeighboursPadIterator::PadVector*
181 AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
182 const AliMpIntPair& direction) const
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
188 AliMpPad current = from;
189 PadVector* ans = new PadVector();
192 if (IsNeighbour(current))
193 ans->Add(new AliMpPad(current));
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);
204 //______________________________________________________________________________
205 void AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal,
206 PadVector* from) const
208 /// Add pads from pad vector to the total set
209 /// only if they are not yet included and deletes the pad vector
211 for (Int_t i=0; i<from->GetEntriesFast(); i++) {
212 AliMpPad* candidate = (AliMpPad*)from->At(i);
214 Bool_t isInSetTotal = false;
215 for (Int_t j=0; j<setTotal.GetEntriesFast(); j++) {
216 AliMpPad* pad = (AliMpPad*)setTotal.At(j);
218 if (pad->GetIndices() == candidate->GetIndices()) {
224 setTotal.Add(candidate);
233 //______________________________________________________________________________
234 void AliMpNeighboursPadIterator::FillPadsVector(Bool_t includeCenter)
236 /// Fill the indices vector with all indices of pads which have common
237 /// parts with the pad located at \a fCenterPad
239 if (!fkSegmentation || !fCenterPad.IsValid()) return;
243 AliMpIntPair direction;
251 // repare a unique simple associative container
252 // --> no doublons, rapid insersion
255 ///////////// Left side
257 ////////////////// up direction
259 from = fkSegmentation->PadsLeft(fCenterPad).GetFirst();
260 direction = AliMpIntPair(0,1);
261 found = PadVectorLine(from,direction);
262 UpdateTotalSet(setTotal, found);
264 ////////////////// down direction
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);
271 ///////////// Up side
273 ////////////////// right direction
275 from = fkSegmentation->PadsUp(fCenterPad).GetFirst();
276 direction = AliMpIntPair(1,0);
277 found = PadVectorLine(from,direction);
278 UpdateTotalSet(setTotal, found);
280 ////////////////// left direction
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);
287 ///////////// Right side
289 ////////////////// Up direction
291 from = fkSegmentation->PadsRight(fCenterPad).GetFirst();
292 direction = AliMpIntPair(0,1);
293 found = PadVectorLine(from,direction);
294 UpdateTotalSet(setTotal, found);
296 ////////////////// down direction
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);
303 ///////////// Down side
305 ////////////////// Right direction
307 from = fkSegmentation->PadsDown(fCenterPad).GetFirst();
308 direction = AliMpIntPair(1,0);
309 found = PadVectorLine(from,direction);
310 UpdateTotalSet(setTotal, found);
312 ////////////////// left direction
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);
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)
324 // include the center pad if requiered
325 if (includeCenter) fPads.push_back(fCenterPad);
326 //fPads.insert(fPads.end(),setTotal.begin(),setTotal.end());
329 for (it = setTotal.begin(); it != setTotal.end(); it++)
330 fPads.push_back((*it));
335 // include the center pad if requiered
336 if (includeCenter) fPads.Add(new AliMpPad(fCenterPad));
338 for (Int_t i = 0; i<setTotal.GetEntriesFast(); i++)
339 fPads.Add(setTotal.At(i));
343 //______________________________________________________________________________
344 Bool_t AliMpNeighboursPadIterator::IsValid() const
346 /// Is the iterator in a valid position?
348 return (fkSegmentation!=0 && fIndex!=fgkInvalidIndex);
353 //______________________________________________________________________________
354 void AliMpNeighboursPadIterator::First()
356 /// Reset the iterator, so that it points to the first available
357 /// pad in the sector
360 if ((fkSegmentation != 0) && (fPads.size() != 0))
363 if ((fkSegmentation != 0) && (fPads.GetEntriesFast() != 0))
367 fIndex=fgkInvalidIndex;
371 //______________________________________________________________________________
372 void AliMpNeighboursPadIterator::Next()
374 /// Pre-increment operator. Should be used by default for iterating over
378 if (!IsValid()) return;
381 if (fIndex < fPads.size()-1)
384 if (Int_t(fIndex) < fPads.GetEntriesFast()-1)
391 //______________________________________________________________________________
392 Bool_t AliMpNeighboursPadIterator::IsDone() const
394 /// Is the iterator in the end?
399 //______________________________________________________________________________
400 AliMpPad AliMpNeighboursPadIterator::CurrentItem() const
402 /// Dereferencement function
405 return AliMpPad::Invalid();
408 return fPads[fIndex];
411 return *((AliMpPad*)fPads[fIndex]);
415 //______________________________________________________________________________
416 void AliMpNeighboursPadIterator::Invalidate()
418 /// Let the iterator point to the invalid position
420 fIndex=fgkInvalidIndex;