]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/mapping/AliMpPCBPadIterator.cxx
Update manu serial number files (Christian)
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpPCBPadIterator.cxx
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
39 ClassImp(AliMpPCBPadIterator)
40 /// \endcond
41
42 //_____________________________________________________________________________
43 AliMpPCBPadIterator::AliMpPCBPadIterator(const AliMpSlat* slat,
44                                                      const AliMpArea& area)
45 : AliMpVPadIterator(),
46 fkSlat(slat),
47 fSlatSegmentation(new AliMpSlatSegmentation(slat)),
48 fMinIndices(),
49 fMaxIndices(),
50 fOffset(0,0),
51 fCurrentPad(),
52 fIsDone(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 //_____________________________________________________________________________
68 AliMpPCBPadIterator::~AliMpPCBPadIterator()
69 {
70   //
71   // Dtor.
72   //
73   delete fSlatSegmentation;
74 }
75
76 //_____________________________________________________________________________
77 Bool_t
78 AliMpPCBPadIterator::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   
111   Double_t xmin = std::max(area.LeftBorder(),xleft);
112   Double_t xmax = std::min(area.RightBorder(),xright);
113   Double_t ymin = std::max(area.DownBorder(),0.0);
114   Double_t ymax = std::min(area.UpBorder(),first->DY()*2.0-kEpsilon);
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 //_____________________________________________________________________________
144 AliMpPad
145 AliMpPCBPadIterator::CurrentItem() const
146 {
147   //
148   // Returns the current iteration position (i.e. a pad)
149   //
150   return fCurrentPad;
151 }
152
153 //_____________________________________________________________________________
154 void
155 AliMpPCBPadIterator::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 //_____________________________________________________________________________
184 Bool_t
185 AliMpPCBPadIterator::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   {
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 //_____________________________________________________________________________
209 void
210 AliMpPCBPadIterator::Invalidate()
211 {
212   //
213   // Invalidate the iterator.
214   //
215   fOffset = AliMpIntPair::Invalid();
216   fCurrentPad = AliMpPad::Invalid();
217   fIsDone = kTRUE;
218 }
219
220 //_____________________________________________________________________________
221 Bool_t
222 AliMpPCBPadIterator::IsDone() const
223 {
224   //
225   // Whether the iteration is finished or not.
226   //
227   return fIsDone;
228 }
229
230 //_____________________________________________________________________________
231 void
232 AliMpPCBPadIterator::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 //_____________________________________________________________________________
267 void 
268 AliMpPCBPadIterator::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 //_____________________________________________________________________________
282 void
283 AliMpPCBPadIterator::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 }