From Laurent:
[u/mrichter/AliRoot.git] / MUON / AliMUONSt345SlatSegmentation.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
18 //*********************************************************
19 //  Segmentation classes for slat modules          
20 //  This class works with local coordinates
21 //  of the slats via the class AliMUONGeometrySegmentation
22 //  This class contains the size of the slats and the
23 //  and the differents PCB densities. 
24 //  (from old AliMUONSegmentationSlatModule)
25 //  Gines, Subatech, Nov04
26 //  Add electronics mapping
27 //  Christian, Subatech, Mai 05
28 //*********************************************************
29
30 #include <TArrayI.h>
31 #include <TArrayF.h>
32 #include "AliMUONSt345SlatSegmentation.h"
33 #include "AliMUONSegmentationDetectionElement.h"
34 #include "AliMUONSegmentManuIndex.h"
35 #include "AliMUONSegmentIndex.h"
36
37 #include "AliLog.h"
38
39 ClassImp(AliMUONSt345SlatSegmentation)
40
41
42 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation() 
43   :     AliMUONVGeometryDESegmentation(),
44         fBending(0),
45         fId(0),
46         fNsec(0),
47         fNDiv(0),
48         fDpxD(0),
49         fDpyD(0),
50         fDpx(0),
51         fDpy(0),
52         fNpx(999999),
53         fNpy(999999),
54         fWireD(0.0),
55         fXhit(0.),
56         fYhit(0.),
57         fIx(0),
58         fIy(0),
59         fX(0.),
60         fY(0.),
61         fIxmin(0),
62         fIxmax(0),
63         fIymin(0),
64         fIymax(0),
65         fInitDone(kFALSE),
66         fSegmentationDetectionElement(0x0)
67 {
68   // default constructor
69         AliDebug(1,Form("this=%p default (empty) ctor",this));
70 }
71
72 //___________________________________________
73 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(Bool_t bending) 
74   :     AliMUONVGeometryDESegmentation(),
75         fBending(bending),
76         fId(0),
77         fNsec(0),
78         fNDiv(0),
79         fDpxD(0),
80         fDpyD(0),
81         fDpx(0),
82         fDpy(0),
83         fNpx(999999),
84         fNpy(999999),
85         fWireD(0.25),
86         fXhit(0.),
87         fYhit(0.),
88         fIx(0),
89         fIy(0),
90         fX(0.),
91         fY(0.),
92         fIxmin(0),
93         fIxmax(0),
94         fIymin(0),
95         fIymax(0),
96         fInitDone(kFALSE),
97         fSegmentationDetectionElement(0x0)
98
99
100 {
101   // Non default constructor
102   fNsec = 4;  // 4 sector densities at most per slat 
103   fNDiv = new TArrayI(fNsec);      
104   fDpxD = new TArrayF(fNsec);      
105   fDpyD = new TArrayF(fNsec);      
106   (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;     
107   (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;       
108   (*fDpyD)[0]=(*fDpyD)[1]=(*fDpyD)[2]=(*fDpyD)[3]=0;   
109   AliDebug(1,Form("this=%p ctor for bending=%d",this,fBending)); 
110
111 }
112 //----------------------------------------------------------------------
113 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(const AliMUONSt345SlatSegmentation& rhs) 
114 :       AliMUONVGeometryDESegmentation(rhs),
115         fBending(0),
116         fId(0),
117         fDpx(0),
118         fDpy(0),
119         fNpx(999999),
120         fNpy(999999),
121         fWireD(0.25),
122         fXhit(0.),
123         fYhit(0.),
124         fIx(0),
125         fIy(0),
126         fX(0.),
127         fY(0.),
128         fIxmin(0),
129         fIxmax(0),
130         fIymin(0),
131         fIymax(0),
132         fSegmentationDetectionElement(0x0)
133 {
134                 AliFatal("Not implemented");
135 }
136 //----------------------------------------------------------------------
137 AliMUONSt345SlatSegmentation::~AliMUONSt345SlatSegmentation() 
138 {
139   // Destructor
140   delete fNDiv;
141   delete fDpxD;
142   delete fDpyD;
143 }
144 //----------------------------------------------------------------------
145 AliMUONSt345SlatSegmentation& AliMUONSt345SlatSegmentation::operator=(const AliMUONSt345SlatSegmentation& rhs)
146 {
147   // Protected assignement operator
148   if (this == &rhs) return *this;
149   AliFatal("Not implemented.");
150   return *this;  
151 }
152
153
154 //------------------------------------------------------------------------
155 Float_t AliMUONSt345SlatSegmentation::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t * /*dummy*/)
156 {
157   // Returns the square of the distance between 1 pad
158   // labelled by its Channel numbers and a coordinate
159   Float_t x,y;
160   GetPadC(iX,iY,x,y);
161   return (x-X)*(x-X) + (y-Y)*(y-Y);
162 }
163 //____________________________________________________________________________
164 Float_t AliMUONSt345SlatSegmentation::Dpx(Int_t isec) const
165 {
166   // Return x-strip width
167   return (*fDpxD)[isec];
168
169
170 //____________________________________________________________________________
171 Float_t AliMUONSt345SlatSegmentation::Dpy(Int_t  isec) const
172 {
173   // Return y-strip width
174   return (*fDpyD)[isec];
175 }
176 //_____________________________________________________________________________
177 Float_t AliMUONSt345SlatSegmentation::GetAnod(Float_t xhit) const
178 {
179   // Returns for a hit position xhit the position of the nearest anode wire    
180   Float_t wire= (xhit>0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5;
181   return fWireD*wire;
182 }
183
184 //_____________________________________________________________________________
185 Bool_t AliMUONSt345SlatSegmentation::HasPad(Int_t ix, Int_t iy)
186 {
187         if ( ix < 1 || ix > Npx() || iy < 1 || iy > Npy() )
188         {
189                 return kFALSE;
190         }
191         Int_t isec = Sector(ix,iy);
192         if ( isec == -1 )
193         {
194                 return kFALSE;
195         }
196         if ( iy > fNpyS[isec] )
197         {
198                 return kFALSE;
199         }
200         return kTRUE;
201 }
202
203 //--------------------------------------------------------------------------------
204 void AliMUONSt345SlatSegmentation::GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y) 
205 {
206   if (ix < 1 || ix > Npx() || iy < 1 || iy > Npy() ){
207     AliWarning(Form("ix %d or iy %d out of boundaries: Npx=%d and Npy=%d",ix, iy, Npx(), Npy()));
208     x = y= 0.;
209
210   } else { 
211
212     //  Returns real coordinates (x,y) for given pad coordinates (ix,iy)
213     //  Find sector isec
214     Int_t isec = Sector(ix,iy);
215     if (isec == -1) AliWarning(Form("isector = %d  with ix %d, iy %d", isec, ix, iy));
216     if (iy > fNpyS[isec]) {
217       x = y = 0.;
218       return;
219     }
220     if (isec>0) {
221       x = fCx[isec-1]+(ix-fNpxS[isec-1])*(*fDpxD)[isec];
222       x = x-(*fDpxD)[isec]/2;
223       y = Float_t(iy*(*fDpyD)[isec])-(*fDpyD)[isec]/2.- fCy;  // !!!  
224     } else {
225       x = y = 0;
226     }
227   }
228 }
229
230
231 //_____________________________________________________________________________
232 void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy) 
233 {
234 //  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
235
236   //  Find sector isec    
237   Int_t isec=-1;
238   for (Int_t i=fNsec-1; i > 0; i--) {
239     if (x >= fCx[i-1]) {
240       isec=i;
241       if (TMath::Abs(fCx[isec] - fCx[isec-1]) <0.1  && isec > 1) isec--;
242       break;
243     }
244   }
245   if (isec == -1) AliWarning(Form("isector equal to %d  with xl %f, yl %f", isec, x, y));
246   if (isec>0) {
247     ix= Int_t((x-fCx[isec-1])/(*fDpxD)[isec])
248       +fNpxS[isec-1]+1;
249     iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
250   } else if (isec == 0) {
251     ix= Int_t(x/(*fDpxD)[isec])+1;
252     iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
253   } else {
254     ix=0;
255     iy=0;
256   }
257 }
258 //-------------------------------------------------------------------------
259 void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
260 {
261   GetPadI(x, y, ix, iy);
262 }
263
264 //-------------------------------------------------------------------------
265 void AliMUONSt345SlatSegmentation::GetPadE(Int_t &ix, Int_t &iy,  AliMUONSegmentManuIndex* manuIndex)
266 {
267   //
268   // return Padx and Pady
269   // input value: electronic connection number
270
271   Int_t icathode = (fBending == 1) ? 0 : 1; // cathode 0 == bending
272
273   //  Int_t busPatchId     = manuIndex->GetBusPatchId(); //
274   Int_t manuId         = manuIndex->GetManuId();
275   Int_t manuChannelId  = manuIndex->GetManuChannelId();
276   //  Int_t channelId      = manuIndex->GetChannelId();
277
278   AliMUONSegmentIndex* index = fSegmentationDetectionElement->GetIndex(manuId,  manuChannelId);
279
280   ix = index->GetPadX();
281   iy = index->GetPadY();
282   swap(ix,iy); // swap cos origin in segmentation and mapping file are different for iy (temporary solution)
283
284   if (index->GetCathode() != icathode)
285     AliWarning("Wrong cathode number !");
286
287 }
288
289 //-------------------------------------------------------------------------
290  AliMUONSegmentManuIndex* AliMUONSt345SlatSegmentation::GetMpConnection(Int_t ix, Int_t iy)
291 {
292   //
293   // return electronic connection number
294   // input value: Padx and Pady
295
296   Int_t icathode = (fBending == 1) ? 0 : 1; // cathode 0 == bending
297
298   return fSegmentationDetectionElement->GetManuIndex(ix, iy, icathode);
299   
300 }
301
302 //_______________________________________________________________
303 void AliMUONSt345SlatSegmentation::SetPadDivision(Int_t ndiv[4])
304 {
305   // Defines the pad size perp. to the anode wire (y) for different sectors. 
306   // Pad sizes are defined as integral fractions ndiv of a basis pad size
307   // fDpx
308   // 
309   for (Int_t i=0; i<4; i++) {
310     (*fNDiv)[i]=ndiv[i];
311   }
312   ndiv[0]=ndiv[1];
313 }
314 //____________________________________________________________________________
315 void AliMUONSt345SlatSegmentation::SetPadSize(Float_t p1, Float_t p2)
316 {
317   //  Sets the padsize 
318   fDpx=p1;
319   fDpy=p2;
320 }
321 //_______________________________________________________________          
322 void AliMUONSt345SlatSegmentation::SetPcbBoards(Int_t n[4])
323 {
324   //
325   // Set PcbBoard segmentation zones for each density
326   // n[0] slat type parameter
327   // n[1] PcbBoards for highest density sector fNDiv[1] etc ...
328
329   fRtype = n[0];
330   n[0] = 0;
331   for (Int_t i=0; i<4; i++) fPcbBoards[i]=n[i];
332
333 }
334 //-------------------------------------------------------------------------
335 void AliMUONSt345SlatSegmentation::SetPad(Int_t ix, Int_t iy)
336 {
337   //
338   // Sets virtual pad coordinates, needed for evaluating pad response 
339   // outside the tracking program 
340   GetPadC(ix,iy,fX,fY);
341   fSector=Sector(ix,iy);
342 }
343 //---------------------------------------------------------------------------
344 void AliMUONSt345SlatSegmentation::SetHit(Float_t x, Float_t y)
345 {
346   // Set current hit 
347   //
348   fXhit = x;
349   fYhit = y;
350     
351   if (x <  fCx[0])    fXhit = fCx[0];
352   if (y < -fDyPCB/2.) fYhit = -fDyPCB/2.;
353     
354   if (x > fCx[fNsec-1]) fXhit = fCx[fNsec-1];
355   if (y > fDyPCB/2.)    fYhit = fDyPCB/2.;
356     
357 }
358 //----------------------------------------------------------------------------
359 void AliMUONSt345SlatSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
360 {
361   SetHit(xhit, yhit);
362 }
363
364 //----------------------------------------------------------
365 void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
366 {
367 // Initialises iteration over pads for charge distribution algorithm
368 //
369     //
370     // Find the wire position (center of charge distribution)
371     Float_t x0a = GetAnod(xhit);
372     fXhit = x0a;
373     fYhit = yhit;
374     //
375     // and take fNsigma*sigma around this center
376     Float_t x01 = x0a  - dx ;
377     Float_t x02 = x0a  + dx;
378     Float_t y01 = yhit - dy;
379     Float_t y02 = yhit + dy;
380
381     // check the limits after adding (fNsigma*sigma)
382     if (x01 <  fCx[0])   x01 =  fCx[0];
383     if (y01 < -fDyPCB/2) y01 = -fDyPCB/2;
384
385     if (x02 >= fCx[fNsec-1]) x02 = fCx[fNsec-1]; // still ok ? (CF)
386     if (y02 >= fDyPCB/2.) y02 = fDyPCB/2.;
387
388    
389     Int_t isec=-1;
390     for (Int_t i=fNsec-1; i > 0; i--) {
391       if (x02 >= fCx[i-1]) {
392         isec=i;
393         if (TMath::Abs(fCx[isec] - fCx[isec-1]) < 0.1 && isec > 1) isec--;
394         break;
395       }
396     }
397
398     //    y02 += Dpy(isec);// why ? (CF)
399    
400     //
401     // find the pads over which the charge distributes
402     GetPadI(x01,y01,fIxmin,fIymin);
403     GetPadI(x02,y02,fIxmax,fIymax);
404     
405     if (fIxmax > fNpx) fIxmax=fNpx;
406     if (fIymax > fNpyS[isec]) fIymax = fNpyS[isec];    
407     if (fIxmin < 1) fIxmin = 1;    // patch for the moment (Ch. Finck)
408     if (fIymin < 1) fIymin = 1;    
409
410     fXmin = x01;
411     fXmax = x02;    
412     fYmin = y01;
413     fYmax = y02;    
414   
415     // 
416     // Set current pad to lower left corner
417     if (fIxmax < fIxmin) fIxmax = fIxmin;
418     if (fIymax < fIymin) fIymax = fIymin;    
419     fIx = fIxmin;
420     fIy = fIymin;
421     
422     GetPadC(fIx,fIy,fX,fY);
423     fSector = Sector(fIx,fIy);
424  
425     AliDebug(4,Form("xhit,yhit,dx,dy=%e,%e,%e,%e ix,iy=%3d,%3d",
426                     xhit,yhit,dx,dy,fIx,fIy));
427 }
428
429 //----------------------------------------------------------------------
430 void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy)
431 {
432   FirstPad(xhit, yhit, dx, dy);
433 }
434 //----------------------------------------------------------------------
435 void AliMUONSt345SlatSegmentation::NextPad()
436 {
437   // Stepper for the iteration over pads
438   //
439   // Step to next pad in the integration region
440   //  step from left to right    
441   if (fIx != fIxmax) {
442     fIx++;
443     GetPadC(fIx,fIy,fX,fY);
444     fSector=Sector(fIx,fIy);
445     //  step up 
446   } else if (fIy != fIymax) {
447     fIx=fIxmin;
448     fIy++;
449     GetPadC(fIx,fIy,fX,fY);
450     fSector=Sector(fIx,fIy);
451   } else {
452     fIx=-999;
453     fIy=-999;
454   }
455 }
456 //-------------------------------------------------------------------------
457 Int_t AliMUONSt345SlatSegmentation::MorePads()
458 {
459   // Stopping condition for the iterator over pads
460   //
461   // Are there more pads in the integration region
462     
463   return  (fIx != -999  || fIy != -999);
464 }
465 //--------------------------------------------------------------------------
466 Int_t AliMUONSt345SlatSegmentation::Sector(Int_t ix, Int_t iy) 
467 {
468   //
469   // Determine segmentation zone from pad coordinates
470   //
471   Int_t isec = -1;
472   for (Int_t i = 0; i < fNsec; i++) {
473     if (ix <= fNpxS[i]) {
474       isec = i;
475       break;
476     }
477   }
478   if (isec == -1) AliWarning(Form("Sector = %d  with ix %d and iy %d, Npx %d",
479                                   isec, ix, iy, fNpx));
480
481   return isec;
482
483 }
484 //-----------------------------------------------------------------------------
485 void AliMUONSt345SlatSegmentation::
486 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) 
487 {
488   //  Returns integration limits for current pad
489   //
490   x1=fXhit-fX-Dpx(fSector)/2.;
491   x2=x1+Dpx(fSector);
492   y1=fYhit-fY-Dpy(fSector)/2.;
493   y2=y1+Dpy(fSector);    
494
495   AliDebug(4,Form("xhit,yhit=%e,%e x,y=%e,%e, x1,x2,y1,y2=%e,%e,%e,%e",fXhit,fYhit,fX,fY,x1,x2,y1,y2));
496
497 }
498 //-----------------------------------------------------------------------------
499 void AliMUONSt345SlatSegmentation::
500 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) 
501 {
502   // Returns list of next neighbours for given Pad (iX, iY)
503   Int_t i=0;
504   //  step right
505   if (iX+1 <= fNpx) {
506     Xlist[i]=iX+1;
507     Ylist[i++]=iY;
508   }
509   //  step left    
510   if (iX-1 > 0) {
511     Xlist[i]=iX-1;
512     Ylist[i++]=iY;
513   } 
514   Int_t sector = Sector(iX,iY);
515   //  step up
516   if (iY+1 <= fNpyS[sector]) {
517     Xlist[i]=iX;
518     Ylist[i++]=iY+1;
519   }
520   //  step down    
521   if (iY-1 > 0) {
522     Xlist[i]=iX;
523     Ylist[i++]=iY-1;
524   }
525   *Nlist=i;
526 }
527
528 //--------------------------------------------------------------------------
529 void AliMUONSt345SlatSegmentation::Init(Int_t detectionElementId)
530 {
531   //
532   //  Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
533   //  These arrays help in converting from real to pad co-ordinates and
534   //  vice versa
535   //   
536   //  Segmentation is defined by rectangular modules approximating
537   //  concentric circles as shown below
538   //
539   //  PCB module size in cm
540   //  printf("\n Initialise Segmentation SlatModule \n");
541
542   
543   //  printf(" fBending: %d \n",fBending);
544
545   if (fInitDone) return; // security if init is already done in AliMUONFactory
546   fDxPCB=40;
547   fDyPCB=40;
548
549   //  Calculate padsize along x
550   (*fDpxD)[fNsec-1]=fDpx;
551   (*fDpyD)[fNsec-1]=fDpy;
552   if (fNsec > 1) {
553     for (Int_t i=fNsec-1; i>=0; i--){ // fNsec-2
554       if (!fBending) {
555         (*fDpxD)[i]=fDpx;
556         (*fDpyD)[i]=(*fDpyD)[fNsec-1]/(*fNDiv)[i];
557       } else {
558         (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
559         (*fDpyD)[i]=fDpy;
560       }
561     }
562   }
563   //
564   // fill the arrays defining the pad segmentation boundaries
565   //
566   //  
567   //  Loop over sectors (isec=0 for secto close to the beam pipe)
568   Float_t totalLength = 0;
569   for (Int_t isec=0; isec<4; isec++) totalLength += fPcbBoards[isec]*fDxPCB;  // !!!!
570
571   fNpy = 0;   // maximum number of pads in y
572   for (Int_t isec=0; isec<4; isec++) {
573     if (isec==0) {
574       fNpxS[0] = 0;
575       fNpyS[0] = 0;
576       fCx[0]   = -totalLength/2;
577     } else {
578       fNpxS[isec] = fNpxS[isec-1] + fPcbBoards[isec]*Int_t(fDxPCB/(*fDpxD)[isec]+0.5); 
579       fNpyS[isec] = Int_t(fDyPCB/(*fDpyD)[isec]+0.5);
580       if (fNpyS[isec] >= fNpy) fNpy = fNpyS[isec]; 
581       fCx[isec]= fCx[isec-1] + fPcbBoards[isec]*fDxPCB;
582     }
583   } // sectors
584
585   fNpx = fNpxS[3];  // maximum number of pads in x
586   fCy = fDyPCB/2.;
587   //
588   fId = detectionElementId;
589
590   //
591   // initalize mapping
592   //
593 //   Int_t icathode = (fBending == 1) ? 0 : 1; // cathode 0 == bending
594 //   Char_t name[15];
595 //   GetMpFileName(name);
596 //   fSegmentationDetectionElement = new AliMUONSegmentationDetectionElement();
597 //   fSegmentationDetectionElement->Init(name, icathode);
598   fInitDone = kTRUE;
599 }
600
601 //--------------------------------------------------------------------------
602 void AliMUONSt345SlatSegmentation::GetMpFileName(Char_t* name) const
603 {
604   //
605   // Get mapping file name
606   //
607
608    strcpy(name,"slat");
609
610    for (Int_t isec = 1; isec < 4; isec++) {
611
612      switch(isec) {
613      case 1:
614        for (Int_t i = 0; i < fPcbBoards[isec]; i++)
615          strcat(name,"1");
616        break;
617      case 2 :
618        for (Int_t i = 0; i < fPcbBoards[isec]; i++)
619          strcat(name,"2");
620        break;
621      case 3:
622        for (Int_t i = 0; i < fPcbBoards[isec]; i++)
623          strcat(name,"3");
624        break;
625      }
626    }
627
628    while (strlen(name) < 10)
629      strcat(name,"0");
630    
631    switch(fRtype) {
632    case 0:
633      strcat(name, "N");
634      break;
635    case 1:
636      strcat(name, "NR1");
637      break;
638    case 2:
639      strcat(name, "NR2");
640      break;
641    case 3:
642      strcat(name, "NR3");
643      break;
644    case 4:
645      strcat(name, "S");
646      break;
647    case -1:
648      strcat(name, "SR1");
649      break;
650    case -2:
651      strcat(name, "SR2");
652      break;
653    case -3:
654      strcat(name, "SR3"); // should not exist
655      AliFatal("SR3 Slat type does not exist !!");
656      break;
657    }
658 }
659
660 //--------------------------------------------------------------------------
661 void AliMUONSt345SlatSegmentation::Swap(Int_t padX, Int_t &padY)
662 {
663
664   // swap the numbering between segmentation (i.e. pady = [0,40]) 
665   // and mapping file  (i.e. pady = [-20,20]) 
666
667
668   if (fBending == 1) {
669     if (padY < 0) 
670       padY += fNpy + 1; 
671     else
672       padY += fNpy; 
673   }
674
675
676   if (fBending == 0) {
677     if (padY < 0) 
678       padY += fNpyS[Sector(padX, padY)] + 1; 
679     else
680       padY += fNpyS[Sector(padX, padY)]; 
681   }
682
683 }
684
685