]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSsegmentationSDD.cxx
Further fixes to the par file generation
[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 "AliITSresponseSDD.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=AliITSresponseSDD::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 void AliITSsegmentationSDD::GetPadIxz(Float_t x,Float_t z,
216                                       Int_t &timebin,Int_t &anode) const {
217 // Returns cell coordinates (time sample,anode)
218 // for given real local coordinates (x,z)
219
220   // expects x, z in cm
221
222   Float_t driftpath=fDx-TMath::Abs(x*fgkCm2Micron);
223   timebin=(Int_t)(driftpath/fDriftSpeed/fTimeStep);
224   anode=(Int_t)GetAnodeFromLocal(x,z);
225   if(!fSetDriftSpeed){
226     timebin=-999;
227     AliWarning("Drift speed not set: timebin is dummy");
228   }
229
230 }
231 //----------------------------------------------------------------------
232 void AliITSsegmentationSDD::GetPadCxz(Int_t timebin,Int_t anode,
233                                       Float_t &x ,Float_t &z) const{
234   // Transform from cell to real local coordinates
235   // returns x, z in cm
236
237   // the +0.5 means that an # and time bin # should start from 0 !!! 
238   // the +0.5 means that an # and time bin # should start from 0 !!! 
239
240   Float_t driftpath=GetDriftTimeFromTb(timebin)*fDriftSpeed;
241   if (anode < fNanodes/2){ // left side, positive x
242     x=(fDx-driftpath)*fgkMicron2Cm;
243   }else{ // right side, negative x
244     x = -(fDx-driftpath)*fgkMicron2Cm;
245   }
246   z=GetLocalZFromAnode(anode);
247   if(!fSetDriftSpeed){
248     x=-9999.;
249     AliWarning("Drift speed not set: x coord. is dummy");
250   }
251 }
252 //----------------------------------------------------------------------
253 void AliITSsegmentationSDD::GetPadTxz(Float_t &x,Float_t &z) const{
254     // Get anode and time bucket as floats - numbering from 0
255
256     // expects x, z in cm
257
258     Float_t xloc=x;
259     Float_t zloc=z;
260     Float_t driftpath=fDx-TMath::Abs(fgkCm2Micron*xloc);
261     x=driftpath/fDriftSpeed/fTimeStep;
262     if (xloc < 0) x = -x;
263     z=GetAnodeFromLocal(xloc,zloc);
264     if(!fSetDriftSpeed){
265       x=-9999.;
266       AliWarning("Drift speed not set: x coord. is dummy");
267     }
268 }
269 //----------------------------------------------------------------------
270 void AliITSsegmentationSDD::Print(Option_t *opt) const {
271   // Print SDD segmentation Parameters
272
273    cout << "**************************************************" << endl;
274    cout << "  Silicon Drift Detector Segmentation Parameters  " << opt << endl;
275    cout << "**************************************************" << endl;
276    cout << "Number of Time Samples: " << fNsamples << endl;
277    cout << "Number of Anodes: " << fNanodes << endl;
278    cout << "Time Step (ns): " << fTimeStep << endl;
279    cout << "Anode Pitch (um): " << fPitch << endl;
280    cout << "Full Detector Width     (x): " << fDx;
281    cout<<" (Default is "<<fgkDxDefault<<") "<<endl;
282    cout << "Half Detector Length    (z): " << fDz;
283    cout<<" (Default is "<<fgkDzDefault<<") "<<endl;
284    cout << "Full Detector Thickness (y): " << fDy;
285    cout<<" (Default is "<<fgkDyDefault<<") "<<endl;
286    cout << "**************************************************" << endl;
287
288 }
289
290 //----------------------------------------------------------------------
291 void AliITSsegmentationSDD::PrintDefaultParameters() const {
292   // print SDD parameters defined as static const data members
293
294   cout << "**************************************************" << endl;
295   cout << "  Silicon Drift Detector Segmentation Parameters  " << endl;
296   cout << " Default values defined as static const data members"<< endl;
297   cout << " Actual values can be set with the relevant setters"<< endl; 
298   cout << "**************************************************" << endl;
299   cout<<"fgkDxDefault = "<<fgkDxDefault<<endl;
300   cout<<"fgkDzDefault = "<<fgkDzDefault<<endl;
301   cout<<"fgkDyDefault = "<<fgkDyDefault<<endl;
302   cout<<"fgkPitchDefault = "<<fgkPitchDefault<<endl;
303   cout<<"fgkClockDefault = "<<fgkClockDefault<<endl;
304   cout<<"fgkHalfNanodesDefault = "<<fgkHalfNanodesDefault<<endl;
305   cout<<"fgkNsamplesDefault = "<<fgkNsamplesDefault<<endl;
306   cout << "**************************************************" << endl;
307
308 }
309
310 //______________________________________________________________________
311 Bool_t AliITSsegmentationSDD::LocalToDet(Float_t x,Float_t z,
312                                          Int_t &ix,Int_t &iz) const {
313 // Transformation from Geant detector centered local coordinates (cm) to
314 // time bucket numbers ix and anode number iz.
315 // Input:
316 // Float_t   x      detector local coordinate x in cm with respect to the
317 //                  center of the sensitive volume.
318 // Float_t   z      detector local coordinate z in cm with respect to the
319 //                  center of the sensitive volulme.
320 // Output:
321 // Int_t    ix      detector x time coordinate. Has the range 0<=ix<fNsamples.
322 // Int_t    iz      detector z anode coordinate. Has the range 0<=iz<fNandoes.
323 //   A value of -1 for ix or iz indecates that this point is outside of the
324 // detector segmentation as defined.
325
326     Float_t dx,dz;
327
328     ix = -1; // default values
329     iz = -1; // default values
330     dx = -fgkMicron2Cm*Dx(); // lower left edge in cm.
331     dz = -0.5*fgkMicron2Cm*Dz(); // lower left edge in cm.
332     if(x<dx || x>-dx) {
333       AliWarning(Form("Input argument %f out of range (%f, %f)",x,dx,-dx));
334       return kFALSE; // outside of defined volume.
335     }
336     if(z<dz || z>-dz) {
337       AliWarning(Form("Input argument %f out of range (%f, %f)",z,dz,-dz));
338       return kFALSE; // outside of defined volume.
339     }
340     GetPadIxz(x,z,ix,iz);
341     if(!fSetDriftSpeed){
342       ix=-999;
343       AliWarning("Drift speed not set: timebin is dummy");
344       return kFALSE;
345     }
346     return kTRUE; // Found ix and iz, return.
347 }
348 //______________________________________________________________________
349 void AliITSsegmentationSDD::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const
350 {
351 // Transformation from Detector time bucket and anode coordiantes to Geant 
352 // detector centerd local coordinates (cm).
353 // Input:
354 // Int_t    ix      detector x time coordinate. Has the range 0<=ix<fNsamples.
355 // Int_t    iz      detector z anode coordinate. Has the range 0<=iz<fNandoes.
356 // Output:
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 // If ix and or iz is outside of the segmentation range a value of -Dx()
362 // or -0.5*Dz() is returned.
363
364   x=-Dx();
365   z=-0.5*Dz();
366   if(ix<0 || ix>=Npx()) {
367     AliWarning(Form("Input argument %d out of range (0, %d)",ix,Npx()));
368     return; // outside of detector
369   }
370   if(iz<0 || iz>=Npz()) {
371     AliWarning(Form("Input argument %d out of range (0, %d)",iz,Npz()));
372     return; // outside of detctor
373   }
374   GetPadCxz(ix,iz,x,z);
375   if(!fSetDriftSpeed){
376     x=-9999.;
377     AliWarning("Drift speed not set: x coord. is dummy");
378   }
379   return; // Found x and z, return.
380 }