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