Line data Source code
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 :
16 : /* $Id$ */
17 :
18 : #include <Riostream.h>
19 : #include <TMath.h>
20 : #include <TGeoManager.h>
21 : #include <TGeoVolume.h>
22 : #include <TGeoBBox.h>
23 : #include "AliITSsegmentationSSD.h"
24 :
25 : //////////////////////////////////////////////////////
26 : // Segmentation class for //
27 : // silicon strips //
28 : // //
29 : //////////////////////////////////////////////////////
30 : const Float_t AliITSsegmentationSSD::fgkDxDefault = 73000.;
31 : const Float_t AliITSsegmentationSSD::fgkDzDefault = 40000.;
32 : const Float_t AliITSsegmentationSSD::fgkDyDefault = 300.;
33 : const Float_t AliITSsegmentationSSD::fgkPitchDefault = 95.;
34 : const Int_t AliITSsegmentationSSD::fgkNstripsDefault = 768;
35 : const Int_t AliITSsegmentationSSD::fgkNchipsPerSide = 6;
36 : const Int_t AliITSsegmentationSSD::fgkNstripsPerChip = 128;
37 :
38 : using std::endl;
39 : using std::cout;
40 118 : ClassImp(AliITSsegmentationSSD)
41 :
42 9 : AliITSsegmentationSSD::AliITSsegmentationSSD(Option_t *opt): AliITSsegmentation(),
43 9 : fNstrips(0),
44 9 : fStereoP(0),
45 9 : fStereoN(0),
46 9 : fPitch(0),
47 54 : fLayer(0){
48 : // default constructor
49 9 : SetDetSize(fgkDxDefault,fgkDzDefault,fgkDyDefault);
50 9 : SetPadSize(fgkPitchDefault,0.);
51 9 : SetNPads(fgkNstripsDefault,0);
52 9 : SetAngles();
53 18 : if(strstr(opt,"TGeo")){
54 0 : if(!gGeoManager){
55 0 : AliError("Geometry is not initialized\n");
56 : return;
57 : }
58 : TGeoVolume *v=NULL;
59 0 : v = gGeoManager->GetVolume("ITSssdSensitivL5");
60 0 : if(!v){
61 0 : AliWarning("TGeo volumeITSssdSensitivL5 not found (hint: use v11Hybrid geometry)\n Using hardwired default values");
62 : }
63 : else {
64 0 : TGeoBBox *s=(TGeoBBox*)v->GetShape();
65 0 : SetDetSize(s->GetDX()*20000.,s->GetDZ()*20000.,s->GetDY()*20000.);
66 : }
67 0 : }
68 18 : }
69 :
70 : //______________________________________________________________________
71 : void AliITSsegmentationSSD::Copy(TObject &obj) const {
72 : // protected method. copy this to obj
73 0 : AliITSsegmentation::Copy(obj);
74 0 : ((AliITSsegmentationSSD& ) obj).Clear();
75 0 : ((AliITSsegmentationSSD& ) obj).fNstrips = fNstrips;
76 0 : ((AliITSsegmentationSSD& ) obj).fStereoP = fStereoP;
77 0 : ((AliITSsegmentationSSD& ) obj).fStereoN = fStereoN;
78 0 : ((AliITSsegmentationSSD& ) obj).fLayer = fLayer;
79 0 : ((AliITSsegmentationSSD& ) obj).fPitch = fPitch;
80 0 : ((AliITSsegmentationSSD& ) obj).fLayer = fLayer;
81 :
82 0 : }
83 :
84 : //______________________________________________________________________
85 : AliITSsegmentationSSD& AliITSsegmentationSSD::operator=(
86 : const AliITSsegmentationSSD &source){
87 : // Operator =
88 0 : if(this != &source){
89 0 : source.Copy(*this);
90 0 : }
91 0 : return *this;
92 : }
93 : //______________________________________________________________________
94 : AliITSsegmentationSSD::AliITSsegmentationSSD(const AliITSsegmentationSSD &source):
95 0 : AliITSsegmentation(source),
96 0 : fNstrips(0),
97 0 : fStereoP(0),
98 0 : fStereoN(0),
99 0 : fPitch(0),
100 0 : fLayer(0){
101 : // copy constructor
102 0 : source.Copy(*this);
103 0 : }
104 : //----------------------------------------------------------------------
105 : void AliITSsegmentationSSD::Init(){
106 : // standard initalizer
107 :
108 0 : SetPadSize(fgkPitchDefault,0.);
109 0 : SetNPads(fgkNstripsDefault,0);
110 0 : SetAngles();
111 0 : }
112 : //----------------------------------------------------------------------
113 : void AliITSsegmentationSSD::Angles(Float_t &aP,Float_t &aN) const{
114 : // P and N side stereo angles
115 0 : aP = fStereoP;
116 0 : aN = fStereoN;
117 0 : }
118 : //----------------------------------------------------------------------
119 : void AliITSsegmentationSSD::SetLayer(Int_t l){
120 : //set fLayer data member (only 5 or 6 are allowed)
121 4004 : if (l==5) fLayer =5;
122 1322 : else if (l==6) fLayer =6;
123 0 : else AliError(Form("Layer can be 5 or 6, not %d",l));
124 1555 : }
125 : //----------------------------------------------------------------------
126 : void AliITSsegmentationSSD::GetPadTxz(Float_t &x,Float_t &z) const{
127 : // returns P and N sided strip numbers for a given location.
128 : // Transformation from microns detector center local coordinates
129 : // to detector P and N side strip numbers..
130 : /* _- Z
131 : + angle / ^
132 : fNstrips v | N-Side ...0
133 : \-------/------------|-----------\--------\
134 : |\\\\\\/////////////.|\\\\\\\\\\\\\\\\\\\\|
135 : |0\\\\/////////////..|.\\\\\\\\\\\\\\\\\\\|
136 : |00\\/////////////...|..\\\\\\\\\\\\\\\\\\|
137 : X <--|000/////////////... |...\\\\\\\\\\\\\\\\\|
138 : |00/////////////... | ...\\\\\\\\\\\\\\\\|
139 : |0/////////////... | ...\\\\\\\\\\\\\\\|
140 : |//////////////... | ...\\\\\\\\\\\\\\\|
141 : /-----\--------------|--------------------/
142 : fNstrips-1 P-Side ...0
143 : |0\
144 : |00\
145 : Dead region: |000/
146 : |00/
147 : |0/
148 : // expects x, z in cm
149 : */
150 :
151 : /*
152 : Float_t stereoP, stereoN;
153 : Angles(stereoP,stereoN);
154 : Float_t tanP = TMath::Tan(stereoP);
155 : Float_t tanN = TMath::Tan(-stereoN);
156 : Float_t x1 = x;
157 : Float_t z1 = z;
158 : x1 += fDx/2;
159 : z1 += fDz/2;
160 : x = (x1 - z1*tanP)/fPitch;
161 : z = (x1 - tanN*(z1 - fDz))/fPitch;
162 : */
163 :
164 : Float_t tP=0;
165 : Float_t tN=0;
166 17698 : if(fLayer==5) {
167 4818 : tP = 105.26*x - 0.7895*z + 382.000; //- 0.79*z + 381.89;
168 4818 : tN = tP + 3.684*z - 4;
169 4818 : }
170 4031 : else if(fLayer==6) {
171 4031 : tP = -105.26*x - 0.7895*z + 385.000; //- 0.79*z + 384.66;
172 4031 : tN = tP + 3.684*z + 4;
173 4031 : }
174 0 : else AliError("Layer can be 5 or 6");
175 :
176 8849 : x=tP;
177 8849 : z=tN;
178 :
179 8849 : }
180 : //----------------------------------------------------------------------
181 : void AliITSsegmentationSSD::GetPadIxz(Float_t x,Float_t z,Int_t &iP,Int_t &iN) const {
182 : // returns P and N sided strip numbers for a given location.
183 : // expects x, z in cm
184 :
185 1160 : GetPadTxz(x,z);
186 1160 : iP = Int_t(x+0.5);
187 1160 : iN = Int_t(z+0.5);
188 1160 : }
189 : //-------------------------------------------------------
190 : void AliITSsegmentationSSD::GetPadCxz(Float_t iP,Float_t iN,Float_t &x,Float_t &z) const {
191 : // actually this is the GetCrossing(Float_t &,Float_t &)
192 : // returns local x, z in cm
193 : const Float_t kStartXzero=3.64325;
194 : const Float_t kDeltaXzero5or6=0.02239;
195 : const Float_t kDeltaZ5to6=7.6/7.0;
196 :
197 1296 : z = 1.9*(iN-iP)/7.0;
198 648 : x = kStartXzero-(285*iN + 1045*iP)/140000.0;
199 :
200 648 : if (fLayer==5){
201 326 : z += kDeltaZ5to6;
202 326 : x = -x + kDeltaXzero5or6;
203 326 : }
204 322 : else if (fLayer==6) {
205 322 : z -= kDeltaZ5to6;
206 322 : x += kDeltaXzero5or6;
207 322 : }
208 : else {
209 0 : AliWarning("Layer shoudl be 5 or 6");
210 0 : x = -99999;
211 0 : z = -99999;
212 : }
213 648 : }
214 : //______________________________________________________________________
215 : Bool_t AliITSsegmentationSSD::LocalToDet(Float_t x,Float_t z,
216 : Int_t &iP,Int_t &iN) const {
217 : // Transformation from Geant cm detector center local coordinates
218 : // to detector P and N side strip numbers..
219 : /* _- Z
220 : + angle / ^
221 : fNstrips v | N-Side ...0
222 : \-------/------------|-----------\--------\
223 : |\\\\\\/////////////.|\\\\\\\\\\\\\\\\\\\\|
224 : |0\\\\/////////////..|.\\\\\\\\\\\\\\\\\\\|
225 : |00\\/////////////...|..\\\\\\\\\\\\\\\\\\|
226 : X <--|000/////////////... |...\\\\\\\\\\\\\\\\\|
227 : |00/////////////... | ...\\\\\\\\\\\\\\\\|
228 : |0/////////////... | ...\\\\\\\\\\\\\\\|
229 : |//////////////... | ...\\\\\\\\\\\\\\\|
230 : /-----\--------------|--------------------/
231 : fNstrips-1 P-Side ...0
232 : |0\
233 : |00\
234 : Dead region: |000/
235 : |00/
236 : |0/
237 : */
238 : Float_t dx,dz;
239 : const Double_t kconst = 1.0E-04; // convert microns to cm.
240 3320 : dx = 0.5*kconst*Dx();
241 3320 : dz = 0.5*kconst*Dz();
242 6640 : if( (x<-dx) || (x>dx) ) {
243 0 : iP=-1;
244 0 : AliWarning(Form("Input argument %f out of range (%f, %f)",x,dx,-dx));
245 0 : return kFALSE; // outside of defined volume.
246 : } // outside x range.
247 6640 : if( (z<-dz) || (z>dz) ) {
248 0 : iN=-1;
249 0 : AliWarning(Form("Input argument %f out of range (%f, %f)",z,dz,-dz));
250 0 : return kFALSE; // outside of defined volume.
251 : }
252 :
253 : //x /= kconst; // convert to microns
254 : //z /= kconst; // convert to microns
255 3320 : this->GetPadTxz(x,z);
256 :
257 : // first for P side
258 3320 : iP = (Int_t) x;
259 6664 : if(iP<0 || iP>=fNstrips) iP=-1; // strip number must be in range.
260 : // Now for N side)
261 3320 : iN = (Int_t) z;
262 6686 : if(iN<0 || iN>=fNstrips) iN=-1; // strip number must be in range.
263 3320 : return kTRUE;
264 3320 : }
265 : //----------------------------------------------------------------------
266 : void AliITSsegmentationSSD::DetToLocal(Int_t ix,Int_t iPN,
267 : Float_t &x,Float_t &z) const{
268 : // Transformation from detector segmentation/cell coordiantes starting
269 : // from 0. iPN=0 for P side and 1 for N side strip. Returned is z=0.0
270 : // and the corresponding x value..
271 : /* _- Z
272 : + angle / ^
273 : fNstrips v | N-Side ...0
274 : \-------/------------|-----------\--------\
275 : |\\\\\\/////////////.|\\\\\\\\\\\\\\\\\\\\|
276 : |0\\\\/////////////..|.\\\\\\\\\\\\\\\\\\\|
277 : |00\\/////////////...|..\\\\\\\\\\\\\\\\\\|
278 : X <--|000/////////////... |...\\\\\\\\\\\\\\\\\|
279 : |00/////////////... | ...\\\\\\\\\\\\\\\\|
280 : |0/////////////... | ...\\\\\\\\\\\\\\\|
281 : |//////////////... | ...\\\\\\\\\\\\\\\|
282 : /-----\--------------|--------------------/
283 : fNstrips-1 P-Side ...0
284 : |0\
285 : |00\
286 : Dead region: |000/
287 : |00/
288 : |0/
289 : */
290 : // for strips p-side
291 : // x = a + b + z*tan(fStereoP); a = Dpx(iP)*(iP+0.5)-dx; b = dz*th;
292 : // for strips n-side
293 : // x = a + b + z*tan(fStereoP); a = Dpx(iN)*(iN+0.5)-dx; b = -dz*th;
294 0 : AliWarning("This function has not been verified. Should probably use GetPadCxz");
295 : const Double_t kconst = 1.0E-04; // convert microns to cm.
296 0 : Float_t flag=kconst*Dx(); // error value
297 0 : Double_t th=0.0,dx,dz,i,a,b=0.0,xb[4],zb[4];
298 0 : Float_t stereoP, stereoN;
299 0 : Angles(stereoP,stereoN);
300 :
301 0 : z = 0.0; // Strip center in z.
302 0 : if(iPN<0 || iPN>1){// if error return full detector size in x.
303 0 : x = z = flag;
304 0 : return;
305 : } // end if
306 0 : if(ix<0 || ix>=fNstrips) { // if error return full detector size in x.
307 0 : x = z = flag;
308 0 : return;
309 : } // end if
310 0 : i = (Double_t) ix; // convert to double
311 0 : dx = 0.5*kconst*Dx(); // half distance in x in cm
312 0 : dz = 0.5*kconst*Dz(); // half distance in z in cm
313 0 : a = kconst*Dpx(ix)*(i+0.5)-dx; // Min x value.
314 0 : if(iPN==0){ //P-side angle defined backwards.
315 0 : th = TMath::Tan(stereoP);
316 0 : b = dz*th;
317 0 : }else if(iPN==1){ // N-side
318 0 : th = TMath::Tan(-stereoN);
319 0 : b = -dz*th;
320 0 : } // end if
321 : // compute average/center position of the strip.
322 0 : xb[0] = +dx; if(th!=0.0) zb[0] = (+dx-a-b)/th; else zb[0] = 0.0;
323 0 : xb[1] = -dx; if(th!=0.0) zb[1] = (-dx-a-b)/th; else zb[1] = 0.0;
324 0 : xb[2] = a+b+dz*th; zb[2] = +dz;
325 0 : xb[3] = a+b-dz*th; zb[3] = -dz;
326 0 : x = 0.0; z = 0.0;
327 0 : for(Int_t j=0;j<4;j++){
328 0 : if(xb[j]>=-dx && xb[j]<=dx && zb[j]>=-dz && zb[j]<=dz){
329 0 : x += xb[j];
330 0 : z += zb[j];
331 0 : } // end if
332 : } // end for
333 0 : x *= 0.5;
334 0 : z *= 0.5;
335 0 : return;
336 0 : }
337 : //----------------------------------------------------------------------
338 : Int_t AliITSsegmentationSSD::GetChipFromChannel(Int_t ix, Int_t iz) const {
339 : // returns chip number (in range 0-11) starting from channel number
340 :
341 12696 : if( (iz>=fgkNstripsDefault) || (iz<0) || (ix<0) || (ix>1) ) {
342 0 : AliError("Bad cell number");
343 0 : return -1;
344 : }
345 :
346 9522 : if(ix==1) iz = 1535-iz;
347 6348 : Int_t theChip =iz/fgkNstripsPerChip;
348 : return theChip;
349 :
350 6348 : }
351 : //----------------------------------------------------------------------
352 : Int_t AliITSsegmentationSSD::GetChipFromLocal(Float_t xloc, Float_t zloc) const
353 : {
354 : // returns chip numbers starting from local coordinates
355 : // The two Nside chip number and Pside chip number are
356 : // coded as chip=Nchip*10+Pchip
357 :
358 6640 : Int_t iP=0;
359 3320 : Int_t iN=0;
360 9814 : if (!LocalToDet(xloc,zloc,iP,iN) ||
361 9728 : (iP<0) || (iP>=fNstrips) || (iN<0) || (iN>=fNstrips) ) {
362 : //AliWarning("Bad local coordinate");
363 146 : return -1;
364 : }
365 :
366 3174 : Int_t iChip = GetChipFromChannel(0,iP);
367 3174 : iChip += 10*GetChipFromChannel(1,iN); // add Nside
368 :
369 : return iChip;
370 :
371 3320 : }
372 : //
373 :
374 : Int_t AliITSsegmentationSSD::GetChipsInLocalWindow(Int_t* array, Float_t zmin, Float_t zmax,
375 : Float_t xmin, Float_t xmax) const {
376 : // returns chip number in a given xz window
377 :
378 : Int_t nChipInW = 0;
379 :
380 1660 : Float_t zminDet=-fDz*1.0E-04/2.;
381 830 : Float_t zmaxDet=fDz*1.0E-04/2.;
382 830 : if(zmin<zminDet) zmin=zminDet;
383 830 : if(zmax>zmaxDet) zmax=zmaxDet;
384 :
385 830 : Float_t xminDet=-fDx*1.0E-04/2;
386 830 : Float_t xmaxDet=fDx*1.0E-04/2;
387 830 : if(xmin<xminDet) xmin=xminDet;
388 830 : if(xmax>xmaxDet) xmax=xmaxDet;
389 :
390 : Int_t n1N=-1;
391 : Int_t n1P=-1;
392 830 : Int_t n1=GetChipFromLocal(xmin,zmin);
393 830 : if(n1!=-1) { // Note! Recpoint can be on the sensor but in the dead area not covered by strips!
394 756 : n1N = (Int_t) (n1/10); // N-side chip coded as 10*chip_index
395 756 : n1P = n1 - 10 * n1N; // P-side chip coded 0-5
396 756 : array[nChipInW]=n1P;
397 : nChipInW++;
398 756 : array[nChipInW]=n1N;
399 : nChipInW++;
400 756 : }
401 :
402 : Int_t n2N=-1;
403 : Int_t n2P=-1;
404 830 : Int_t n2=GetChipFromLocal(xmin,zmax);
405 830 : if(n2!=-1) { // Note! Recpoint can be on the sensor but in the dead area not covered by strips!
406 762 : n2N = (Int_t) (n2/10); // N-side chip coded as 10*chip_index
407 762 : n2P = n2 - 10 * n2N; // P-side chip coded 0-5
408 774 : if(n2P!=n1P) { array[nChipInW]=n2P; nChipInW++;}
409 798 : if(n2N!=n1N) { array[nChipInW]=n2N; nChipInW++;}
410 : }
411 :
412 : Int_t n3N=-1;
413 : Int_t n3P=-1;
414 830 : Int_t n3=GetChipFromLocal(xmax,zmin);
415 830 : if(n3!=-1) {
416 828 : n3N=(Int_t) (n3/10); // N-side chip coded as 10*chip_index
417 828 : n3P=n3 - 10 * n3N; // P-side chip coded 0-5
418 1620 : if((n3P!=n1P)&&(n3P!=n2P)) { array[nChipInW]=n3P; nChipInW++;}
419 1632 : if((n3N!=n1N)&&(n3N!=n2N)) { array[nChipInW]=n3N; nChipInW++;}
420 : }
421 :
422 : Int_t n4N=-1;
423 : Int_t n4P=-1;
424 830 : Int_t n4=GetChipFromLocal(xmax,zmax);
425 830 : if(n4!=-1) {
426 828 : n4N=(Int_t) (n4/10); // N-side chip coded as 10*chip_index
427 828 : n4P=n4 - 10 * n4N; // P-side chip coded 0-5
428 1612 : if((n4P!=n1P)&&(n4P!=n2P)&&(n4P!=n3P)) { array[nChipInW]=n4P; nChipInW++;}
429 1672 : if((n4N!=n1N)&&(n4N!=n2N)&&(n4N!=n3N)) { array[nChipInW]=n4N; nChipInW++;}
430 : }
431 :
432 830 : return nChipInW;
433 :
434 : }
435 :
436 : //----------------------------------------------------------------------
437 : void AliITSsegmentationSSD::PrintDefaultParameters() const {
438 : // Print default values for parameters.
439 : // Values specified as static const data members are shown
440 :
441 0 : cout<<"fgkDxDefault = "<<fgkDxDefault<<endl;
442 0 : cout<<"fgkDzDefault = "<<fgkDzDefault<<endl;
443 0 : cout<<"fgkDyDefault = "<<fgkDyDefault<<endl;
444 0 : cout<<"fgkPitchDefault = "<<fgkPitchDefault<<endl;
445 0 : cout<<"fgkNstripsDefault = "<<fgkNstripsDefault<<endl;
446 0 : }
|