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