Adding comment lines to class description needed for Root documentation,
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpPCBPadIterator.cxx
CommitLineData
618ea77a 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16// $Id$
17// $MpId$
18
19#include "AliMpPCBPadIterator.h"
20
21#include "AliMpArea.h"
22#include "AliMpConstants.h"
23#include "AliLog.h"
24#include "AliMpPCB.h"
25#include "AliMpSlat.h"
26#include "AliMpSlatSegmentation.h"
27
28#include "Riostream.h"
29#include "TMath.h"
30
3d1463c8 31
32//-----------------------------------------------------------------------------
618ea77a 33/// \class AliMpPCBPadIterator
34///
35/// Iterates over slat pads within a region of constant pad size.
36///
37/// \author Laurent Aphecetche
3d1463c8 38//-----------------------------------------------------------------------------
618ea77a 39
40/// \cond CLASSIMP
41ClassImp(AliMpPCBPadIterator)
42/// \endcond
43
44//_____________________________________________________________________________
45AliMpPCBPadIterator::AliMpPCBPadIterator(const AliMpSlat* slat,
46 const AliMpArea& area)
47: AliMpVPadIterator(),
48fkSlat(slat),
49fSlatSegmentation(new AliMpSlatSegmentation(slat)),
50fMinIndices(),
51fMaxIndices(),
52fOffset(0,0),
53fCurrentPad(),
54fIsDone(kTRUE)
55{
71a2d3aa 56 ///
57 /// Normal ctor.
58 /// Iteration will be done on the slat, over the crop of (area,slat_area)
59 ///
618ea77a 60 if (!CropArea(area))
61 {
62 AliError(Form("Could not crop area : (x,y)min=(%e,%e) ; max=(%e,%e) for slat %s",
63 area.LeftBorder(),area.DownBorder(),
64 area.RightBorder(),area.UpBorder(),fkSlat->GetID()));
65 }
66 Invalidate();
67}
68
69//_____________________________________________________________________________
70AliMpPCBPadIterator::~AliMpPCBPadIterator()
71{
71a2d3aa 72 ///
73 /// Dtor.
74 ///
618ea77a 75 delete fSlatSegmentation;
76}
77
78//_____________________________________________________________________________
79Bool_t
80AliMpPCBPadIterator::CropArea(const AliMpArea& area)
81{
71a2d3aa 82 ///
83 /// Checks the area is correct, and truncate it
84 /// if it goes outside the slat.
618ea77a 85
86 AliDebug(3,Form("Input area (%7.2f,%7.2f)->(%7.2f,%7.2f)",
87 area.LeftBorder(),area.DownBorder(),
88 area.RightBorder(),area.UpBorder()));
89
90 const Double_t kEpsilon = AliMpConstants::LengthTolerance();
91
92 // Left and right x-limits have to come from first and last pcbs
93 // to deal with short and rounded pcbs cases.
94 AliMpPCB* first = fkSlat->FindPCB(area.LeftBorder(),area.DownBorder());
95 AliMpPCB* last = fkSlat->FindPCB(area.RightBorder()-kEpsilon,
96 area.DownBorder());
97
98 // Check we're indeed dealing with only one pcb
99 if ( first != last )
100 {
101 AliError("This iterator supposed to work on a single PCB. Please check");
102 return kFALSE;
103 }
104
105 AliDebug(3,Form("PCB %s Ixmin %2d Ixmax %2d",
106 first->GetID(),first->Ixmin(),first->Ixmax()));
107
108 Double_t xleft = first->ActiveXmin();
109 Double_t xright = first->ActiveXmax() - kEpsilon;
110
111 AliDebug(3,Form("xleft,xright=%e,%e",xleft,xright));
112
1b36647b 113 Double_t xmin = TMath::Max(area.LeftBorder(),xleft);
114 Double_t xmax = TMath::Min(area.RightBorder(),xright);
115 Double_t ymin = TMath::Max(area.DownBorder(),0.0);
116 Double_t ymax = TMath::Min(area.UpBorder(),first->DY()*2.0-kEpsilon);
618ea77a 117
118 AliDebug(3,Form("Cropped area (%e,%e)->(%e,%e)",
119 xmin,ymin,xmax,ymax));
120
121 // At this point (xmin,ymin)->(xmax,ymax) should be a zone completely included
122 // inside the slat.
123 // We now try to convert this into a couple of indices pair indicating the
124 // region to iterate over, using integer values, not floating point ones.
125 // For this, we must find out the 4 pads that intersect the (xmin,ymin;xmax,ymax)
126 // area.
127
128 Int_t ixmin = first->Ixmin() + TMath::FloorNint((xmin-first->ActiveXmin())/first->PadSizeX());
129 Int_t ixmax = first->Ixmin() + TMath::CeilNint((xmax-first->ActiveXmin())/first->PadSizeX()) - 1;
130 Int_t iymin = first->Iymin() + TMath::FloorNint((ymin-first->Ymin())/first->PadSizeY());
131 Int_t iymax = first->Iymin() + TMath::CeilNint((ymax-first->Ymin())/first->PadSizeY()) - 1;
132
133
134 fMinIndices.Set(ixmin,iymin);
135 fMaxIndices.Set(ixmax,iymax);
136
137 AliDebug(3,Form("Paddified cropped area (%d,%d)->(%d,%d) %d,%d ; %d,%d",
138 ixmin,iymin,ixmax,iymax,
139 fMinIndices.GetFirst(),fMinIndices.GetSecond(),
140 fMaxIndices.GetFirst(),fMaxIndices.GetSecond()));
141
142 return fMinIndices.IsValid() && fMaxIndices.IsValid();
143}
144
145//_____________________________________________________________________________
146AliMpPad
147AliMpPCBPadIterator::CurrentItem() const
148{
71a2d3aa 149 ///
150 /// Returns the current iteration position (i.e. a pad)
151 ///
618ea77a 152 return fCurrentPad;
153}
154
155//_____________________________________________________________________________
156void
157AliMpPCBPadIterator::First()
158{
71a2d3aa 159 ///
160 /// (re)Starts the iteration.
161 ///
618ea77a 162
163 AliDebug(3,Form("area = (%d,%d)->(%d,%d)",
164 fMinIndices.GetFirst(),fMinIndices.GetSecond(),
165 fMaxIndices.GetFirst(),fMaxIndices.GetSecond()));
166 fOffset = fMinIndices;
167 fIsDone = kFALSE;
168 SetPad(fCurrentPad,fOffset);
169 if (!fCurrentPad.IsValid()) Next();
170 if ( !fCurrentPad.IsValid() )
171 {
172 // did not find any valid pad in there, bailing out.
173 fIsDone = kTRUE;
174 AliError(Form("Could not initiate iterator for slat %s. "
175 " Please check the area you gave : %d,%d to %d,%d",
176 fkSlat->GetName(),
177 fMinIndices.GetFirst(),
178 fMinIndices.GetSecond(),
179 fMaxIndices.GetFirst(),
180 fMaxIndices.GetSecond()));
181 return;
182 }
183}
184
185//_____________________________________________________________________________
186Bool_t
187AliMpPCBPadIterator::GetNextPosition(Int_t& ix, Int_t& iy)
188{
71a2d3aa 189 /// Get the next iteration position.
190 /// On input, fOffset must be a valid position (i.e. within iteration
191 /// area already).
618ea77a 192
193 ++ix;
194
195 if ( ix > fMaxIndices.GetFirst() )
196 {
618ea77a 197 // Go back leftmost position...
198 ix = fMinIndices.GetFirst();
199 // ... and up
200 ++iy;
201 if ( iy > fMaxIndices.GetSecond() )
202 {
203 return false;
204 }
205 }
206 return true;
207}
208
209
210//_____________________________________________________________________________
211void
212AliMpPCBPadIterator::Invalidate()
213{
71a2d3aa 214 ///
215 /// Invalidate the iterator.
216 ///
618ea77a 217 fOffset = AliMpIntPair::Invalid();
218 fCurrentPad = AliMpPad::Invalid();
219 fIsDone = kTRUE;
220}
221
222//_____________________________________________________________________________
223Bool_t
224AliMpPCBPadIterator::IsDone() const
225{
71a2d3aa 226 ///
227 /// Whether the iteration is finished or not.
228 ///
618ea77a 229 return fIsDone;
230}
231
232//_____________________________________________________________________________
233void
234AliMpPCBPadIterator::Next()
235{
71a2d3aa 236 /// This one is the meat of the class.
237 /// We're iterating in x-direction mainly, starting from
238 /// lower-left of the iteration area, and proceeding right,
239 /// until we reach right border, in which case we increment y
240 /// and go back to leftmost position.
241 /// End of iteration occurs when both x and y are outside the iteration
242 /// window.
618ea77a 243
244 if (IsDone()) return;
245
246 AliMpPad pad(fCurrentPad);
247 int n = 0;
248 Int_t ix(fOffset.GetFirst());
249 Int_t iy(fOffset.GetSecond());
250
251 while ( ( pad == fCurrentPad || !pad.IsValid() ) && n<100 )
252 {
253 ++n;
254 if (GetNextPosition(ix,iy)==kFALSE)
255 {
256 Invalidate();
257 return;
258 }
259 SetPad(pad,AliMpIntPair(ix,iy));
260 }
261 if ( n>=100 )
262 {
263 AliFatal("This should not happen!");
264 }
265 fCurrentPad = pad;
266}
267
268//_____________________________________________________________________________
269void
270AliMpPCBPadIterator::Print(Option_t*) const
271{
272 /// printout
273 cout << Form("fkSlat=%p fSlatSegmentation=%p (%s)",fkSlat,fSlatSegmentation,
274 fkSlat->GetName()) << endl
275 << Form("minIndices=(%d,%d) maxIndices=(%d,%d)",
276 fMinIndices.GetFirst(),fMinIndices.GetSecond(),
277 fMaxIndices.GetFirst(),fMaxIndices.GetSecond()) << endl
278 << Form("currentOffset=(%d,%d) isdone=%d currentpad=",
279 fOffset.GetFirst(),fOffset.GetSecond(),IsDone()) << endl;
280 fCurrentPad.Print();
281}
282
283//_____________________________________________________________________________
284void
285AliMpPCBPadIterator::SetPad(AliMpPad& pad, const AliMpIntPair& indices)
286{
71a2d3aa 287 ///
288 /// Sets the current pad.
289 ///
618ea77a 290 pad = fSlatSegmentation->PadByIndices(indices,kFALSE);
291 if (pad.IsValid())
292 {
293 fOffset = indices;
294 }
295}