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