store also difference in local Y
[u/mrichter/AliRoot.git] / ITS / AliITSsegmentationSDD.cxx
CommitLineData
b0f5e3fc 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 **************************************************************************/
4ae5bbc4 15#include <Riostream.h>
b0f5e3fc 16#include <TMath.h>
c9649d1e 17#include <TGeoManager.h>
18#include <TGeoVolume.h>
19#include <TGeoBBox.h>
b0f5e3fc 20#include "AliITSsegmentationSDD.h"
253e68a0 21#include "AliITSDriftSpeedSDD.h"
f6b6d58e 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/////////////////////////////////////////////////////////////////////////////
55d2c544 47
c9649d1e 48/* $Id$ */
214b9c8f 49
55d2c544 50const Float_t AliITSsegmentationSDD::fgkDxDefault = 35085.;
51const Float_t AliITSsegmentationSDD::fgkDzDefault = 75264.;
52const Float_t AliITSsegmentationSDD::fgkDyDefault = 300.;
53const Float_t AliITSsegmentationSDD::fgkPitchDefault = 294.;
54const Float_t AliITSsegmentationSDD::fgkClockDefault = 40.;
55const Int_t AliITSsegmentationSDD::fgkHalfNanodesDefault = 256;
56const Int_t AliITSsegmentationSDD::fgkNsamplesDefault = 256;
d24bc9d6 57const Int_t AliITSsegmentationSDD::fgkNchipsPerHybrid = 4;
58const Int_t AliITSsegmentationSDD::fgkNanodesPerChip = 64;
f6b6d58e 59const Float_t AliITSsegmentationSDD::fgkCm2Micron = 10000.;
60const Float_t AliITSsegmentationSDD::fgkMicron2Cm = 1.0E-04;
fe7d86eb 61
62using std::endl;
63using std::cout;
b0f5e3fc 64ClassImp(AliITSsegmentationSDD)
fa4f0f62 65
2a4239d3 66//______________________________________________________________________
c9649d1e 67AliITSsegmentationSDD::AliITSsegmentationSDD(Option_t *opt) : AliITSsegmentation(),
e56160b8 68fNsamples(0),
69fNanodes(0),
70fPitch(0),
71fTimeStep(0),
4952f440 72fDriftSpeed(0),
73fSetDriftSpeed(0){
55d2c544 74 // Default constructor
d24bc9d6 75 Init();
c9649d1e 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 }
55d2c544 91}
b0f5e3fc 92
55d2c544 93//______________________________________________________________________
94void 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;
4952f440 102 ((AliITSsegmentationSDD& ) obj).fSetDriftSpeed = fSetDriftSpeed;
b0f5e3fc 103}
55d2c544 104
105//______________________________________________________________________
106AliITSsegmentationSDD& AliITSsegmentationSDD::operator=(const AliITSsegmentationSDD &source){
107 // = operator
108 if(this==&source) return *this;
109 source.Copy(*this);
110 return *this;
111}
112
113//____________________________________________________________________________
114AliITSsegmentationSDD::AliITSsegmentationSDD(const AliITSsegmentationSDD &source) :
e56160b8 115 AliITSsegmentation(source),
116fNsamples(0),
117fNanodes(0),
118fPitch(0),
119fTimeStep(0),
4952f440 120fDriftSpeed(0),
121fSetDriftSpeed(0){
55d2c544 122 // copy constructor
123 source.Copy(*this);
124}
125
2a4239d3 126//----------------------------------------------------------------------
b0f5e3fc 127void AliITSsegmentationSDD::Init(){
d24bc9d6 128// Standard initilisation routine
253e68a0 129 fDriftSpeed=AliITSDriftSpeedSDD::DefaultDriftSpeed();
d24bc9d6 130 fCorr=0;
131 SetDetSize(fgkDxDefault,fgkDzDefault,fgkDyDefault);
132 SetPadSize(fgkPitchDefault,fgkClockDefault);
133 SetNPads(fgkHalfNanodesDefault,fgkNsamplesDefault);
134}
b0f5e3fc 135
2a4239d3 136//----------------------------------------------------------------------
b0f5e3fc 137void AliITSsegmentationSDD::
55d2c544 138Neighbours(Int_t iX, Int_t iZ, Int_t* Nlist, Int_t Xlist[8], Int_t Zlist[8]) const {
314ba410 139 // returns neighbours for use in Cluster Finder routines and the like
b0f5e3fc 140
e8189707 141 if(iX >= fNanodes) printf("iX > fNanodes %d %d\n",iX,fNanodes);
142 if(iZ >= fNsamples) printf("iZ > fNsamples %d %d\n",iZ,fNsamples);
b0f5e3fc 143 *Nlist=4;
144 Xlist[0]=Xlist[1]=iX;
314ba410 145 if(iX && (iX != fNanodes/2)) Xlist[2]=iX-1;
b0f5e3fc 146 else Xlist[2]=iX;
314ba410 147 if ((iX !=fNanodes/2 -1) && (iX != fNanodes)) Xlist[3]=iX+1;
b0f5e3fc 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;
b0f5e3fc 154}
2a4239d3 155//----------------------------------------------------------------------
f6b6d58e 156Float_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//----------------------------------------------------------------------
168Float_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//----------------------------------------------------------------------
175Float_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//----------------------------------------------------------------------
d24bc9d6 187Int_t AliITSsegmentationSDD::GetChipFromChannel(Int_t ix, Int_t iz) const {
214b9c8f 188 // returns chip number (in range 0-7) starting from channel number
d24bc9d6 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//----------------------------------------------------------------------
197Int_t AliITSsegmentationSDD::GetChipFromLocal(Float_t xloc, Float_t zloc) const {
214b9c8f 198 // returns chip number (in range 0-7) starting from local coordinates
d24bc9d6 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//----------------------------------------------------------------------
23197852 218Int_t AliITSsegmentationSDD::GetChipsInLocalWindow(Int_t* array, Float_t zmin, Float_t zmax, Float_t xmin, Float_t xmax) const {
776c19a3 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
23197852 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//----------------------------------------------------------------------
2a4239d3 262void AliITSsegmentationSDD::GetPadIxz(Float_t x,Float_t z,
55d2c544 263 Int_t &timebin,Int_t &anode) const {
f6b6d58e 264// Returns cell coordinates (time sample,anode)
03898a57 265// for given real local coordinates (x,z)
b0f5e3fc 266
f6b6d58e 267 // expects x, z in cm
b0f5e3fc 268
f6b6d58e 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 }
b0f5e3fc 276
277}
2a4239d3 278//----------------------------------------------------------------------
279void AliITSsegmentationSDD::GetPadCxz(Int_t timebin,Int_t anode,
55d2c544 280 Float_t &x ,Float_t &z) const{
f6b6d58e 281 // Transform from cell to real local coordinates
282 // returns x, z in cm
b0f5e3fc 283
03898a57 284 // the +0.5 means that an # and time bin # should start from 0 !!!
03898a57 285 // the +0.5 means that an # and time bin # should start from 0 !!!
b0f5e3fc 286
f6b6d58e 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 }
b0f5e3fc 298}
2a4239d3 299//----------------------------------------------------------------------
55d2c544 300void AliITSsegmentationSDD::GetPadTxz(Float_t &x,Float_t &z) const{
e8189707 301 // Get anode and time bucket as floats - numbering from 0
302
303 // expects x, z in cm
304
f6b6d58e 305 Float_t xloc=x;
306 Float_t zloc=z;
307 Float_t driftpath=fDx-TMath::Abs(fgkCm2Micron*xloc);
03898a57 308 x=driftpath/fDriftSpeed/fTimeStep;
f6b6d58e 309 if (xloc < 0) x = -x;
310 z=GetAnodeFromLocal(xloc,zloc);
4952f440 311 if(!fSetDriftSpeed){
312 x=-9999.;
f6b6d58e 313 AliWarning("Drift speed not set: x coord. is dummy");
b0f5e3fc 314 }
b0f5e3fc 315}
f5d698b9 316//----------------------------------------------------------------------
db93954b 317void AliITSsegmentationSDD::Print(Option_t *opt) const {
f5d698b9 318 // Print SDD segmentation Parameters
319
320 cout << "**************************************************" << endl;
ac74f489 321 cout << " Silicon Drift Detector Segmentation Parameters " << opt << endl;
f5d698b9 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;
55d2c544 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;
f5d698b9 333 cout << "**************************************************" << endl;
334
335}
55d2c544 336
337//----------------------------------------------------------------------
338void 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}
5752a110 356
357//______________________________________________________________________
aacedc3e 358Bool_t AliITSsegmentationSDD::LocalToDet(Float_t x,Float_t z,
359 Int_t &ix,Int_t &iz) const {
5752a110 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.
f6b6d58e 372
373 Float_t dx,dz;
5752a110 374
375 ix = -1; // default values
376 iz = -1; // default values
f6b6d58e 377 dx = -fgkMicron2Cm*Dx(); // lower left edge in cm.
378 dz = -0.5*fgkMicron2Cm*Dz(); // lower left edge in cm.
507cf1a7 379 if(x<dx || x>-dx) {
f6b6d58e 380 AliWarning(Form("Input argument %f out of range (%f, %f)",x,dx,-dx));
aacedc3e 381 return kFALSE; // outside of defined volume.
507cf1a7 382 }
383 if(z<dz || z>-dz) {
f6b6d58e 384 AliWarning(Form("Input argument %f out of range (%f, %f)",z,dz,-dz));
aacedc3e 385 return kFALSE; // outside of defined volume.
507cf1a7 386 }
f6b6d58e 387 GetPadIxz(x,z,ix,iz);
4952f440 388 if(!fSetDriftSpeed){
f6b6d58e 389 ix=-999;
390 AliWarning("Drift speed not set: timebin is dummy");
4952f440 391 return kFALSE;
392 }
aacedc3e 393 return kTRUE; // Found ix and iz, return.
5752a110 394}
395//______________________________________________________________________
55d2c544 396void AliITSsegmentationSDD::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const
5752a110 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.
5752a110 410
f6b6d58e 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.
5752a110 427}