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