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