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