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.8 2005/08/26 15:43:36 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
28 #include "AliMpNeighboursPadIterator.h"
29 #include "AliMpIntPair.h"
30 #include "AliMpSectorSegmentation.h"
32 #include "AliMpConstants.h"
34 ClassImp(AliMpNeighboursPadIterator)
36 const UInt_t AliMpNeighboursPadIterator::fgkInvalidIndex = 9999;
37 //never so much neighbours...
39 //______________________________________________________________________________
40 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator()
41 : AliMpVPadIterator(),
43 fCenterPad(AliMpPad::Invalid()),
45 fIndex(fgkInvalidIndex)
47 /// Default constructor, set the current position to "invalid"
50 //______________________________________________________________________________
51 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
52 const AliMpSectorSegmentation* segmentation,
53 const AliMpPad& centerPad,
55 : AliMpVPadIterator(),
56 fkSegmentation(segmentation),
57 fCenterPad(centerPad),
58 fIndex(fgkInvalidIndex)
60 /// Standard constructor, set *this to invalid position
62 FillPadsVector(includeCenter);
65 //______________________________________________________________________________
66 AliMpNeighboursPadIterator::AliMpNeighboursPadIterator(
67 const AliMpNeighboursPadIterator& right)
68 : AliMpVPadIterator(right)
75 //______________________________________________________________________________
76 AliMpNeighboursPadIterator::~AliMpNeighboursPadIterator()
87 //______________________________________________________________________________
88 AliMpNeighboursPadIterator&
89 AliMpNeighboursPadIterator::operator = (const AliMpNeighboursPadIterator& right)
91 /// Assignment operator. \n
92 /// If the right hand iterator isn't of a good type
93 /// the current operator is invalidated \n
94 /// Not provided for WITH_ROOT option.
96 // check assignment to self
97 if (this == &right) return *this;
99 // base class assignment
100 AliMpVPadIterator::operator=(right);
103 fkSegmentation = right.fkSegmentation;
104 fCenterPad = right.fCenterPad;
106 fIndex = right.fIndex;
109 Fatal("operator=", "Not allowed assignment for TObjArray");
119 //______________________________________________________________________________
120 Bool_t AliMpNeighboursPadIterator::IsNeighbours(const AliMpPad& pad) const
122 /// Return true if the pad located by <padIndice> is a neighbour of those
123 /// located at <fCenterPad>
126 TVector2 relPos = pad.Position() - fCenterPad.Position();
127 TVector2 bounds = pad.Dimensions() + fCenterPad.Dimensions();
128 return (TMath::Abs(relPos.X())- bounds.X()<AliMpConstants::LengthTolerance()) &&
129 (TMath::Abs(relPos.Y())- bounds.Y()<AliMpConstants::LengthTolerance());
134 //______________________________________________________________________________
135 PadVector AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
136 const AliMpIntPair& direction) const
138 /// Fill a new vector with all pads which have common
139 /// parts with the pad located at <fCenterPad>, in a given line
140 /// starting from <from> and moving by <direction>
142 AliMpPad current = from;
146 if (IsNeighbours(current))
147 ans.push_back(current);
150 TVector2 nextPos = current.Position() + TVector2(
151 current.Dimensions().X()*(AliMpConstants::LengthStep()+1.)*direction.GetFirst(),
152 current.Dimensions().Y()*(AliMpConstants::LengthStep()+1.)*direction.GetSecond());
153 current = fkSegmentation->PadByPosition(nextPos);
158 //______________________________________________________________________________
159 void AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal,
160 const PadVector& from) const
162 /// Add pads from pad vector to the total set
163 /// only if they are not yet included
165 setTotal.insert(from.begin(),from.end());
170 //______________________________________________________________________________
171 PadVector* AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
172 const AliMpIntPair& direction) const
174 /// Fill a new vector with all pads which have common
175 /// parts with the pad located at <fCenterPad>, in a given line
176 /// starting from <from> and moving by <direction>
178 AliMpPad current = from;
179 PadVector* ans = new PadVector();
182 if (IsNeighbours(current))
183 ans->Add(new AliMpPad(current));
186 TVector2 nextPos = current.Position() + TVector2(
187 current.Dimensions().X()*(AliMpConstants::LengthStep()+1.)*direction.GetFirst(),
188 current.Dimensions().Y()*(AliMpConstants::LengthStep()+1.)*direction.GetSecond());
189 current = fkSegmentation->PadByPosition(nextPos);
194 //______________________________________________________________________________
195 void AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal,
196 PadVector* from) const
198 /// Add pads from pad vector to the total set
199 /// only if they are not yet included and deletes the pad vector
201 for (Int_t i=0; i<from->GetEntriesFast(); i++) {
202 AliMpPad* candidate = (AliMpPad*)from->At(i);
204 Bool_t isInSetTotal = false;
205 for (Int_t j=0; j<setTotal.GetEntriesFast(); j++) {
206 AliMpPad* pad = (AliMpPad*)setTotal.At(j);
208 if (pad->GetIndices() == candidate->GetIndices()) {
214 setTotal.Add(candidate);
223 //______________________________________________________________________________
224 void AliMpNeighboursPadIterator::FillPadsVector(Bool_t includeCenter)
226 /// Fill the indices vector with all indices of pads which have common
227 /// parts with the pad located at <fCenterPad>
229 if (!fkSegmentation || !fCenterPad.IsValid()) return;
233 AliMpIntPair direction;
241 // repare a unique simple associative container
242 // --> no doublons, rapid insersion
245 ///////////// Left side
247 ////////////////// up direction
249 from = fkSegmentation->PadsLeft(fCenterPad).GetFirst();
250 direction = AliMpIntPair(0,1);
251 found = PadVectorLine(from,direction);
252 UpdateTotalSet(setTotal, found);
254 ////////////////// down direction
256 from = fkSegmentation->PadsDown(from).GetFirst(); // the Pad down is already added
257 direction = AliMpIntPair(0,-1);
258 found = PadVectorLine(from,direction);
259 UpdateTotalSet(setTotal, found);
261 ///////////// Up side
263 ////////////////// right direction
265 from = fkSegmentation->PadsUp(fCenterPad).GetFirst();
266 direction = AliMpIntPair(1,0);
267 found = PadVectorLine(from,direction);
268 UpdateTotalSet(setTotal, found);
270 ////////////////// left direction
272 from = fkSegmentation->PadsLeft(from).GetFirst(); // the pad up is already added
273 direction = AliMpIntPair(-1,0);
274 found = PadVectorLine(from,direction);
275 UpdateTotalSet(setTotal, found);
277 ///////////// Right side
279 ////////////////// Up direction
281 from = fkSegmentation->PadsRight(fCenterPad).GetFirst();
282 direction = AliMpIntPair(0,1);
283 found = PadVectorLine(from,direction);
284 UpdateTotalSet(setTotal, found);
286 ////////////////// down direction
288 from = fkSegmentation->PadsDown(from).GetFirst(); // the pad right is already added
289 direction = AliMpIntPair(0,-1);
290 found = PadVectorLine(from,direction);
291 UpdateTotalSet(setTotal, found);
293 ///////////// Down side
295 ////////////////// Right direction
297 from = fkSegmentation->PadsDown(fCenterPad).GetFirst();
298 direction = AliMpIntPair(1,0);
299 found = PadVectorLine(from,direction);
300 UpdateTotalSet(setTotal, found);
302 ////////////////// left direction
304 from = fkSegmentation->PadsLeft(from).GetFirst(); // the pad down is already added
305 direction = AliMpIntPair(-1,0);
306 found = PadVectorLine(from,direction);
307 UpdateTotalSet(setTotal, found);
309 // fill the fIndices vector with the set (-->pass from a rapid insertion,
310 // to rapid and indexed access, for the rest of the job)
314 // include the center pad if requiered
315 if (includeCenter) fPads.push_back(fCenterPad);
316 //fPads.insert(fPads.end(),setTotal.begin(),setTotal.end());
319 for (it = setTotal.begin(); it != setTotal.end(); it++)
320 fPads.push_back((*it));
325 // include the center pad if requiered
326 if (includeCenter) fPads.Add(new AliMpPad(fCenterPad));
328 for (Int_t i = 0; i<setTotal.GetEntriesFast(); i++)
329 fPads.Add(setTotal.At(i));
333 //______________________________________________________________________________
334 Bool_t AliMpNeighboursPadIterator::IsValid() const
336 /// Is the iterator in a valid position?
338 return (fkSegmentation!=0 && fIndex!=fgkInvalidIndex);
343 //______________________________________________________________________________
344 void AliMpNeighboursPadIterator::First()
346 /// Reset the iterator, so that it points to the first available
347 /// pad in the sector
350 if ((fkSegmentation != 0) && (fPads.size() != 0))
353 if ((fkSegmentation != 0) && (fPads.GetEntriesFast() != 0))
357 fIndex=fgkInvalidIndex;
361 //______________________________________________________________________________
362 void AliMpNeighboursPadIterator::Next()
364 /// Pre-increment operator. Should be used by default for iterating over
368 if (!IsValid()) return;
371 if (fIndex < fPads.size()-1)
374 if (Int_t(fIndex) < fPads.GetEntriesFast()-1)
381 //______________________________________________________________________________
382 Bool_t AliMpNeighboursPadIterator::IsDone() const
384 /// Is the iterator in the end?
389 //______________________________________________________________________________
390 AliMpPad AliMpNeighboursPadIterator::CurrentItem() const
392 /// Dereferencement function
395 return AliMpPad::Invalid();
398 return fPads[fIndex];
401 return *((AliMpPad*)fPads[fIndex]);
405 //______________________________________________________________________________
406 void AliMpNeighboursPadIterator::Invalidate()
408 /// Let the iterator point to the invalid position
410 fIndex=fgkInvalidIndex;