]>
Commit | Line | Data |
---|---|---|
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 | |
b80faac0 | 41 | using std::cout; |
42 | using std::endl; | |
618ea77a | 43 | /// \cond CLASSIMP |
44 | ClassImp(AliMpPCBPadIterator) | |
45 | /// \endcond | |
46 | ||
47 | //_____________________________________________________________________________ | |
48 | AliMpPCBPadIterator::AliMpPCBPadIterator(const AliMpSlat* slat, | |
168e9c4d | 49 | const AliMpArea& area) |
618ea77a | 50 | : AliMpVPadIterator(), |
51 | fkSlat(slat), | |
52 | fSlatSegmentation(new AliMpSlatSegmentation(slat)), | |
168e9c4d | 53 | fMinIndices(0), |
54 | fMaxIndices(0), | |
55 | fOffset(0), | |
618ea77a | 56 | fCurrentPad(), |
57 | fIsDone(kTRUE) | |
58 | { | |
71a2d3aa | 59 | /// |
60 | /// Normal ctor. | |
61 | /// Iteration will be done on the slat, over the crop of (area,slat_area) | |
62 | /// | |
618ea77a | 63 | if (!CropArea(area)) |
64 | { | |
65 | 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 | Invalidate(); | |
70 | } | |
71 | ||
72 | //_____________________________________________________________________________ | |
73 | AliMpPCBPadIterator::~AliMpPCBPadIterator() | |
74 | { | |
71a2d3aa | 75 | /// |
76 | /// Dtor. | |
77 | /// | |
618ea77a | 78 | delete fSlatSegmentation; |
79 | } | |
80 | ||
81 | //_____________________________________________________________________________ | |
82 | Bool_t | |
83 | AliMpPCBPadIterator::CropArea(const AliMpArea& area) | |
84 | { | |
71a2d3aa | 85 | /// |
86 | /// Checks the area is correct, and truncate it | |
87 | /// if it goes outside the slat. | |
618ea77a | 88 | |
89 | 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 | 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 | AliMpPCB* first = fkSlat->FindPCB(area.LeftBorder(),area.DownBorder()); | |
98 | AliMpPCB* last = fkSlat->FindPCB(area.RightBorder()-kEpsilon, | |
99 | area.DownBorder()); | |
100 | ||
101 | // Check we're indeed dealing with only one pcb | |
102 | if ( first != last ) | |
103 | { | |
104 | AliError("This iterator supposed to work on a single PCB. Please check"); | |
105 | return kFALSE; | |
106 | } | |
107 | ||
108 | AliDebug(3,Form("PCB %s Ixmin %2d Ixmax %2d", | |
109 | first->GetID(),first->Ixmin(),first->Ixmax())); | |
110 | ||
111 | Double_t xleft = first->ActiveXmin(); | |
112 | Double_t xright = first->ActiveXmax() - kEpsilon; | |
113 | ||
114 | AliDebug(3,Form("xleft,xright=%e,%e",xleft,xright)); | |
115 | ||
1b36647b | 116 | Double_t xmin = TMath::Max(area.LeftBorder(),xleft); |
117 | Double_t xmax = TMath::Min(area.RightBorder(),xright); | |
118 | Double_t ymin = TMath::Max(area.DownBorder(),0.0); | |
119 | Double_t ymax = TMath::Min(area.UpBorder(),first->DY()*2.0-kEpsilon); | |
618ea77a | 120 | |
121 | 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 | Int_t ixmin = first->Ixmin() + TMath::FloorNint((xmin-first->ActiveXmin())/first->PadSizeX()); | |
132 | Int_t ixmax = first->Ixmin() + TMath::CeilNint((xmax-first->ActiveXmin())/first->PadSizeX()) - 1; | |
133 | Int_t iymin = first->Iymin() + TMath::FloorNint((ymin-first->Ymin())/first->PadSizeY()); | |
134 | Int_t iymax = first->Iymin() + TMath::CeilNint((ymax-first->Ymin())/first->PadSizeY()) - 1; | |
135 | ||
136 | ||
168e9c4d | 137 | fMinIndices = AliMp::Pair(ixmin,iymin); |
138 | fMaxIndices = AliMp::Pair(ixmax,iymax); | |
618ea77a | 139 | |
140 | AliDebug(3,Form("Paddified cropped area (%d,%d)->(%d,%d) %d,%d ; %d,%d", | |
141 | ixmin,iymin,ixmax,iymax, | |
168e9c4d | 142 | AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices), |
143 | AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices))); | |
618ea77a | 144 | |
168e9c4d | 145 | return fMinIndices >= 0 && fMaxIndices >= 0; |
618ea77a | 146 | } |
147 | ||
148 | //_____________________________________________________________________________ | |
149 | AliMpPad | |
150 | AliMpPCBPadIterator::CurrentItem() const | |
151 | { | |
71a2d3aa | 152 | /// |
153 | /// Returns the current iteration position (i.e. a pad) | |
154 | /// | |
618ea77a | 155 | return fCurrentPad; |
156 | } | |
157 | ||
158 | //_____________________________________________________________________________ | |
159 | void | |
160 | AliMpPCBPadIterator::First() | |
161 | { | |
71a2d3aa | 162 | /// |
163 | /// (re)Starts the iteration. | |
164 | /// | |
618ea77a | 165 | |
166 | AliDebug(3,Form("area = (%d,%d)->(%d,%d)", | |
168e9c4d | 167 | AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices), |
168 | AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices))); | |
618ea77a | 169 | fOffset = fMinIndices; |
170 | fIsDone = kFALSE; | |
168e9c4d | 171 | SetPad(fCurrentPad,AliMp::PairFirst(fOffset),AliMp::PairSecond(fOffset)); |
172 | if ( ! fCurrentPad.IsValid() ) Next(); | |
173 | if ( ! fCurrentPad.IsValid() ) | |
618ea77a | 174 | { |
175 | // did not find any valid pad in there, bailing out. | |
176 | fIsDone = kTRUE; | |
177 | AliError(Form("Could not initiate iterator for slat %s. " | |
178 | " Please check the area you gave : %d,%d to %d,%d", | |
179 | fkSlat->GetName(), | |
168e9c4d | 180 | AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices), |
181 | AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices))); | |
618ea77a | 182 | return; |
183 | } | |
184 | } | |
185 | ||
186 | //_____________________________________________________________________________ | |
187 | Bool_t | |
9ee1d6ff | 188 | AliMpPCBPadIterator::GetNextPosition(Int_t& ix, Int_t& iy) const |
618ea77a | 189 | { |
71a2d3aa | 190 | /// Get the next iteration position. |
191 | /// On input, fOffset must be a valid position (i.e. within iteration | |
192 | /// area already). | |
618ea77a | 193 | |
194 | ++ix; | |
195 | ||
168e9c4d | 196 | if ( ix > AliMp::PairFirst(fMaxIndices) ) |
618ea77a | 197 | { |
618ea77a | 198 | // Go back leftmost position... |
168e9c4d | 199 | ix = AliMp::PairFirst(fMinIndices); |
618ea77a | 200 | // ... and up |
201 | ++iy; | |
168e9c4d | 202 | if ( iy > AliMp::PairSecond(fMaxIndices) ) |
618ea77a | 203 | { |
204 | return false; | |
205 | } | |
206 | } | |
207 | return true; | |
208 | } | |
209 | ||
210 | ||
211 | //_____________________________________________________________________________ | |
212 | void | |
213 | AliMpPCBPadIterator::Invalidate() | |
214 | { | |
71a2d3aa | 215 | /// |
216 | /// Invalidate the iterator. | |
217 | /// | |
168e9c4d | 218 | fOffset = 0; |
618ea77a | 219 | fCurrentPad = AliMpPad::Invalid(); |
220 | fIsDone = kTRUE; | |
221 | } | |
222 | ||
223 | //_____________________________________________________________________________ | |
224 | Bool_t | |
225 | AliMpPCBPadIterator::IsDone() const | |
226 | { | |
71a2d3aa | 227 | /// |
228 | /// Whether the iteration is finished or not. | |
229 | /// | |
618ea77a | 230 | return fIsDone; |
231 | } | |
232 | ||
233 | //_____________________________________________________________________________ | |
234 | void | |
235 | AliMpPCBPadIterator::Next() | |
236 | { | |
71a2d3aa | 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. | |
618ea77a | 244 | |
245 | if (IsDone()) return; | |
246 | ||
247 | AliMpPad pad(fCurrentPad); | |
248 | int n = 0; | |
168e9c4d | 249 | Int_t ix(AliMp::PairFirst(fOffset)); |
250 | Int_t iy(AliMp::PairSecond(fOffset)); | |
618ea77a | 251 | |
168e9c4d | 252 | while ( ( pad == fCurrentPad || ! pad.IsValid() ) && n<100 ) |
618ea77a | 253 | { |
254 | ++n; | |
255 | if (GetNextPosition(ix,iy)==kFALSE) | |
256 | { | |
257 | Invalidate(); | |
258 | return; | |
259 | } | |
168e9c4d | 260 | SetPad(pad,ix,iy); |
618ea77a | 261 | } |
262 | if ( n>=100 ) | |
263 | { | |
264 | AliFatal("This should not happen!"); | |
265 | } | |
266 | fCurrentPad = pad; | |
267 | } | |
268 | ||
269 | //_____________________________________________________________________________ | |
270 | void | |
271 | AliMpPCBPadIterator::Print(Option_t*) const | |
272 | { | |
273 | /// printout | |
274 | cout << Form("fkSlat=%p fSlatSegmentation=%p (%s)",fkSlat,fSlatSegmentation, | |
275 | fkSlat->GetName()) << endl | |
276 | << Form("minIndices=(%d,%d) maxIndices=(%d,%d)", | |
168e9c4d | 277 | AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices), |
278 | AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices)) << endl | |
618ea77a | 279 | << Form("currentOffset=(%d,%d) isdone=%d currentpad=", |
1130977f | 280 | AliMp::PairFirst(fOffset),AliMp::PairSecond(fOffset),fIsDone) << endl; |
618ea77a | 281 | fCurrentPad.Print(); |
282 | } | |
283 | ||
284 | //_____________________________________________________________________________ | |
285 | void | |
168e9c4d | 286 | AliMpPCBPadIterator::SetPad(AliMpPad& pad, Int_t ix, Int_t iy) |
618ea77a | 287 | { |
71a2d3aa | 288 | /// |
289 | /// Sets the current pad. | |
290 | /// | |
168e9c4d | 291 | pad = fSlatSegmentation->PadByIndices(ix, iy,kFALSE); |
618ea77a | 292 | if (pad.IsValid()) |
293 | { | |
168e9c4d | 294 | fOffset = AliMp::Pair(ix,iy); |
618ea77a | 295 | } |
296 | } |