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.9 2005/09/26 16:12:23 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 AliMpNeighboursPadIterator::PadVector
136 AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
137 const AliMpIntPair& direction) const
139 /// Fill a new vector with all pads which have common
140 /// parts with the pad located at <fCenterPad>, in a given line
141 /// starting from <from> and moving by <direction>
143 AliMpPad current = from;
147 if (IsNeighbours(current))
148 ans.push_back(current);
151 TVector2 nextPos = current.Position() + TVector2(
152 current.Dimensions().X()*(AliMpConstants::LengthStep()+1.)*direction.GetFirst(),
153 current.Dimensions().Y()*(AliMpConstants::LengthStep()+1.)*direction.GetSecond());
154 current = fkSegmentation->PadByPosition(nextPos);
159 //______________________________________________________________________________
160 void AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal,
161 const PadVector& from) const
163 /// Add pads from pad vector to the total set
164 /// only if they are not yet included
166 setTotal.insert(from.begin(),from.end());
171 //______________________________________________________________________________
172 AliMpNeighboursPadIterator::PadVector*
173 AliMpNeighboursPadIterator::PadVectorLine(const AliMpPad& from,
174 const AliMpIntPair& direction) const
176 /// Fill a new vector with all pads which have common
177 /// parts with the pad located at <fCenterPad>, in a given line
178 /// starting from <from> and moving by <direction>
180 AliMpPad current = from;
181 PadVector* ans = new PadVector();
184 if (IsNeighbours(current))
185 ans->Add(new AliMpPad(current));
188 TVector2 nextPos = current.Position() + TVector2(
189 current.Dimensions().X()*(AliMpConstants::LengthStep()+1.)*direction.GetFirst(),
190 current.Dimensions().Y()*(AliMpConstants::LengthStep()+1.)*direction.GetSecond());
191 current = fkSegmentation->PadByPosition(nextPos);
196 //______________________________________________________________________________
197 void AliMpNeighboursPadIterator::UpdateTotalSet(PadSet& setTotal,
198 PadVector* from) const
200 /// Add pads from pad vector to the total set
201 /// only if they are not yet included and deletes the pad vector
203 for (Int_t i=0; i<from->GetEntriesFast(); i++) {
204 AliMpPad* candidate = (AliMpPad*)from->At(i);
206 Bool_t isInSetTotal = false;
207 for (Int_t j=0; j<setTotal.GetEntriesFast(); j++) {
208 AliMpPad* pad = (AliMpPad*)setTotal.At(j);
210 if (pad->GetIndices() == candidate->GetIndices()) {
216 setTotal.Add(candidate);
225 //______________________________________________________________________________
226 void AliMpNeighboursPadIterator::FillPadsVector(Bool_t includeCenter)
228 /// Fill the indices vector with all indices of pads which have common
229 /// parts with the pad located at <fCenterPad>
231 if (!fkSegmentation || !fCenterPad.IsValid()) return;
235 AliMpIntPair direction;
243 // repare a unique simple associative container
244 // --> no doublons, rapid insersion
247 ///////////// Left side
249 ////////////////// up direction
251 from = fkSegmentation->PadsLeft(fCenterPad).GetFirst();
252 direction = AliMpIntPair(0,1);
253 found = PadVectorLine(from,direction);
254 UpdateTotalSet(setTotal, found);
256 ////////////////// down direction
258 from = fkSegmentation->PadsDown(from).GetFirst(); // the Pad down is already added
259 direction = AliMpIntPair(0,-1);
260 found = PadVectorLine(from,direction);
261 UpdateTotalSet(setTotal, found);
263 ///////////// Up side
265 ////////////////// right direction
267 from = fkSegmentation->PadsUp(fCenterPad).GetFirst();
268 direction = AliMpIntPair(1,0);
269 found = PadVectorLine(from,direction);
270 UpdateTotalSet(setTotal, found);
272 ////////////////// left direction
274 from = fkSegmentation->PadsLeft(from).GetFirst(); // the pad up is already added
275 direction = AliMpIntPair(-1,0);
276 found = PadVectorLine(from,direction);
277 UpdateTotalSet(setTotal, found);
279 ///////////// Right side
281 ////////////////// Up direction
283 from = fkSegmentation->PadsRight(fCenterPad).GetFirst();
284 direction = AliMpIntPair(0,1);
285 found = PadVectorLine(from,direction);
286 UpdateTotalSet(setTotal, found);
288 ////////////////// down direction
290 from = fkSegmentation->PadsDown(from).GetFirst(); // the pad right is already added
291 direction = AliMpIntPair(0,-1);
292 found = PadVectorLine(from,direction);
293 UpdateTotalSet(setTotal, found);
295 ///////////// Down side
297 ////////////////// Right direction
299 from = fkSegmentation->PadsDown(fCenterPad).GetFirst();
300 direction = AliMpIntPair(1,0);
301 found = PadVectorLine(from,direction);
302 UpdateTotalSet(setTotal, found);
304 ////////////////// left direction
306 from = fkSegmentation->PadsLeft(from).GetFirst(); // the pad down is already added
307 direction = AliMpIntPair(-1,0);
308 found = PadVectorLine(from,direction);
309 UpdateTotalSet(setTotal, found);
311 // fill the fIndices vector with the set (-->pass from a rapid insertion,
312 // to rapid and indexed access, for the rest of the job)
316 // include the center pad if requiered
317 if (includeCenter) fPads.push_back(fCenterPad);
318 //fPads.insert(fPads.end(),setTotal.begin(),setTotal.end());
321 for (it = setTotal.begin(); it != setTotal.end(); it++)
322 fPads.push_back((*it));
327 // include the center pad if requiered
328 if (includeCenter) fPads.Add(new AliMpPad(fCenterPad));
330 for (Int_t i = 0; i<setTotal.GetEntriesFast(); i++)
331 fPads.Add(setTotal.At(i));
335 //______________________________________________________________________________
336 Bool_t AliMpNeighboursPadIterator::IsValid() const
338 /// Is the iterator in a valid position?
340 return (fkSegmentation!=0 && fIndex!=fgkInvalidIndex);
345 //______________________________________________________________________________
346 void AliMpNeighboursPadIterator::First()
348 /// Reset the iterator, so that it points to the first available
349 /// pad in the sector
352 if ((fkSegmentation != 0) && (fPads.size() != 0))
355 if ((fkSegmentation != 0) && (fPads.GetEntriesFast() != 0))
359 fIndex=fgkInvalidIndex;
363 //______________________________________________________________________________
364 void AliMpNeighboursPadIterator::Next()
366 /// Pre-increment operator. Should be used by default for iterating over
370 if (!IsValid()) return;
373 if (fIndex < fPads.size()-1)
376 if (Int_t(fIndex) < fPads.GetEntriesFast()-1)
383 //______________________________________________________________________________
384 Bool_t AliMpNeighboursPadIterator::IsDone() const
386 /// Is the iterator in the end?
391 //______________________________________________________________________________
392 AliMpPad AliMpNeighboursPadIterator::CurrentItem() const
394 /// Dereferencement function
397 return AliMpPad::Invalid();
400 return fPads[fIndex];
403 return *((AliMpPad*)fPads[fIndex]);
407 //______________________________________________________________________________
408 void AliMpNeighboursPadIterator::Invalidate()
410 /// Let the iterator point to the invalid position
412 fIndex=fgkInvalidIndex;