]>
Commit | Line | Data |
---|---|---|
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 | ClassImp(AliITSsegmentationSSD) | |
41 | ||
42 | AliITSsegmentationSSD::AliITSsegmentationSSD(Option_t *opt): AliITSsegmentation(), | |
43 | fNstrips(0), | |
44 | fStereoP(0), | |
45 | fStereoN(0), | |
46 | fPitch(0), | |
47 | fLayer(0){ | |
48 | // default constructor | |
49 | SetDetSize(fgkDxDefault,fgkDzDefault,fgkDyDefault); | |
50 | SetPadSize(fgkPitchDefault,0.); | |
51 | SetNPads(fgkNstripsDefault,0); | |
52 | SetAngles(); | |
53 | if(strstr(opt,"TGeo")){ | |
54 | if(!gGeoManager){ | |
55 | AliError("Geometry is not initialized\n"); | |
56 | return; | |
57 | } | |
58 | TGeoVolume *v=NULL; | |
59 | v = gGeoManager->GetVolume("ITSssdSensitivL5"); | |
60 | if(!v){ | |
61 | AliWarning("TGeo volumeITSssdSensitivL5 not found (hint: use v11Hybrid geometry)\n Using hardwired default values"); | |
62 | } | |
63 | else { | |
64 | TGeoBBox *s=(TGeoBBox*)v->GetShape(); | |
65 | SetDetSize(s->GetDX()*20000.,s->GetDZ()*20000.,s->GetDY()*20000.); | |
66 | } | |
67 | } | |
68 | } | |
69 | ||
70 | //______________________________________________________________________ | |
71 | void AliITSsegmentationSSD::Copy(TObject &obj) const { | |
72 | // protected method. copy this to obj | |
73 | AliITSsegmentation::Copy(obj); | |
74 | ((AliITSsegmentationSSD& ) obj).Clear(); | |
75 | ((AliITSsegmentationSSD& ) obj).fNstrips = fNstrips; | |
76 | ((AliITSsegmentationSSD& ) obj).fStereoP = fStereoP; | |
77 | ((AliITSsegmentationSSD& ) obj).fStereoN = fStereoN; | |
78 | ((AliITSsegmentationSSD& ) obj).fLayer = fLayer; | |
79 | ((AliITSsegmentationSSD& ) obj).fPitch = fPitch; | |
80 | ((AliITSsegmentationSSD& ) obj).fLayer = fLayer; | |
81 | ||
82 | } | |
83 | ||
84 | //______________________________________________________________________ | |
85 | AliITSsegmentationSSD& AliITSsegmentationSSD::operator=( | |
86 | const AliITSsegmentationSSD &source){ | |
87 | // Operator = | |
88 | if(this != &source){ | |
89 | source.Copy(*this); | |
90 | } | |
91 | return *this; | |
92 | } | |
93 | //______________________________________________________________________ | |
94 | AliITSsegmentationSSD::AliITSsegmentationSSD(const AliITSsegmentationSSD &source): | |
95 | AliITSsegmentation(source), | |
96 | fNstrips(0), | |
97 | fStereoP(0), | |
98 | fStereoN(0), | |
99 | fPitch(0), | |
100 | fLayer(0){ | |
101 | // copy constructor | |
102 | source.Copy(*this); | |
103 | } | |
104 | //---------------------------------------------------------------------- | |
105 | void AliITSsegmentationSSD::Init(){ | |
106 | // standard initalizer | |
107 | ||
108 | SetPadSize(fgkPitchDefault,0.); | |
109 | SetNPads(fgkNstripsDefault,0); | |
110 | SetAngles(); | |
111 | } | |
112 | //---------------------------------------------------------------------- | |
113 | void AliITSsegmentationSSD::Angles(Float_t &aP,Float_t &aN) const{ | |
114 | // P and N side stereo angles | |
115 | aP = fStereoP; | |
116 | aN = fStereoN; | |
117 | } | |
118 | //---------------------------------------------------------------------- | |
119 | void AliITSsegmentationSSD::SetLayer(Int_t l){ | |
120 | //set fLayer data member (only 5 or 6 are allowed) | |
121 | if (l==5) fLayer =5; | |
122 | else if (l==6) fLayer =6; | |
123 | else AliError(Form("Layer can be 5 or 6, not %d",l)); | |
124 | } | |
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 | if(fLayer==5) { | |
167 | tP = 105.26*x - 0.7895*z + 382.000; //- 0.79*z + 381.89; | |
168 | tN = tP + 3.684*z - 4; | |
169 | } | |
170 | else if(fLayer==6) { | |
171 | tP = -105.26*x - 0.7895*z + 385.000; //- 0.79*z + 384.66; | |
172 | tN = tP + 3.684*z + 4; | |
173 | } | |
174 | else AliError("Layer can be 5 or 6"); | |
175 | ||
176 | x=tP; | |
177 | z=tN; | |
178 | ||
179 | } | |
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 | GetPadTxz(x,z); | |
186 | iP = Int_t(x+0.5); | |
187 | iN = Int_t(z+0.5); | |
188 | } | |
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 | z = 1.9*(iN-iP)/7.0; | |
198 | x = kStartXzero-(285*iN + 1045*iP)/140000.0; | |
199 | ||
200 | if (fLayer==5){ | |
201 | z += kDeltaZ5to6; | |
202 | x = -x + kDeltaXzero5or6; | |
203 | } | |
204 | else if (fLayer==6) { | |
205 | z -= kDeltaZ5to6; | |
206 | x += kDeltaXzero5or6; | |
207 | } | |
208 | else { | |
209 | AliWarning("Layer shoudl be 5 or 6"); | |
210 | x = -99999; | |
211 | z = -99999; | |
212 | } | |
213 | } | |
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 | dx = 0.5*kconst*Dx(); | |
241 | dz = 0.5*kconst*Dz(); | |
242 | if( (x<-dx) || (x>dx) ) { | |
243 | iP=-1; | |
244 | AliWarning(Form("Input argument %f out of range (%f, %f)",x,dx,-dx)); | |
245 | return kFALSE; // outside of defined volume. | |
246 | } // outside x range. | |
247 | if( (z<-dz) || (z>dz) ) { | |
248 | iN=-1; | |
249 | AliWarning(Form("Input argument %f out of range (%f, %f)",z,dz,-dz)); | |
250 | return kFALSE; // outside of defined volume. | |
251 | } | |
252 | ||
253 | //x /= kconst; // convert to microns | |
254 | //z /= kconst; // convert to microns | |
255 | this->GetPadTxz(x,z); | |
256 | ||
257 | // first for P side | |
258 | iP = (Int_t) x; | |
259 | if(iP<0 || iP>=fNstrips) iP=-1; // strip number must be in range. | |
260 | // Now for N side) | |
261 | iN = (Int_t) z; | |
262 | if(iN<0 || iN>=fNstrips) iN=-1; // strip number must be in range. | |
263 | return kTRUE; | |
264 | } | |
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 | AliWarning("This function has not been verified. Should probably use GetPadCxz"); | |
295 | const Double_t kconst = 1.0E-04; // convert microns to cm. | |
296 | Float_t flag=kconst*Dx(); // error value | |
297 | Double_t th=0.0,dx,dz,i,a,b=0.0,xb[4],zb[4]; | |
298 | Float_t stereoP, stereoN; | |
299 | Angles(stereoP,stereoN); | |
300 | ||
301 | z = 0.0; // Strip center in z. | |
302 | if(iPN<0 || iPN>1){// if error return full detector size in x. | |
303 | x = z = flag; | |
304 | return; | |
305 | } // end if | |
306 | if(ix<0 || ix>=fNstrips) { // if error return full detector size in x. | |
307 | x = z = flag; | |
308 | return; | |
309 | } // end if | |
310 | i = (Double_t) ix; // convert to double | |
311 | dx = 0.5*kconst*Dx(); // half distance in x in cm | |
312 | dz = 0.5*kconst*Dz(); // half distance in z in cm | |
313 | a = kconst*Dpx(ix)*(i+0.5)-dx; // Min x value. | |
314 | if(iPN==0){ //P-side angle defined backwards. | |
315 | th = TMath::Tan(stereoP); | |
316 | b = dz*th; | |
317 | }else if(iPN==1){ // N-side | |
318 | th = TMath::Tan(-stereoN); | |
319 | b = -dz*th; | |
320 | } // end if | |
321 | // compute average/center position of the strip. | |
322 | xb[0] = +dx; if(th!=0.0) zb[0] = (+dx-a-b)/th; else zb[0] = 0.0; | |
323 | xb[1] = -dx; if(th!=0.0) zb[1] = (-dx-a-b)/th; else zb[1] = 0.0; | |
324 | xb[2] = a+b+dz*th; zb[2] = +dz; | |
325 | xb[3] = a+b-dz*th; zb[3] = -dz; | |
326 | x = 0.0; z = 0.0; | |
327 | for(Int_t j=0;j<4;j++){ | |
328 | if(xb[j]>=-dx && xb[j]<=dx && zb[j]>=-dz && zb[j]<=dz){ | |
329 | x += xb[j]; | |
330 | z += zb[j]; | |
331 | } // end if | |
332 | } // end for | |
333 | x *= 0.5; | |
334 | z *= 0.5; | |
335 | return; | |
336 | } | |
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 | if( (iz>=fgkNstripsDefault) || (iz<0) || (ix<0) || (ix>1) ) { | |
342 | AliError("Bad cell number"); | |
343 | return -1; | |
344 | } | |
345 | ||
346 | if(ix==1) iz = 1535-iz; | |
347 | Int_t theChip =iz/fgkNstripsPerChip; | |
348 | return theChip; | |
349 | ||
350 | } | |
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 | Int_t iP=0; | |
359 | Int_t iN=0; | |
360 | if (!LocalToDet(xloc,zloc,iP,iN) || | |
361 | (iP<0) || (iP>=fNstrips) || (iN<0) || (iN>=fNstrips) ) { | |
362 | //AliWarning("Bad local coordinate"); | |
363 | return -1; | |
364 | } | |
365 | ||
366 | Int_t iChip = GetChipFromChannel(0,iP); | |
367 | iChip += 10*GetChipFromChannel(1,iN); // add Nside | |
368 | ||
369 | return iChip; | |
370 | ||
371 | } | |
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 | Float_t zminDet=-fDz*1.0E-04/2.; | |
381 | Float_t zmaxDet=fDz*1.0E-04/2.; | |
382 | if(zmin<zminDet) zmin=zminDet; | |
383 | if(zmax>zmaxDet) zmax=zmaxDet; | |
384 | ||
385 | Float_t xminDet=-fDx*1.0E-04/2; | |
386 | Float_t xmaxDet=fDx*1.0E-04/2; | |
387 | if(xmin<xminDet) xmin=xminDet; | |
388 | if(xmax>xmaxDet) xmax=xmaxDet; | |
389 | ||
390 | Int_t n1N=-1; | |
391 | Int_t n1P=-1; | |
392 | Int_t n1=GetChipFromLocal(xmin,zmin); | |
393 | if(n1!=-1) { // Note! Recpoint can be on the sensor but in the dead area not covered by strips! | |
394 | n1N = (Int_t) (n1/10); // N-side chip coded as 10*chip_index | |
395 | n1P = n1 - 10 * n1N; // P-side chip coded 0-5 | |
396 | array[nChipInW]=n1P; | |
397 | nChipInW++; | |
398 | array[nChipInW]=n1N; | |
399 | nChipInW++; | |
400 | } | |
401 | ||
402 | Int_t n2N=-1; | |
403 | Int_t n2P=-1; | |
404 | Int_t n2=GetChipFromLocal(xmin,zmax); | |
405 | if(n2!=-1) { // Note! Recpoint can be on the sensor but in the dead area not covered by strips! | |
406 | n2N = (Int_t) (n2/10); // N-side chip coded as 10*chip_index | |
407 | n2P = n2 - 10 * n2N; // P-side chip coded 0-5 | |
408 | if(n2P!=n1P) { array[nChipInW]=n2P; nChipInW++;} | |
409 | if(n2N!=n1N) { array[nChipInW]=n2N; nChipInW++;} | |
410 | } | |
411 | ||
412 | Int_t n3N=-1; | |
413 | Int_t n3P=-1; | |
414 | Int_t n3=GetChipFromLocal(xmax,zmin); | |
415 | if(n3!=-1) { | |
416 | n3N=(Int_t) (n3/10); // N-side chip coded as 10*chip_index | |
417 | n3P=n3 - 10 * n3N; // P-side chip coded 0-5 | |
418 | if((n3P!=n1P)&&(n3P!=n2P)) { array[nChipInW]=n3P; nChipInW++;} | |
419 | if((n3N!=n1N)&&(n3N!=n2N)) { array[nChipInW]=n3N; nChipInW++;} | |
420 | } | |
421 | ||
422 | Int_t n4N=-1; | |
423 | Int_t n4P=-1; | |
424 | Int_t n4=GetChipFromLocal(xmax,zmax); | |
425 | if(n4!=-1) { | |
426 | n4N=(Int_t) (n4/10); // N-side chip coded as 10*chip_index | |
427 | n4P=n4 - 10 * n4N; // P-side chip coded 0-5 | |
428 | if((n4P!=n1P)&&(n4P!=n2P)&&(n4P!=n3P)) { array[nChipInW]=n4P; nChipInW++;} | |
429 | if((n4N!=n1N)&&(n4N!=n2N)&&(n4N!=n3N)) { array[nChipInW]=n4N; nChipInW++;} | |
430 | } | |
431 | ||
432 | 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 | cout<<"fgkDxDefault = "<<fgkDxDefault<<endl; | |
442 | cout<<"fgkDzDefault = "<<fgkDzDefault<<endl; | |
443 | cout<<"fgkDyDefault = "<<fgkDyDefault<<endl; | |
444 | cout<<"fgkPitchDefault = "<<fgkPitchDefault<<endl; | |
445 | cout<<"fgkNstripsDefault = "<<fgkNstripsDefault<<endl; | |
446 | } |