Separating well and badly reconstructed pileup vertices. Adding statistics of associa...
[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
62 using std::endl;
63 using std::cout;
64 ClassImp(AliITSsegmentationSDD)
65
66 //______________________________________________________________________
67 AliITSsegmentationSDD::AliITSsegmentationSDD(Option_t *opt) : AliITSsegmentation(),
68 fNsamples(0),
69 fNanodes(0),
70 fPitch(0),
71 fTimeStep(0),
72 fDriftSpeed(0),
73 fSetDriftSpeed(0){
74   // Default constructor
75   Init();
76   if(strstr(opt,"TGeo")){
77     if(!gGeoManager){
78       AliError("Geometry is not initialized\n");
79       return;
80     }
81     TGeoVolume *v=NULL;
82     v = gGeoManager->GetVolume("ITSsddSensitivL3");
83     if(!v){
84       AliWarning("TGeo volume ITSsddSensitivL3 not found (hint: use v11Hybrid geometry)\n Using hardwired default values"); 
85     }
86     else {
87       TGeoBBox *s=(TGeoBBox*)v->GetShape();
88       SetDetSize(s->GetDX()*10000.,s->GetDZ()*20000.,s->GetDY()*20000.);
89     }
90   }
91 }
92
93 //______________________________________________________________________
94 void AliITSsegmentationSDD::Copy(TObject &obj) const {
95   // protected method. copy this to obj
96   AliITSsegmentation::Copy(obj);
97   ((AliITSsegmentationSDD& ) obj).fNsamples = fNsamples;
98   ((AliITSsegmentationSDD& ) obj).fNanodes = fNanodes;
99   ((AliITSsegmentationSDD& ) obj).fPitch = fPitch;
100   ((AliITSsegmentationSDD& ) obj).fTimeStep = fTimeStep;
101   ((AliITSsegmentationSDD& ) obj).fDriftSpeed = fDriftSpeed;
102   ((AliITSsegmentationSDD& ) obj).fSetDriftSpeed = fSetDriftSpeed;
103 }
104
105 //______________________________________________________________________
106 AliITSsegmentationSDD& AliITSsegmentationSDD::operator=(const AliITSsegmentationSDD &source){
107    // = operator
108    if(this==&source) return *this;
109    source.Copy(*this);
110    return *this;
111 }
112
113 //____________________________________________________________________________
114 AliITSsegmentationSDD::AliITSsegmentationSDD(const AliITSsegmentationSDD &source) :
115     AliITSsegmentation(source),
116 fNsamples(0),
117 fNanodes(0),
118 fPitch(0),
119 fTimeStep(0),
120 fDriftSpeed(0),
121 fSetDriftSpeed(0){
122   // copy constructor
123   source.Copy(*this);
124 }
125
126 //----------------------------------------------------------------------
127 void AliITSsegmentationSDD::Init(){
128 // Standard initilisation routine
129    fDriftSpeed=AliITSDriftSpeedSDD::DefaultDriftSpeed();
130    fCorr=0;
131    SetDetSize(fgkDxDefault,fgkDzDefault,fgkDyDefault);
132    SetPadSize(fgkPitchDefault,fgkClockDefault);
133    SetNPads(fgkHalfNanodesDefault,fgkNsamplesDefault);
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 Int_t AliITSsegmentationSDD::GetChipFromChannel(Int_t ix, Int_t iz) const {
188   // returns chip number (in range 0-7) starting from channel number
189   if(iz>=fNanodes  || iz<0 || ix>fNsamples){
190     AliError("Bad cell number");
191     return -1;
192   }
193   Int_t theChip=iz/fgkNanodesPerChip;
194   return theChip;
195 }
196 //----------------------------------------------------------------------
197 Int_t AliITSsegmentationSDD::GetChipFromLocal(Float_t xloc, Float_t zloc) const {  
198   // returns chip number (in range 0-7) starting from local coordinates
199   Float_t detsize=fDz*fgkMicron2Cm;
200   Float_t chipsize=detsize/(Float_t)fgkNchipsPerHybrid;
201   zloc+=detsize/2.;
202   if(zloc<-0.01 || zloc>detsize+0.01){ // 100 micron tolerance around edges
203     AliError("Z local value out of sensitive SDD area");
204     return -1;
205   }
206   Int_t iChip=int(zloc/chipsize);
207   if(zloc<0.) iChip=0;  
208   if(zloc>=detsize) iChip=fgkNchipsPerHybrid-1;
209   if(iChip>=fgkNchipsPerHybrid || iChip<0){ 
210     AliError(Form("Bad chip number %d",iChip));
211     return -1;
212   }
213   Int_t iSide=GetSideFromLocalX(xloc);
214   if(iSide==1) iChip=fgkNchipsPerHybrid-iChip+3;   // i.e. 7-iChip
215   return iChip;
216 }
217 //----------------------------------------------------------------------
218 Int_t AliITSsegmentationSDD::GetChipsInLocalWindow(Int_t* array, Float_t zmin, Float_t zmax, Float_t xmin, Float_t xmax) const {
219   // returns the numbers of the chips that read channels in a given region
220   // of the module defined in local coordinates by zmin-zmax, xmin-max
221
222   Int_t nChipInW = 0;
223   Float_t zminDet=-fDz*fgkMicron2Cm/2.;
224   Float_t zmaxDet=fDz*fgkMicron2Cm/2.;
225   if(zmin<zminDet) zmin=zminDet;
226   if(zmax>zmaxDet) zmax=zmaxDet;
227   Float_t xminDet=-fDx*fgkMicron2Cm;
228   Float_t xmaxDet=fDx*fgkMicron2Cm;
229   if(xmin<xminDet) xmin=xminDet;
230   if(xmax>xmaxDet) xmax=xmaxDet;
231   Int_t n1=GetChipFromLocal(xmin,zmin);
232   array[nChipInW]=n1;
233   nChipInW++;
234   Int_t n2=GetChipFromLocal(xmin,zmax);
235   if(n2!=n1){
236     Int_t imin=TMath::Min(n1,n2);
237     Int_t imax=TMath::Max(n1,n2);
238     for(Int_t ichip=imin; ichip<=imax; ichip++){
239       if(ichip==n1) continue;
240       array[nChipInW]=ichip;
241       nChipInW++;    
242     }
243   }
244   Int_t n3=GetChipFromLocal(xmax,zmin);
245   if(n3!=n1){
246     array[nChipInW]=n3;
247     nChipInW++;
248     Int_t n4=GetChipFromLocal(xmax,zmax);
249     if(n4!=n3){
250       Int_t imin=TMath::Min(n3,n4);
251       Int_t imax=TMath::Max(n3,n4);
252       for(Int_t ichip=imin; ichip<=imax; ichip++){
253         if(ichip==n3) continue;
254         array[nChipInW]=ichip;
255         nChipInW++;    
256       }
257     }
258   }
259   return nChipInW;
260 }
261 //----------------------------------------------------------------------
262 void AliITSsegmentationSDD::GetPadIxz(Float_t x,Float_t z,
263                                       Int_t &timebin,Int_t &anode) const {
264 // Returns cell coordinates (time sample,anode)
265 // for given real local coordinates (x,z)
266
267   // expects x, z in cm
268
269   Float_t driftpath=fDx-TMath::Abs(x*fgkCm2Micron);
270   timebin=(Int_t)(driftpath/fDriftSpeed/fTimeStep);
271   anode=(Int_t)GetAnodeFromLocal(x,z);
272   if(!fSetDriftSpeed){
273     timebin=-999;
274     AliWarning("Drift speed not set: timebin is dummy");
275   }
276
277 }
278 //----------------------------------------------------------------------
279 void AliITSsegmentationSDD::GetPadCxz(Int_t timebin,Int_t anode,
280                                       Float_t &x ,Float_t &z) const{
281   // Transform from cell to real local coordinates
282   // returns x, z in cm
283
284   // the +0.5 means that an # and time bin # should start from 0 !!! 
285   // the +0.5 means that an # and time bin # should start from 0 !!! 
286
287   Float_t driftpath=GetDriftTimeFromTb(timebin)*fDriftSpeed;
288   if (anode < fNanodes/2){ // left side, positive x
289     x=(fDx-driftpath)*fgkMicron2Cm;
290   }else{ // right side, negative x
291     x = -(fDx-driftpath)*fgkMicron2Cm;
292   }
293   z=GetLocalZFromAnode(anode);
294   if(!fSetDriftSpeed){
295     x=-9999.;
296     AliWarning("Drift speed not set: x coord. is dummy");
297   }
298 }
299 //----------------------------------------------------------------------
300 void AliITSsegmentationSDD::GetPadTxz(Float_t &x,Float_t &z) const{
301     // Get anode and time bucket as floats - numbering from 0
302
303     // expects x, z in cm
304
305     Float_t xloc=x;
306     Float_t zloc=z;
307     Float_t driftpath=fDx-TMath::Abs(fgkCm2Micron*xloc);
308     x=driftpath/fDriftSpeed/fTimeStep;
309     if (xloc < 0) x = -x;
310     z=GetAnodeFromLocal(xloc,zloc);
311     if(!fSetDriftSpeed){
312       x=-9999.;
313       AliWarning("Drift speed not set: x coord. is dummy");
314     }
315 }
316 //----------------------------------------------------------------------
317 void AliITSsegmentationSDD::Print(Option_t *opt) const {
318   // Print SDD segmentation Parameters
319
320    cout << "**************************************************" << endl;
321    cout << "  Silicon Drift Detector Segmentation Parameters  " << opt << endl;
322    cout << "**************************************************" << endl;
323    cout << "Number of Time Samples: " << fNsamples << endl;
324    cout << "Number of Anodes: " << fNanodes << endl;
325    cout << "Time Step (ns): " << fTimeStep << endl;
326    cout << "Anode Pitch (um): " << fPitch << endl;
327    cout << "Full Detector Width     (x): " << fDx;
328    cout<<" (Default is "<<fgkDxDefault<<") "<<endl;
329    cout << "Half Detector Length    (z): " << fDz;
330    cout<<" (Default is "<<fgkDzDefault<<") "<<endl;
331    cout << "Full Detector Thickness (y): " << fDy;
332    cout<<" (Default is "<<fgkDyDefault<<") "<<endl;
333    cout << "**************************************************" << endl;
334
335 }
336
337 //----------------------------------------------------------------------
338 void AliITSsegmentationSDD::PrintDefaultParameters() const {
339   // print SDD parameters defined as static const data members
340
341   cout << "**************************************************" << endl;
342   cout << "  Silicon Drift Detector Segmentation Parameters  " << endl;
343   cout << " Default values defined as static const data members"<< endl;
344   cout << " Actual values can be set with the relevant setters"<< endl; 
345   cout << "**************************************************" << endl;
346   cout<<"fgkDxDefault = "<<fgkDxDefault<<endl;
347   cout<<"fgkDzDefault = "<<fgkDzDefault<<endl;
348   cout<<"fgkDyDefault = "<<fgkDyDefault<<endl;
349   cout<<"fgkPitchDefault = "<<fgkPitchDefault<<endl;
350   cout<<"fgkClockDefault = "<<fgkClockDefault<<endl;
351   cout<<"fgkHalfNanodesDefault = "<<fgkHalfNanodesDefault<<endl;
352   cout<<"fgkNsamplesDefault = "<<fgkNsamplesDefault<<endl;
353   cout << "**************************************************" << endl;
354
355 }
356
357 //______________________________________________________________________
358 Bool_t AliITSsegmentationSDD::LocalToDet(Float_t x,Float_t z,
359                                          Int_t &ix,Int_t &iz) const {
360 // Transformation from Geant detector centered local coordinates (cm) to
361 // time bucket numbers ix and anode number iz.
362 // Input:
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 // Output:
368 // Int_t    ix      detector x time coordinate. Has the range 0<=ix<fNsamples.
369 // Int_t    iz      detector z anode coordinate. Has the range 0<=iz<fNandoes.
370 //   A value of -1 for ix or iz indecates that this point is outside of the
371 // detector segmentation as defined.
372
373     Float_t dx,dz;
374
375     ix = -1; // default values
376     iz = -1; // default values
377     dx = -fgkMicron2Cm*Dx(); // lower left edge in cm.
378     dz = -0.5*fgkMicron2Cm*Dz(); // lower left edge in cm.
379     if(x<dx || x>-dx) {
380       AliWarning(Form("Input argument %f out of range (%f, %f)",x,dx,-dx));
381       return kFALSE; // outside of defined volume.
382     }
383     if(z<dz || z>-dz) {
384       AliWarning(Form("Input argument %f out of range (%f, %f)",z,dz,-dz));
385       return kFALSE; // outside of defined volume.
386     }
387     GetPadIxz(x,z,ix,iz);
388     if(!fSetDriftSpeed){
389       ix=-999;
390       AliWarning("Drift speed not set: timebin is dummy");
391       return kFALSE;
392     }
393     return kTRUE; // Found ix and iz, return.
394 }
395 //______________________________________________________________________
396 void AliITSsegmentationSDD::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const
397 {
398 // Transformation from Detector time bucket and anode coordiantes to Geant 
399 // detector centerd local coordinates (cm).
400 // Input:
401 // Int_t    ix      detector x time coordinate. Has the range 0<=ix<fNsamples.
402 // Int_t    iz      detector z anode coordinate. Has the range 0<=iz<fNandoes.
403 // Output:
404 // Float_t   x      detector local coordinate x in cm with respect to the
405 //                  center of the sensitive volume.
406 // Float_t   z      detector local coordinate z in cm with respect to the
407 //                  center of the sensitive volulme.
408 // If ix and or iz is outside of the segmentation range a value of -Dx()
409 // or -0.5*Dz() is returned.
410
411   x=-Dx();
412   z=-0.5*Dz();
413   if(ix<0 || ix>=Npx()) {
414     AliWarning(Form("Input argument %d out of range (0, %d)",ix,Npx()));
415     return; // outside of detector
416   }
417   if(iz<0 || iz>=Npz()) {
418     AliWarning(Form("Input argument %d out of range (0, %d)",iz,Npz()));
419     return; // outside of detctor
420   }
421   GetPadCxz(ix,iz,x,z);
422   if(!fSetDriftSpeed){
423     x=-9999.;
424     AliWarning("Drift speed not set: x coord. is dummy");
425   }
426   return; // Found x and z, return.
427 }