]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONSt345SlatSegmentation.cxx
Separating writing and reading of raw data (Christian)
[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 "AliLog.h"
34
35 ClassImp(AliMUONSt345SlatSegmentation)
36
37
38 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation() 
39   :     AliMUONVGeometryDESegmentation(),
40         fBending(0),
41         fId(0),
42         fNsec(0),
43         fNDiv(0),
44         fDpxD(0),
45         fDpyD(0),
46         fDpx(0),
47         fDpy(0),
48         fNpx(999999),
49         fNpy(999999),
50         fWireD(0.0),
51         fXhit(0.),
52         fYhit(0.),
53         fIx(0),
54         fIy(0),
55         fX(0.),
56         fY(0.),
57         fIxmin(0),
58         fIxmax(0),
59         fIymin(0),
60         fIymax(0),
61         fInitDone(kFALSE)
62 {
63   // default constructor
64         AliDebug(1,Form("this=%p default (empty) ctor",this));
65 }
66
67 //___________________________________________
68 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(Bool_t bending) 
69   :     AliMUONVGeometryDESegmentation(),
70         fBending(bending),
71         fId(0),
72         fNsec(0),
73         fNDiv(0),
74         fDpxD(0),
75         fDpyD(0),
76         fDpx(0),
77         fDpy(0),
78         fNpx(999999),
79         fNpy(999999),
80         fWireD(0.25),
81         fXhit(0.),
82         fYhit(0.),
83         fIx(0),
84         fIy(0),
85         fX(0.),
86         fY(0.),
87         fIxmin(0),
88         fIxmax(0),
89         fIymin(0),
90         fIymax(0),
91         fInitDone(kFALSE)
92
93 {
94   // Non default constructor
95   fNsec = 4;  // 4 sector densities at most per slat 
96   fNDiv = new TArrayI(fNsec);      
97   fDpxD = new TArrayF(fNsec);      
98   fDpyD = new TArrayF(fNsec);      
99   (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;     
100   (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;       
101   (*fDpyD)[0]=(*fDpyD)[1]=(*fDpyD)[2]=(*fDpyD)[3]=0;   
102   AliDebug(1,Form("this=%p ctor for bending=%d",this,fBending)); 
103
104 }
105 //----------------------------------------------------------------------
106 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(const AliMUONSt345SlatSegmentation& rhs) 
107 :       AliMUONVGeometryDESegmentation(rhs),
108         fBending(0),
109         fId(0),
110         fDpx(0),
111         fDpy(0),
112         fNpx(999999),
113         fNpy(999999),
114         fWireD(0.25),
115         fXhit(0.),
116         fYhit(0.),
117         fIx(0),
118         fIy(0),
119         fX(0.),
120         fY(0.),
121         fIxmin(0),
122         fIxmax(0),
123         fIymin(0),
124         fIymax(0)
125 {
126                 AliFatal("Not implemented");
127 }
128 //----------------------------------------------------------------------
129 AliMUONSt345SlatSegmentation::~AliMUONSt345SlatSegmentation() 
130 {
131   // Destructor
132
133   AliDebug(1, Form("dtor this = %p", this));
134
135   delete fNDiv;
136   delete fDpxD;
137   delete fDpyD;
138 }
139 //----------------------------------------------------------------------
140 AliMUONSt345SlatSegmentation& AliMUONSt345SlatSegmentation::operator=(const AliMUONSt345SlatSegmentation& rhs)
141 {
142   // Protected assignement operator
143   if (this == &rhs) return *this;
144   AliFatal("Not implemented.");
145   return *this;  
146 }
147
148
149 //------------------------------------------------------------------------
150 Float_t AliMUONSt345SlatSegmentation::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t * /*dummy*/)
151 {
152   // Returns the square of the distance between 1 pad
153   // labelled by its Channel numbers and a coordinate
154   Float_t x,y;
155   GetPadC(iX,iY,x,y);
156   return (x-X)*(x-X) + (y-Y)*(y-Y);
157 }
158 //____________________________________________________________________________
159 Float_t AliMUONSt345SlatSegmentation::Dpx(Int_t isec) const
160 {
161   // Return x-strip width
162   return (*fDpxD)[isec];
163
164
165 //____________________________________________________________________________
166 Float_t AliMUONSt345SlatSegmentation::Dpy(Int_t  isec) const
167 {
168   // Return y-strip width
169   return (*fDpyD)[isec];
170 }
171 //_____________________________________________________________________________
172 Float_t AliMUONSt345SlatSegmentation::GetAnod(Float_t xhit) const
173 {
174   // Returns for a hit position xhit the position of the nearest anode wire    
175   Float_t wire= (xhit>0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5;
176   return fWireD*wire;
177 }
178
179 //_____________________________________________________________________________
180 Bool_t AliMUONSt345SlatSegmentation::HasPad(Int_t ix, Int_t iy)
181 {
182         if ( ix < 1 || ix > Npx() || iy < 1 || iy > Npy() )
183         {
184                 return kFALSE;
185         }
186         Int_t isec = Sector(ix,iy);
187         if ( isec == -1 )
188         {
189                 return kFALSE;
190         }
191         if ( iy > fNpyS[isec] )
192         {
193                 return kFALSE;
194         }
195         return kTRUE;
196 }
197
198 //--------------------------------------------------------------------------------
199 void AliMUONSt345SlatSegmentation::GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y) 
200 {
201   if (ix < 1 || ix > Npx() || iy < 1 || iy > Npy() ){
202     AliWarning(Form("ix %d or iy %d out of boundaries: Npx=%d and Npy=%d",ix, iy, Npx(), Npy()));
203     x = y= 0.;
204
205   } else { 
206
207     //  Returns real coordinates (x,y) for given pad coordinates (ix,iy)
208     //  Find sector isec
209     Int_t isec = Sector(ix,iy);
210     if (isec == -1) AliWarning(Form("isector = %d  with ix %d, iy %d", isec, ix, iy));
211     if (iy > fNpyS[isec]) {
212       x = y = 0.;
213       return;
214     }
215     if (isec>0) {
216       x = fCx[isec-1]+(ix-fNpxS[isec-1])*(*fDpxD)[isec];
217       x = x-(*fDpxD)[isec]/2;
218       y = Float_t(iy*(*fDpyD)[isec])-(*fDpyD)[isec]/2.- fCy;  // !!!  
219     } else {
220       x = y = 0;
221     }
222   }
223 }
224
225
226 //_____________________________________________________________________________
227 void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy) 
228 {
229 //  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
230
231   //  Find sector isec    
232   Int_t isec=-1;
233   for (Int_t i=fNsec-1; i > 0; i--) {
234     if (x >= fCx[i-1]) {
235       isec=i;
236       if (TMath::Abs(fCx[isec] - fCx[isec-1]) <0.1  && isec > 1) isec--;
237       break;
238     }
239   }
240   if (isec == -1) AliWarning(Form("isector equal to %d  with xl %f, yl %f", isec, x, y));
241   if (isec>0) {
242     ix= Int_t((x-fCx[isec-1])/(*fDpxD)[isec])
243       +fNpxS[isec-1]+1;
244     iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
245   } else if (isec == 0) {
246     ix= Int_t(x/(*fDpxD)[isec])+1;
247     iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
248   } else {
249     ix=0;
250     iy=0;
251   }
252 }
253 //-------------------------------------------------------------------------
254 void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
255 {
256   GetPadI(x, y, ix, iy);
257 }
258
259
260 //_______________________________________________________________
261 void AliMUONSt345SlatSegmentation::SetPadDivision(Int_t ndiv[4])
262 {
263   // Defines the pad size perp. to the anode wire (y) for different sectors. 
264   // Pad sizes are defined as integral fractions ndiv of a basis pad size
265   // fDpx
266   // 
267   for (Int_t i=0; i<4; i++) {
268     (*fNDiv)[i]=ndiv[i];
269   }
270   ndiv[0]=ndiv[1];
271 }
272 //____________________________________________________________________________
273 void AliMUONSt345SlatSegmentation::SetPadSize(Float_t p1, Float_t p2)
274 {
275   //  Sets the padsize 
276   fDpx=p1;
277   fDpy=p2;
278 }
279 //_______________________________________________________________          
280 void AliMUONSt345SlatSegmentation::SetPcbBoards(Int_t n[4])
281 {
282   //
283   // Set PcbBoard segmentation zones for each density
284   // n[0] slat type parameter
285   // n[1] PcbBoards for highest density sector fNDiv[1] etc ...
286
287   fRtype = n[0];
288   n[0] = 0;
289   for (Int_t i=0; i<4; i++) fPcbBoards[i]=n[i];
290
291 }
292 //-------------------------------------------------------------------------
293 void AliMUONSt345SlatSegmentation::SetPad(Int_t ix, Int_t iy)
294 {
295   //
296   // Sets virtual pad coordinates, needed for evaluating pad response 
297   // outside the tracking program 
298   GetPadC(ix,iy,fX,fY);
299   fSector=Sector(ix,iy);
300 }
301 //---------------------------------------------------------------------------
302 void AliMUONSt345SlatSegmentation::SetHit(Float_t x, Float_t y)
303 {
304   // Set current hit 
305   //
306   fXhit = x;
307   fYhit = y;
308     
309   if (x <  fCx[0])    fXhit = fCx[0];
310   if (y < -fDyPCB/2.) fYhit = -fDyPCB/2.;
311     
312   if (x > fCx[fNsec-1]) fXhit = fCx[fNsec-1];
313   if (y > fDyPCB/2.)    fYhit = fDyPCB/2.;
314     
315 }
316 //----------------------------------------------------------------------------
317 void AliMUONSt345SlatSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
318 {
319   SetHit(xhit, yhit);
320 }
321
322 //----------------------------------------------------------
323 void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
324 {
325 // Initialises iteration over pads for charge distribution algorithm
326 //
327     //
328     // Find the wire position (center of charge distribution)
329     Float_t x0a = GetAnod(xhit);
330     fXhit = x0a;
331     fYhit = yhit;
332     //
333     // and take fNsigma*sigma around this center
334     Float_t x01 = x0a  - dx ;
335     Float_t x02 = x0a  + dx;
336     Float_t y01 = yhit - dy;
337     Float_t y02 = yhit + dy;
338
339     // check the limits after adding (fNsigma*sigma)
340     if (x01 <  fCx[0])   x01 =  fCx[0];
341     if (y01 < -fDyPCB/2) y01 = -fDyPCB/2;
342
343     if (x02 >= fCx[fNsec-1]) x02 = fCx[fNsec-1]; // still ok ? (CF)
344     if (y02 >= fDyPCB/2.) y02 = fDyPCB/2.;
345
346    
347     Int_t isec=-1;
348     for (Int_t i=fNsec-1; i > 0; i--) {
349       if (x02 >= fCx[i-1]) {
350         isec=i;
351         if (TMath::Abs(fCx[isec] - fCx[isec-1]) < 0.1 && isec > 1) isec--;
352         break;
353       }
354     }
355
356     //    y02 += Dpy(isec);// why ? (CF)
357    
358     //
359     // find the pads over which the charge distributes
360     GetPadI(x01,y01,fIxmin,fIymin);
361     GetPadI(x02,y02,fIxmax,fIymax);
362     
363     if (fIxmax > fNpx) fIxmax=fNpx;
364     if (fIymax > fNpyS[isec]) fIymax = fNpyS[isec];    
365     if (fIxmin < 1) fIxmin = 1;    // patch for the moment (Ch. Finck)
366     if (fIymin < 1) fIymin = 1;    
367
368     fXmin = x01;
369     fXmax = x02;    
370     fYmin = y01;
371     fYmax = y02;    
372   
373     // 
374     // Set current pad to lower left corner
375     if (fIxmax < fIxmin) fIxmax = fIxmin;
376     if (fIymax < fIymin) fIymax = fIymin;    
377     fIx = fIxmin;
378     fIy = fIymin;
379     
380     GetPadC(fIx,fIy,fX,fY);
381     fSector = Sector(fIx,fIy);
382  
383     AliDebug(4,Form("xhit,yhit,dx,dy=%e,%e,%e,%e ix,iy=%3d,%3d",
384                     xhit,yhit,dx,dy,fIx,fIy));
385 }
386
387 //----------------------------------------------------------------------
388 void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy)
389 {
390   FirstPad(xhit, yhit, dx, dy);
391 }
392 //----------------------------------------------------------------------
393 void AliMUONSt345SlatSegmentation::NextPad()
394 {
395   // Stepper for the iteration over pads
396   //
397   // Step to next pad in the integration region
398   //  step from left to right    
399   if (fIx != fIxmax) {
400     fIx++;
401     GetPadC(fIx,fIy,fX,fY);
402     fSector=Sector(fIx,fIy);
403     //  step up 
404   } else if (fIy != fIymax) {
405     fIx=fIxmin;
406     fIy++;
407     GetPadC(fIx,fIy,fX,fY);
408     fSector=Sector(fIx,fIy);
409   } else {
410     fIx=-999;
411     fIy=-999;
412   }
413 }
414 //-------------------------------------------------------------------------
415 Int_t AliMUONSt345SlatSegmentation::MorePads()
416 {
417   // Stopping condition for the iterator over pads
418   //
419   // Are there more pads in the integration region
420     
421   return  (fIx != -999  || fIy != -999);
422 }
423 //--------------------------------------------------------------------------
424 Int_t AliMUONSt345SlatSegmentation::Sector(Int_t ix, Int_t iy) 
425 {
426   //
427   // Determine segmentation zone from pad coordinates
428   //
429   Int_t isec = -1;
430   for (Int_t i = 0; i < fNsec; i++) {
431     if (ix <= fNpxS[i]) {
432       isec = i;
433       break;
434     }
435   }
436   if (isec == -1) AliWarning(Form("Sector = %d  with ix %d and iy %d, Npx %d",
437                                   isec, ix, iy, fNpx));
438
439   return isec;
440
441 }
442 //-----------------------------------------------------------------------------
443 void AliMUONSt345SlatSegmentation::
444 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) 
445 {
446   //  Returns integration limits for current pad
447   //
448   x1=fXhit-fX-Dpx(fSector)/2.;
449   x2=x1+Dpx(fSector);
450   y1=fYhit-fY-Dpy(fSector)/2.;
451   y2=y1+Dpy(fSector);    
452
453   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));
454
455 }
456 //-----------------------------------------------------------------------------
457 void AliMUONSt345SlatSegmentation::
458 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) 
459 {
460   // Returns list of next neighbours for given Pad (iX, iY)
461   Int_t i=0;
462   //  step right
463   if (iX+1 <= fNpx) {
464     Xlist[i]=iX+1;
465     Ylist[i++]=iY;
466   }
467   //  step left    
468   if (iX-1 > 0) {
469     Xlist[i]=iX-1;
470     Ylist[i++]=iY;
471   } 
472   Int_t sector = Sector(iX,iY);
473   //  step up
474   if (iY+1 <= fNpyS[sector]) {
475     Xlist[i]=iX;
476     Ylist[i++]=iY+1;
477   }
478   //  step down    
479   if (iY-1 > 0) {
480     Xlist[i]=iX;
481     Ylist[i++]=iY-1;
482   }
483   *Nlist=i;
484 }
485
486 //--------------------------------------------------------------------------
487 void AliMUONSt345SlatSegmentation::Init(Int_t detectionElementId)
488 {
489   //
490   //  Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
491   //  These arrays help in converting from real to pad co-ordinates and
492   //  vice versa
493   //   
494   //  Segmentation is defined by rectangular modules approximating
495   //  concentric circles as shown below
496   //
497   //  PCB module size in cm
498   //  printf("\n Initialise Segmentation SlatModule \n");
499
500   
501   //  printf(" fBending: %d \n",fBending);
502
503   if (fInitDone) return; // security if init is already done in AliMUONFactory
504   fDxPCB=40;
505   fDyPCB=40;
506
507   //  Calculate padsize along x
508   (*fDpxD)[fNsec-1]=fDpx;
509   (*fDpyD)[fNsec-1]=fDpy;
510   if (fNsec > 1) {
511     for (Int_t i=fNsec-1; i>=0; i--){ // fNsec-2
512       if (!fBending) {
513         (*fDpxD)[i]=fDpx;
514         (*fDpyD)[i]=(*fDpyD)[fNsec-1]/(*fNDiv)[i];
515       } else {
516         (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
517         (*fDpyD)[i]=fDpy;
518       }
519     }
520   }
521   //
522   // fill the arrays defining the pad segmentation boundaries
523   //
524   //  
525   //  Loop over sectors (isec=0 for secto close to the beam pipe)
526   Float_t totalLength = 0;
527   for (Int_t isec=0; isec<4; isec++) totalLength += fPcbBoards[isec]*fDxPCB;  // !!!!
528
529   fNpy = 0;   // maximum number of pads in y
530   for (Int_t isec=0; isec<4; isec++) {
531     if (isec==0) {
532       fNpxS[0] = 0;
533       fNpyS[0] = 0;
534       fCx[0]   = -totalLength/2;
535     } else {
536       fNpxS[isec] = fNpxS[isec-1] + fPcbBoards[isec]*Int_t(fDxPCB/(*fDpxD)[isec]+0.5); 
537       fNpyS[isec] = Int_t(fDyPCB/(*fDpyD)[isec]+0.5);
538       if (fNpyS[isec] >= fNpy) fNpy = fNpyS[isec]; 
539       fCx[isec]= fCx[isec-1] + fPcbBoards[isec]*fDxPCB;
540     }
541   } // sectors
542
543   fNpx = fNpxS[3];  // maximum number of pads in x
544   fCy = fDyPCB/2.;
545   //
546   fId = detectionElementId;
547
548   fInitDone = kTRUE;
549 }