Chip number information added to segmentation mother class and to SDD segmentation...
[u/mrichter/AliRoot.git] / ITS / AliITSsegmentationSDD.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 #include <Riostream.h>
16 #include <TMath.h>
17
18 #include "AliITSsegmentationSDD.h"
19 #include "AliITSgeomSDD.h"
20 #include "AliITSresponseSDD.h"
21
22 /////////////////////////////////////////////////////////////////////////////
23 // Segmentation class for drift detectors                                  //
24 //                                                                         //
25 //     microcables                                  microcables            //
26 //       /\                                           /\                   //
27 //       ||                                           ||                   //
28 //       ||                                           ||                   //
29 //       ||                                           ||                   //
30 //        0                     256                    0                   //
31 //      0 |----------------------|---------------------| 511               //
32 //        |       time-bins      |     time-bins       |                   //
33 //        | a                    |                   a |                   //
34 //        | n                    |                   n |                   //
35 //    X <_|_o____________________|___________________o_|__                 //
36 //        | d                    |                   d |                   //
37 //        | e     LEFT SIDE      |   RIGHT SIDE      e |                   //
38 //        | s     CHANNEL 0      |   CHANNEL 1       s |                   //
39 //        |       Xlocal > 0     |   Xlocal < 0        |                   //
40 //    255 |----------------------|---------------------| 256               //
41 //                               |                                         //
42 //                               |                                         //
43 //                               V                                         //
44 //                               Z                                         //
45 /////////////////////////////////////////////////////////////////////////////
46
47 const Float_t AliITSsegmentationSDD::fgkDxDefault = 35085.;
48 const Float_t AliITSsegmentationSDD::fgkDzDefault = 75264.;
49 const Float_t AliITSsegmentationSDD::fgkDyDefault = 300.;
50 const Float_t AliITSsegmentationSDD::fgkPitchDefault = 294.;
51 const Float_t AliITSsegmentationSDD::fgkClockDefault = 40.;
52 const Int_t AliITSsegmentationSDD::fgkHalfNanodesDefault = 256; 
53 const Int_t AliITSsegmentationSDD::fgkNsamplesDefault = 256;
54 const Int_t AliITSsegmentationSDD::fgkNchipsPerHybrid = 4;
55 const Int_t AliITSsegmentationSDD::fgkNanodesPerChip = 64;
56 const Float_t AliITSsegmentationSDD::fgkCm2Micron = 10000.;
57 const Float_t AliITSsegmentationSDD::fgkMicron2Cm = 1.0E-04;
58 ClassImp(AliITSsegmentationSDD)
59 //----------------------------------------------------------------------
60 AliITSsegmentationSDD::AliITSsegmentationSDD(AliITSgeom* geom):
61 AliITSsegmentation(),
62 fNsamples(0),
63 fNanodes(0),
64 fPitch(0),
65 fTimeStep(0),
66 fDriftSpeed(0),
67 fSetDriftSpeed(0){
68   // constructor
69   InitFromGeom(geom);
70 }
71 //______________________________________________________________________
72 AliITSsegmentationSDD::AliITSsegmentationSDD() : AliITSsegmentation(),
73 fNsamples(0),
74 fNanodes(0),
75 fPitch(0),
76 fTimeStep(0),
77 fDriftSpeed(0),
78 fSetDriftSpeed(0){
79   // Default constructor
80   Init();
81 }
82
83 //______________________________________________________________________
84 void AliITSsegmentationSDD::Copy(TObject &obj) const {
85   // protected method. copy this to obj
86   AliITSsegmentation::Copy(obj);
87   ((AliITSsegmentationSDD& ) obj).fNsamples = fNsamples;
88   ((AliITSsegmentationSDD& ) obj).fNanodes = fNanodes;
89   ((AliITSsegmentationSDD& ) obj).fPitch = fPitch;
90   ((AliITSsegmentationSDD& ) obj).fTimeStep = fTimeStep;
91   ((AliITSsegmentationSDD& ) obj).fDriftSpeed = fDriftSpeed;
92   ((AliITSsegmentationSDD& ) obj).fSetDriftSpeed = fSetDriftSpeed;
93 }
94
95 //______________________________________________________________________
96 AliITSsegmentationSDD& AliITSsegmentationSDD::operator=(const AliITSsegmentationSDD &source){
97    // = operator
98    if(this==&source) return *this;
99    source.Copy(*this);
100    return *this;
101 }
102
103 //____________________________________________________________________________
104 AliITSsegmentationSDD::AliITSsegmentationSDD(const AliITSsegmentationSDD &source) :
105     AliITSsegmentation(source),
106 fNsamples(0),
107 fNanodes(0),
108 fPitch(0),
109 fTimeStep(0),
110 fDriftSpeed(0),
111 fSetDriftSpeed(0){
112   // copy constructor
113   source.Copy(*this);
114 }
115
116 //----------------------------------------------------------------------
117 void AliITSsegmentationSDD::Init(){
118 // Standard initilisation routine
119    fDriftSpeed=AliITSresponseSDD::DefaultDriftSpeed();
120    fCorr=0;
121    SetDetSize(fgkDxDefault,fgkDzDefault,fgkDyDefault);
122    SetPadSize(fgkPitchDefault,fgkClockDefault);
123    SetNPads(fgkHalfNanodesDefault,fgkNsamplesDefault);
124 }
125 //----------------------------------------------------------------------
126 void AliITSsegmentationSDD::InitFromGeom(AliITSgeom *geom){
127 // Inizialization from geometry
128   Init();
129   if(!geom) {
130     AliFatal("Pointer to ITS geometry class (AliITSgeom) is null\n");
131     return;
132   }
133   AliITSgeomSDD *gsdd = (AliITSgeomSDD *) (geom->GetShape(3,1,1));
134   
135   fDz = 2.*fgkCm2Micron*gsdd->GetDz();
136   fDx = fgkCm2Micron*gsdd->GetDx();
137   fDy = 2.*fgkCm2Micron*gsdd->GetDy();
138  
139 }
140
141 //----------------------------------------------------------------------
142 void AliITSsegmentationSDD::
143 Neighbours(Int_t iX, Int_t iZ, Int_t* Nlist, Int_t Xlist[8], Int_t Zlist[8]) const {
144   // returns neighbours for use in Cluster Finder routines and the like
145
146     if(iX >= fNanodes) printf("iX > fNanodes %d %d\n",iX,fNanodes);
147     if(iZ >= fNsamples) printf("iZ > fNsamples %d %d\n",iZ,fNsamples);
148     *Nlist=4;
149     Xlist[0]=Xlist[1]=iX;
150     if(iX && (iX != fNanodes/2)) Xlist[2]=iX-1;
151     else Xlist[2]=iX;
152     if ((iX !=fNanodes/2 -1) && (iX != fNanodes)) Xlist[3]=iX+1;
153     else Xlist[3]=iX;
154     if(iZ) Zlist[0]=iZ-1;
155     else Zlist[0]=iZ;
156     if (iZ < fNsamples) Zlist[1]=iZ+1;
157     else Zlist[1]=iZ;
158     Zlist[2]=Zlist[3]=iZ;
159 }
160 //----------------------------------------------------------------------
161 Float_t AliITSsegmentationSDD::GetAnodeFromLocal(Float_t xloc,Float_t zloc) const {
162   // returns anode coordinate (as float) starting from local coordinates
163   Float_t xAnode=zloc*fgkCm2Micron/fPitch;
164   if(xloc>0){   // left side (anodes 0-255, anode 0 at zloc<0)
165     xAnode+=(Float_t)fNanodes/4;
166   }else{ // right side (anodes 256-511, anode 0 at zloc>0)
167     xAnode=3*fNanodes/4-xAnode;
168   }
169   return xAnode;
170 }
171
172 //----------------------------------------------------------------------
173 Float_t AliITSsegmentationSDD::GetLocalZFromAnode(Int_t nAnode) const{
174   // returns local Z coordinate from anode number (integer)
175   Float_t zAnode=(Float_t)nAnode+0.5;
176   return GetLocalZFromAnode(zAnode);
177 }
178
179 //----------------------------------------------------------------------
180 Float_t AliITSsegmentationSDD::GetLocalZFromAnode(Float_t zAnode) const{
181   // returns local Z coordinate from anode number (float)
182   Float_t zloc=0.;
183   if(zAnode<fNanodes/2){ // left side
184     zloc=(zAnode*fPitch-fDz/2)*fgkMicron2Cm;
185   }else{  // right side
186     zAnode-=fNanodes/2;
187     zloc=-(zAnode*fPitch-fDz/2)*fgkMicron2Cm;
188   }
189   return zloc;
190 }
191 //----------------------------------------------------------------------
192 Int_t AliITSsegmentationSDD::GetChipFromChannel(Int_t ix, Int_t iz) const {
193   if(iz>=fNanodes  || iz<0 || ix>fNsamples){
194     AliError("Bad cell number");
195     return -1;
196   }
197   Int_t theChip=iz/fgkNanodesPerChip;
198   return theChip;
199 }
200 //----------------------------------------------------------------------
201 Int_t AliITSsegmentationSDD::GetChipFromLocal(Float_t xloc, Float_t zloc) const {  
202   Float_t detsize=fDz*fgkMicron2Cm;
203   Float_t chipsize=detsize/(Float_t)fgkNchipsPerHybrid;
204   zloc+=detsize/2.;
205   if(zloc<-0.01 || zloc>detsize+0.01){ // 100 micron tolerance around edges
206     AliError("Z local value out of sensitive SDD area");
207     return -1;
208   }
209   Int_t iChip=int(zloc/chipsize);
210   if(zloc<0.) iChip=0;  
211   if(zloc>=detsize) iChip=fgkNchipsPerHybrid-1;
212   if(iChip>=fgkNchipsPerHybrid || iChip<0){ 
213     AliError(Form("Bad chip number %d",iChip));
214     return -1;
215   }
216   Int_t iSide=GetSideFromLocalX(xloc);
217   if(iSide==1) iChip=fgkNchipsPerHybrid-iChip+3;   // i.e. 7-iChip
218   return iChip;
219 }
220 //----------------------------------------------------------------------
221 void AliITSsegmentationSDD::GetPadIxz(Float_t x,Float_t z,
222                                       Int_t &timebin,Int_t &anode) const {
223 // Returns cell coordinates (time sample,anode)
224 // for given real local coordinates (x,z)
225
226   // expects x, z in cm
227
228   Float_t driftpath=fDx-TMath::Abs(x*fgkCm2Micron);
229   timebin=(Int_t)(driftpath/fDriftSpeed/fTimeStep);
230   anode=(Int_t)GetAnodeFromLocal(x,z);
231   if(!fSetDriftSpeed){
232     timebin=-999;
233     AliWarning("Drift speed not set: timebin is dummy");
234   }
235
236 }
237 //----------------------------------------------------------------------
238 void AliITSsegmentationSDD::GetPadCxz(Int_t timebin,Int_t anode,
239                                       Float_t &x ,Float_t &z) const{
240   // Transform from cell to real local coordinates
241   // returns x, z in cm
242
243   // the +0.5 means that an # and time bin # should start from 0 !!! 
244   // the +0.5 means that an # and time bin # should start from 0 !!! 
245
246   Float_t driftpath=GetDriftTimeFromTb(timebin)*fDriftSpeed;
247   if (anode < fNanodes/2){ // left side, positive x
248     x=(fDx-driftpath)*fgkMicron2Cm;
249   }else{ // right side, negative x
250     x = -(fDx-driftpath)*fgkMicron2Cm;
251   }
252   z=GetLocalZFromAnode(anode);
253   if(!fSetDriftSpeed){
254     x=-9999.;
255     AliWarning("Drift speed not set: x coord. is dummy");
256   }
257 }
258 //----------------------------------------------------------------------
259 void AliITSsegmentationSDD::GetPadTxz(Float_t &x,Float_t &z) const{
260     // Get anode and time bucket as floats - numbering from 0
261
262     // expects x, z in cm
263
264     Float_t xloc=x;
265     Float_t zloc=z;
266     Float_t driftpath=fDx-TMath::Abs(fgkCm2Micron*xloc);
267     x=driftpath/fDriftSpeed/fTimeStep;
268     if (xloc < 0) x = -x;
269     z=GetAnodeFromLocal(xloc,zloc);
270     if(!fSetDriftSpeed){
271       x=-9999.;
272       AliWarning("Drift speed not set: x coord. is dummy");
273     }
274 }
275 //----------------------------------------------------------------------
276 void AliITSsegmentationSDD::Print(Option_t *opt) const {
277   // Print SDD segmentation Parameters
278
279    cout << "**************************************************" << endl;
280    cout << "  Silicon Drift Detector Segmentation Parameters  " << opt << endl;
281    cout << "**************************************************" << endl;
282    cout << "Number of Time Samples: " << fNsamples << endl;
283    cout << "Number of Anodes: " << fNanodes << endl;
284    cout << "Time Step (ns): " << fTimeStep << endl;
285    cout << "Anode Pitch (um): " << fPitch << endl;
286    cout << "Full Detector Width     (x): " << fDx;
287    cout<<" (Default is "<<fgkDxDefault<<") "<<endl;
288    cout << "Half Detector Length    (z): " << fDz;
289    cout<<" (Default is "<<fgkDzDefault<<") "<<endl;
290    cout << "Full Detector Thickness (y): " << fDy;
291    cout<<" (Default is "<<fgkDyDefault<<") "<<endl;
292    cout << "**************************************************" << endl;
293
294 }
295
296 //----------------------------------------------------------------------
297 void AliITSsegmentationSDD::PrintDefaultParameters() const {
298   // print SDD parameters defined as static const data members
299
300   cout << "**************************************************" << endl;
301   cout << "  Silicon Drift Detector Segmentation Parameters  " << endl;
302   cout << " Default values defined as static const data members"<< endl;
303   cout << " Actual values can be set with the relevant setters"<< endl; 
304   cout << "**************************************************" << endl;
305   cout<<"fgkDxDefault = "<<fgkDxDefault<<endl;
306   cout<<"fgkDzDefault = "<<fgkDzDefault<<endl;
307   cout<<"fgkDyDefault = "<<fgkDyDefault<<endl;
308   cout<<"fgkPitchDefault = "<<fgkPitchDefault<<endl;
309   cout<<"fgkClockDefault = "<<fgkClockDefault<<endl;
310   cout<<"fgkHalfNanodesDefault = "<<fgkHalfNanodesDefault<<endl;
311   cout<<"fgkNsamplesDefault = "<<fgkNsamplesDefault<<endl;
312   cout << "**************************************************" << endl;
313
314 }
315
316 //______________________________________________________________________
317 Bool_t AliITSsegmentationSDD::LocalToDet(Float_t x,Float_t z,
318                                          Int_t &ix,Int_t &iz) const {
319 // Transformation from Geant detector centered local coordinates (cm) to
320 // time bucket numbers ix and anode number iz.
321 // Input:
322 // Float_t   x      detector local coordinate x in cm with respect to the
323 //                  center of the sensitive volume.
324 // Float_t   z      detector local coordinate z in cm with respect to the
325 //                  center of the sensitive volulme.
326 // Output:
327 // Int_t    ix      detector x time coordinate. Has the range 0<=ix<fNsamples.
328 // Int_t    iz      detector z anode coordinate. Has the range 0<=iz<fNandoes.
329 //   A value of -1 for ix or iz indecates that this point is outside of the
330 // detector segmentation as defined.
331
332     Float_t dx,dz;
333
334     ix = -1; // default values
335     iz = -1; // default values
336     dx = -fgkMicron2Cm*Dx(); // lower left edge in cm.
337     dz = -0.5*fgkMicron2Cm*Dz(); // lower left edge in cm.
338     if(x<dx || x>-dx) {
339       AliWarning(Form("Input argument %f out of range (%f, %f)",x,dx,-dx));
340       return kFALSE; // outside of defined volume.
341     }
342     if(z<dz || z>-dz) {
343       AliWarning(Form("Input argument %f out of range (%f, %f)",z,dz,-dz));
344       return kFALSE; // outside of defined volume.
345     }
346     GetPadIxz(x,z,ix,iz);
347     if(!fSetDriftSpeed){
348       ix=-999;
349       AliWarning("Drift speed not set: timebin is dummy");
350       return kFALSE;
351     }
352     return kTRUE; // Found ix and iz, return.
353 }
354 //______________________________________________________________________
355 void AliITSsegmentationSDD::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const
356 {
357 // Transformation from Detector time bucket and anode coordiantes to Geant 
358 // detector centerd local coordinates (cm).
359 // Input:
360 // Int_t    ix      detector x time coordinate. Has the range 0<=ix<fNsamples.
361 // Int_t    iz      detector z anode coordinate. Has the range 0<=iz<fNandoes.
362 // Output:
363 // Float_t   x      detector local coordinate x in cm with respect to the
364 //                  center of the sensitive volume.
365 // Float_t   z      detector local coordinate z in cm with respect to the
366 //                  center of the sensitive volulme.
367 // If ix and or iz is outside of the segmentation range a value of -Dx()
368 // or -0.5*Dz() is returned.
369
370   x=-Dx();
371   z=-0.5*Dz();
372   if(ix<0 || ix>=Npx()) {
373     AliWarning(Form("Input argument %d out of range (0, %d)",ix,Npx()));
374     return; // outside of detector
375   }
376   if(iz<0 || iz>=Npz()) {
377     AliWarning(Form("Input argument %d out of range (0, %d)",iz,Npz()));
378     return; // outside of detctor
379   }
380   GetPadCxz(ix,iz,x,z);
381   if(!fSetDriftSpeed){
382     x=-9999.;
383     AliWarning("Drift speed not set: x coord. is dummy");
384   }
385   return; // Found x and z, return.
386 }