1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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>
18 #include "AliITSsegmentationSDD.h"
19 #include "AliITSgeomSDD.h"
20 #include "AliITSresponseSDD.h"
22 /////////////////////////////////////////////////////////////////////////////
23 // Segmentation class for drift detectors //
25 // microcables microcables //
31 // 0 |----------------------|---------------------| 511 //
32 // | time-bins | time-bins | //
35 // X <_|_o____________________|___________________o_|__ //
37 // | e LEFT SIDE | RIGHT SIDE e | //
38 // | s CHANNEL 0 | CHANNEL 1 s | //
39 // | Xlocal > 0 | Xlocal < 0 | //
40 // 255 |----------------------|---------------------| 256 //
45 /////////////////////////////////////////////////////////////////////////////
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 Int_t AliITSsegmentationSDD::fgkNchipsPerHybrid = 4;
55 const Int_t AliITSsegmentationSDD::fgkNanodesPerChip = 64;
56 const Float_t AliITSsegmentationSDD::fgkCm2Micron = 10000.;
57 const Float_t AliITSsegmentationSDD::fgkMicron2Cm = 1.0E-04;
58 ClassImp(AliITSsegmentationSDD)
59 //----------------------------------------------------------------------
60 AliITSsegmentationSDD::AliITSsegmentationSDD(AliITSgeom* geom):
71 //______________________________________________________________________
72 AliITSsegmentationSDD::AliITSsegmentationSDD() : AliITSsegmentation(),
79 // Default constructor
83 //______________________________________________________________________
84 void AliITSsegmentationSDD::Copy(TObject &obj) const {
85 // protected method. copy this to obj
86 AliITSsegmentation::Copy(obj);
87 ((AliITSsegmentationSDD& ) obj).fNsamples = fNsamples;
88 ((AliITSsegmentationSDD& ) obj).fNanodes = fNanodes;
89 ((AliITSsegmentationSDD& ) obj).fPitch = fPitch;
90 ((AliITSsegmentationSDD& ) obj).fTimeStep = fTimeStep;
91 ((AliITSsegmentationSDD& ) obj).fDriftSpeed = fDriftSpeed;
92 ((AliITSsegmentationSDD& ) obj).fSetDriftSpeed = fSetDriftSpeed;
95 //______________________________________________________________________
96 AliITSsegmentationSDD& AliITSsegmentationSDD::operator=(const AliITSsegmentationSDD &source){
98 if(this==&source) return *this;
103 //____________________________________________________________________________
104 AliITSsegmentationSDD::AliITSsegmentationSDD(const AliITSsegmentationSDD &source) :
105 AliITSsegmentation(source),
116 //----------------------------------------------------------------------
117 void AliITSsegmentationSDD::Init(){
118 // Standard initilisation routine
119 fDriftSpeed=AliITSresponseSDD::DefaultDriftSpeed();
121 SetDetSize(fgkDxDefault,fgkDzDefault,fgkDyDefault);
122 SetPadSize(fgkPitchDefault,fgkClockDefault);
123 SetNPads(fgkHalfNanodesDefault,fgkNsamplesDefault);
125 //----------------------------------------------------------------------
126 void AliITSsegmentationSDD::InitFromGeom(AliITSgeom *geom){
127 // Inizialization from geometry
130 AliFatal("Pointer to ITS geometry class (AliITSgeom) is null\n");
133 AliITSgeomSDD *gsdd = (AliITSgeomSDD *) (geom->GetShape(3,1,1));
135 fDz = 2.*fgkCm2Micron*gsdd->GetDz();
136 fDx = fgkCm2Micron*gsdd->GetDx();
137 fDy = 2.*fgkCm2Micron*gsdd->GetDy();
141 //----------------------------------------------------------------------
142 void AliITSsegmentationSDD::
143 Neighbours(Int_t iX, Int_t iZ, Int_t* Nlist, Int_t Xlist[8], Int_t Zlist[8]) const {
144 // returns neighbours for use in Cluster Finder routines and the like
146 if(iX >= fNanodes) printf("iX > fNanodes %d %d\n",iX,fNanodes);
147 if(iZ >= fNsamples) printf("iZ > fNsamples %d %d\n",iZ,fNsamples);
149 Xlist[0]=Xlist[1]=iX;
150 if(iX && (iX != fNanodes/2)) Xlist[2]=iX-1;
152 if ((iX !=fNanodes/2 -1) && (iX != fNanodes)) Xlist[3]=iX+1;
154 if(iZ) Zlist[0]=iZ-1;
156 if (iZ < fNsamples) Zlist[1]=iZ+1;
158 Zlist[2]=Zlist[3]=iZ;
160 //----------------------------------------------------------------------
161 Float_t AliITSsegmentationSDD::GetAnodeFromLocal(Float_t xloc,Float_t zloc) const {
162 // returns anode coordinate (as float) starting from local coordinates
163 Float_t xAnode=zloc*fgkCm2Micron/fPitch;
164 if(xloc>0){ // left side (anodes 0-255, anode 0 at zloc<0)
165 xAnode+=(Float_t)fNanodes/4;
166 }else{ // right side (anodes 256-511, anode 0 at zloc>0)
167 xAnode=3*fNanodes/4-xAnode;
172 //----------------------------------------------------------------------
173 Float_t AliITSsegmentationSDD::GetLocalZFromAnode(Int_t nAnode) const{
174 // returns local Z coordinate from anode number (integer)
175 Float_t zAnode=(Float_t)nAnode+0.5;
176 return GetLocalZFromAnode(zAnode);
179 //----------------------------------------------------------------------
180 Float_t AliITSsegmentationSDD::GetLocalZFromAnode(Float_t zAnode) const{
181 // returns local Z coordinate from anode number (float)
183 if(zAnode<fNanodes/2){ // left side
184 zloc=(zAnode*fPitch-fDz/2)*fgkMicron2Cm;
187 zloc=-(zAnode*fPitch-fDz/2)*fgkMicron2Cm;
191 //----------------------------------------------------------------------
192 Int_t AliITSsegmentationSDD::GetChipFromChannel(Int_t ix, Int_t iz) const {
193 if(iz>=fNanodes || iz<0 || ix>fNsamples){
194 AliError("Bad cell number");
197 Int_t theChip=iz/fgkNanodesPerChip;
200 //----------------------------------------------------------------------
201 Int_t AliITSsegmentationSDD::GetChipFromLocal(Float_t xloc, Float_t zloc) const {
202 Float_t detsize=fDz*fgkMicron2Cm;
203 Float_t chipsize=detsize/(Float_t)fgkNchipsPerHybrid;
205 if(zloc<-0.01 || zloc>detsize+0.01){ // 100 micron tolerance around edges
206 AliError("Z local value out of sensitive SDD area");
209 Int_t iChip=int(zloc/chipsize);
211 if(zloc>=detsize) iChip=fgkNchipsPerHybrid-1;
212 if(iChip>=fgkNchipsPerHybrid || iChip<0){
213 AliError(Form("Bad chip number %d",iChip));
216 Int_t iSide=GetSideFromLocalX(xloc);
217 if(iSide==1) iChip=fgkNchipsPerHybrid-iChip+3; // i.e. 7-iChip
220 //----------------------------------------------------------------------
221 void AliITSsegmentationSDD::GetPadIxz(Float_t x,Float_t z,
222 Int_t &timebin,Int_t &anode) const {
223 // Returns cell coordinates (time sample,anode)
224 // for given real local coordinates (x,z)
226 // expects x, z in cm
228 Float_t driftpath=fDx-TMath::Abs(x*fgkCm2Micron);
229 timebin=(Int_t)(driftpath/fDriftSpeed/fTimeStep);
230 anode=(Int_t)GetAnodeFromLocal(x,z);
233 AliWarning("Drift speed not set: timebin is dummy");
237 //----------------------------------------------------------------------
238 void AliITSsegmentationSDD::GetPadCxz(Int_t timebin,Int_t anode,
239 Float_t &x ,Float_t &z) const{
240 // Transform from cell to real local coordinates
241 // returns x, z in cm
243 // the +0.5 means that an # and time bin # should start from 0 !!!
244 // the +0.5 means that an # and time bin # should start from 0 !!!
246 Float_t driftpath=GetDriftTimeFromTb(timebin)*fDriftSpeed;
247 if (anode < fNanodes/2){ // left side, positive x
248 x=(fDx-driftpath)*fgkMicron2Cm;
249 }else{ // right side, negative x
250 x = -(fDx-driftpath)*fgkMicron2Cm;
252 z=GetLocalZFromAnode(anode);
255 AliWarning("Drift speed not set: x coord. is dummy");
258 //----------------------------------------------------------------------
259 void AliITSsegmentationSDD::GetPadTxz(Float_t &x,Float_t &z) const{
260 // Get anode and time bucket as floats - numbering from 0
262 // expects x, z in cm
266 Float_t driftpath=fDx-TMath::Abs(fgkCm2Micron*xloc);
267 x=driftpath/fDriftSpeed/fTimeStep;
268 if (xloc < 0) x = -x;
269 z=GetAnodeFromLocal(xloc,zloc);
272 AliWarning("Drift speed not set: x coord. is dummy");
275 //----------------------------------------------------------------------
276 void AliITSsegmentationSDD::Print(Option_t *opt) const {
277 // Print SDD segmentation Parameters
279 cout << "**************************************************" << endl;
280 cout << " Silicon Drift Detector Segmentation Parameters " << opt << endl;
281 cout << "**************************************************" << endl;
282 cout << "Number of Time Samples: " << fNsamples << endl;
283 cout << "Number of Anodes: " << fNanodes << endl;
284 cout << "Time Step (ns): " << fTimeStep << endl;
285 cout << "Anode Pitch (um): " << fPitch << endl;
286 cout << "Full Detector Width (x): " << fDx;
287 cout<<" (Default is "<<fgkDxDefault<<") "<<endl;
288 cout << "Half Detector Length (z): " << fDz;
289 cout<<" (Default is "<<fgkDzDefault<<") "<<endl;
290 cout << "Full Detector Thickness (y): " << fDy;
291 cout<<" (Default is "<<fgkDyDefault<<") "<<endl;
292 cout << "**************************************************" << endl;
296 //----------------------------------------------------------------------
297 void AliITSsegmentationSDD::PrintDefaultParameters() const {
298 // print SDD parameters defined as static const data members
300 cout << "**************************************************" << endl;
301 cout << " Silicon Drift Detector Segmentation Parameters " << endl;
302 cout << " Default values defined as static const data members"<< endl;
303 cout << " Actual values can be set with the relevant setters"<< endl;
304 cout << "**************************************************" << endl;
305 cout<<"fgkDxDefault = "<<fgkDxDefault<<endl;
306 cout<<"fgkDzDefault = "<<fgkDzDefault<<endl;
307 cout<<"fgkDyDefault = "<<fgkDyDefault<<endl;
308 cout<<"fgkPitchDefault = "<<fgkPitchDefault<<endl;
309 cout<<"fgkClockDefault = "<<fgkClockDefault<<endl;
310 cout<<"fgkHalfNanodesDefault = "<<fgkHalfNanodesDefault<<endl;
311 cout<<"fgkNsamplesDefault = "<<fgkNsamplesDefault<<endl;
312 cout << "**************************************************" << endl;
316 //______________________________________________________________________
317 Bool_t AliITSsegmentationSDD::LocalToDet(Float_t x,Float_t z,
318 Int_t &ix,Int_t &iz) const {
319 // Transformation from Geant detector centered local coordinates (cm) to
320 // time bucket numbers ix and anode number iz.
322 // Float_t x detector local coordinate x in cm with respect to the
323 // center of the sensitive volume.
324 // Float_t z detector local coordinate z in cm with respect to the
325 // center of the sensitive volulme.
327 // Int_t ix detector x time coordinate. Has the range 0<=ix<fNsamples.
328 // Int_t iz detector z anode coordinate. Has the range 0<=iz<fNandoes.
329 // A value of -1 for ix or iz indecates that this point is outside of the
330 // detector segmentation as defined.
334 ix = -1; // default values
335 iz = -1; // default values
336 dx = -fgkMicron2Cm*Dx(); // lower left edge in cm.
337 dz = -0.5*fgkMicron2Cm*Dz(); // lower left edge in cm.
339 AliWarning(Form("Input argument %f out of range (%f, %f)",x,dx,-dx));
340 return kFALSE; // outside of defined volume.
343 AliWarning(Form("Input argument %f out of range (%f, %f)",z,dz,-dz));
344 return kFALSE; // outside of defined volume.
346 GetPadIxz(x,z,ix,iz);
349 AliWarning("Drift speed not set: timebin is dummy");
352 return kTRUE; // Found ix and iz, return.
354 //______________________________________________________________________
355 void AliITSsegmentationSDD::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const
357 // Transformation from Detector time bucket and anode coordiantes to Geant
358 // detector centerd local coordinates (cm).
360 // Int_t ix detector x time coordinate. Has the range 0<=ix<fNsamples.
361 // Int_t iz detector z anode coordinate. Has the range 0<=iz<fNandoes.
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 // If ix and or iz is outside of the segmentation range a value of -Dx()
368 // or -0.5*Dz() is returned.
372 if(ix<0 || ix>=Npx()) {
373 AliWarning(Form("Input argument %d out of range (0, %d)",ix,Npx()));
374 return; // outside of detector
376 if(iz<0 || iz>=Npz()) {
377 AliWarning(Form("Input argument %d out of range (0, %d)",iz,Npz()));
378 return; // outside of detctor
380 GetPadCxz(ix,iz,x,z);
383 AliWarning("Drift speed not set: x coord. is dummy");
385 return; // Found x and z, return.