]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/mapping/AliMpSlatZonePadIterator.cxx
Doxygen configuration files (Initial version)
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpSlatZonePadIterator.cxx
CommitLineData
dee1d5f1 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: AliMpSlatZonePadIterator.cxx,v 1.4 2005/09/19 19:01:31 ivana Exp $
18
19#include "AliMpSlatZonePadIterator.h"
20
21#include "AliLog.h"
22#include "AliMpPCB.h"
23#include "AliMpSlat.h"
24#include "AliMpSlatSegmentation.h"
25
26#include <algorithm>
27#include <limits>
28#include <cassert>
29
30ClassImp(AliMpSlatZonePadIterator)
31
32// This iterator only works within a region of constant density.
33
34namespace
35{
36 const Double_t epsilon = 1E-9; // mm
37 Double_t DMAX(std::numeric_limits<Double_t>::max());
38}
39
40//_____________________________________________________________________________
41AliMpSlatZonePadIterator::AliMpSlatZonePadIterator(const AliMpSlat* slat,
42 const AliMpArea& area)
43: AliMpVPadIterator(),
44fkSlat(slat),
45fSlatSegmentation(new AliMpSlatSegmentation(slat)),
46fArea(area),
47fOffset(0.0,0.0),
48fStep(0.0,0.0),
49fIsDone(kTRUE)
50{
51 //
52 // Normal ctor.
53 // Iteration will be done on the slat, over the crop of (area,slat_area)
54 //
55 if (!CropArea())
56 {
57 AliFatal(Form("Could not crop area : (x,y)min=(%e,%e) ; max=(%e,%e) for slat %s",
58 area.LeftBorder(),area.DownBorder(),
59 area.RightBorder(),area.UpBorder(),fkSlat->GetID()));
60 }
61 Invalidate();
62}
63
64//_____________________________________________________________________________
65AliMpSlatZonePadIterator::~AliMpSlatZonePadIterator()
66{
67 //
68 // Dtor.
69 //
70 delete fSlatSegmentation;
71}
72
73//_____________________________________________________________________________
74Bool_t
75AliMpSlatZonePadIterator::CropArea()
76{
77 //
78 // Checks the area is correct, and truncate it
79 // if it goes outside the slat.
80
81 AliDebug(3,Form("Input area (%7.2f,%7.2f)->(%7.2f,%7.2f)",
82 fArea.LeftBorder(),fArea.DownBorder(),
83 fArea.RightBorder(),fArea.UpBorder()));
84
85 // Left and right x-limits have to come from first and last pcbs
86 // to deal with short and rounded pcbs cases.
87 AliMpPCB* first = fkSlat->FindPCB(fArea.LeftBorder(),fArea.DownBorder());
88 AliMpPCB* last = fkSlat->FindPCB(fArea.RightBorder()-epsilon,
89 fArea.DownBorder());
90
91 AliDebug(3,Form("First PCB %s Ixmin %2d Last PCB %s Ixmax %2d",
92 first->GetID(),first->Ixmin(),
93 last->GetID(),last->Ixmax()));
94
95 Double_t xleft = first->ActiveXmin();
96 Double_t xright = last->ActiveXmax() - epsilon;
97
98 AliDebug(3,Form("xleft,xright=%7.2f,%7.2f",xleft,xright));
99
100 Double_t xmin = std::max(fArea.LeftBorder(),xleft);
101 Double_t xmax = std::min(fArea.RightBorder(),xright);
102 Double_t ymin = std::max(fArea.DownBorder(),0.0);
103 Double_t ymax = std::min(fArea.UpBorder(),fkSlat->DY()*2.0-epsilon);
104
105 AliDebug(3,Form("Cropped area (%7.2f,%7.2f)->(%7.2f,%7.2f)",
106 xmin,ymin,xmax,ymax));
107
108 // At this point (xmin,ymin)->(xmax,ymax) should be a zone completely included
109 // inside the slat.
110 // But there's so far no guarantee that it is "filling" an integer number
111 // of pads. The following lines solve this, by expanding the area up to
112 // the bottomLeft and topRight limits of the pads sitting at (xmin,ymin)
113 // and (xmax,ymax).
114
115 AliMpPad bottomLeft
116 = fSlatSegmentation->PadByPosition(TVector2(xmin,ymin),kFALSE);
117 if ( bottomLeft.IsValid() )
118 {
119 xmin = std::min(xmin,fkSlat->DX() +
120 bottomLeft.Position().X() - bottomLeft.Dimensions().X());
121 ymin = std::min(ymin,fkSlat->DY() +
122 bottomLeft.Position().Y() - bottomLeft.Dimensions().Y());
123 }
124
125 AliMpPad topRight
126 = fSlatSegmentation->PadByPosition(TVector2(xmax,ymax),kFALSE);
127 if ( topRight.IsValid() )
128 {
129 xmax = std::max(xmax,fkSlat->DX() +
130 topRight.Position().X() + topRight.Dimensions().X());
131 ymax = std::max(ymax,fkSlat->DY() +
132 topRight.Position().Y() + topRight.Dimensions().Y());
133 }
134
135 fArea = AliMpArea(TVector2((xmin+xmax)/2.0,(ymin+ymax)/2.0),
136 TVector2((xmax-xmin)/2.0,(ymax-ymin)/2.0));
137
138 AliDebug(3,Form("Paddified cropped area (%7.2f,%7.2f)->(%7.2f,%7.2f)",
139 fArea.LeftBorder(),fArea.DownBorder(),
140 fArea.RightBorder(),fArea.UpBorder()));
141
142 // Finally set the step sizes equal to the smallest pad sizes (which is
143 // hereby assumed to be that of the first pcb).
144 fStep.Set(first->PadSizeX(),first->PadSizeY());
145
146 AliDebug(3,Form("Step Sizes (%7.2f,%7.2f)",fStep.X(),fStep.Y()));
147
148 return fArea.IsValid();
149}
150
151//_____________________________________________________________________________
152AliMpPad
153AliMpSlatZonePadIterator::CurrentItem() const
154{
155 //
156 // Returns the current iteration position (i.e. a pad)
157 //
158 return fCurrentPad;
159}
160
161//_____________________________________________________________________________
162Bool_t
163AliMpSlatZonePadIterator::GetNextPosition(Double_t& x, Double_t& y)
164{
165 // Get the next iteration position.
166 // On input, fOffset must be a valid position (i.e. within iteration
167 // area already).
168
169 AliDebug(3,Form("input (x,y)=(%7.2f,%7.2f)",x,y));
170
171 x += fStep.X();
172
173 if ( x > fArea.Dimensions().X() )
174 {
175 AliDebug(3,"Going back left");
176 // Go back leftmost position...
177 x = -1.0*fArea.Dimensions().X();
178 // ... and up
179 y += fStep.Y();
180 // Update y offset
181 fOffset.Set(fOffset.X(),y);
182 if ( y > fArea.Dimensions().Y() )
183 {
184 return false;
185 }
186 }
187 AliDebug(3,Form("output (x,y)=(%7.2f,%7.2f",x,y));
188 return true;
189}
190
191//_____________________________________________________________________________
192void
193AliMpSlatZonePadIterator::First()
194{
195 //
196 // (re)Starts the iteration.
197 //
198
199 fOffset = fArea.Dimensions()*(-1.0);
200 fIsDone = kFALSE;
201 SetPad(fCurrentPad,fArea.Position()+fOffset);
202 if (!fCurrentPad.IsValid()) Next();
203 AliDebug(3,Form("fOffset after Next=%7.2f,%7.2f",fOffset.X(),fOffset.Y()));
204 if ( !fCurrentPad.IsValid() )
205 {
206 // did not find any valid pad in there, bailing out.
207 fIsDone = kTRUE;
208 AliError("Could not initiate iterator. Please check the area you gave.");
209 return;
210 }
211 else
212 {
213 // Reposition to pad center (both in x and y).
214 // Please note that repositionning y is valid here, and only here
215 // (i.e. do *not* do this in Next() for instance).
216 fOffset.Set(fCurrentPad.Position().X()+fkSlat->DX()-fArea.Position().X(),
217 fCurrentPad.Position().Y()+fkSlat->DY()-fArea.Position().Y());
218 fIsDone = kFALSE;
219 }
220 AliDebug(3,Form("fOffset repositionned=%7.2f,%7.2f",fOffset.X(),fOffset.Y()));
221}
222
223//_____________________________________________________________________________
224void
225AliMpSlatZonePadIterator::Invalidate()
226{
227 //
228 // Invalidate the iterator.
229 //
230
231 fOffset = TVector2(DMAX,DMAX);
232 fCurrentPad = AliMpPad::Invalid();
233 fIsDone = kTRUE;
234}
235
236//_____________________________________________________________________________
237Bool_t
238AliMpSlatZonePadIterator::IsDone() const
239{
240 //
241 // Whether the iteration is finished or not.
242 //
243 return fIsDone;
244}
245
246//_____________________________________________________________________________
247void
248AliMpSlatZonePadIterator::Next()
249{
250 // This one is the meat of the class.
251 // We're iterating in x-direction mainly, starting from
252 // lower-left of the iteration area, and proceeding right,
253 // until we reach right border, in which case we increment y
254 // and go back to leftmost position.
255 // Put otherwise, here's basically how it should work:
256 // try to do x+=xstep. If outside the area, get back to xmin
257 // and try y+=ystep. If outside of the window end-of-game.
258 // When new x,y known, get the corresponding pad.
259 // If same pad as before (should not happen if step sizes are
260 // well chosen) or not valid pad (might happen for e.g. rounded pcbs),
261 // restart.
262 // End of iteration occurs when both x and y are outside the iteration
263 // window.
264
265 if (IsDone()) return;
266
267 AliMpPad pad(fCurrentPad);
268 int n = 0;
269 Double_t x(fOffset.X());
270 Double_t y(fOffset.Y());
271
272 while ( ( pad == fCurrentPad || !pad.IsValid() ) && n<100 )
273 {
274 ++n;
275 if (GetNextPosition(x,y)==kFALSE)
276 {
277 Invalidate();
278 return;
279 }
280 SetPad(pad,fArea.Position()+TVector2(x,y));
281 }
282 fCurrentPad = pad;
283}
284
285//_____________________________________________________________________________
286void
287AliMpSlatZonePadIterator::SetPad(AliMpPad& pad, const TVector2& pos)
288{
289 //
290 // Sets the current pad.
291 //
292 pad = fSlatSegmentation->PadByPosition(pos,kFALSE);
293 if ( pad.IsValid() )
294 {
295 // Reposition fOffset to pad center (only in x-direction).
296 fOffset.Set(pad.Position().X()+fkSlat->DX()-fArea.Position().X(),
297 fOffset.Y());
298 }
299}