Fix long line
[u/mrichter/AliRoot.git] / TPC / AliTPCv2.cxx
CommitLineData
4c039060 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/*
17$Log$
73042f01 18Revision 1.21.2.4 2000/06/26 07:39:42 kowal2
19Changes to obey the coding rules
20
21Revision 1.21.2.3 2000/06/25 08:38:41 kowal2
22Splitted from AliTPCtracking
23
24Revision 1.21.2.2 2000/06/16 12:58:13 kowal2
25Changed parameter settings
26
27Revision 1.21.2.1 2000/06/09 07:15:07 kowal2
28
29Defaults loaded automatically (hard-wired)
30Optional parameters can be set via macro called in the constructor
31
32Revision 1.21 2000/05/15 10:00:30 kowal2
33Corrected bug in the TPC geometry, thanks to Ivana Hrivnacova
34
e94dd9ca 35Revision 1.20 2000/04/17 09:37:33 kowal2
36removed obsolete AliTPCDigitsDisplay.C
37
cc80f89e 38Revision 1.19.8.2 2000/04/10 08:31:52 kowal2
39
40Different geometry for different sectors
41Updated readout chambers
42Some modifications to StepManager by J.Belikov
43
44Revision 1.19.8.1 2000/04/10 07:56:53 kowal2
45Not used anymore - removed
46
47Revision 1.19 1999/11/04 17:28:07 fca
48Correct barrel part of HV Degrader
49
a5371c42 50Revision 1.18 1999/10/14 16:52:08 fca
51Only use PDG codes and not GEANT ones
52
69e40cce 53Revision 1.17 1999/10/08 06:27:23 fca
54Corrected bug in the HV degrader geometry, thanks to G.Tabary
55
d183a600 56Revision 1.16 1999/10/04 13:39:54 fca
57Correct array index problem
58
cdde5b1e 59Revision 1.15 1999/09/29 09:24:34 fca
60Introduction of the Copyright and cvs Log
61
4c039060 62*/
63
73042f01 64//
fe4da5cc 65///////////////////////////////////////////////////////////////////////////////
66// //
67// Time Projection Chamber version 2 -- detailed TPC and slow simulation //
68// //
69//Begin_Html
70/*
1439f98e 71<img src="picts/AliTPCv2Class.gif">
fe4da5cc 72*/
73//End_Html
74// //
75// //
76///////////////////////////////////////////////////////////////////////////////
2a49965d 77#include <stdlib.h>
fe4da5cc 78
79#include <TMath.h>
bcac8ae4 80
fe4da5cc 81#include "AliTPCv2.h"
cc80f89e 82#include "AliTPCDigitsArray.h"
fe4da5cc 83#include "AliRun.h"
fe4da5cc 84#include "AliConst.h"
69e40cce 85#include "AliPDG.h"
73042f01 86#include "AliTPCParam.h"
87#include "AliTPCParamSR.h"
8c555625 88
fe4da5cc 89ClassImp(AliTPCv2)
90
91//_____________________________________________________________________________
92AliTPCv2::AliTPCv2(const char *name, const char *title) :
93 AliTPC(name, title)
94{
95 //
96 // Standard constructor for Time Projection Chamber version 2
97 //
98 fIdSens1=0;
99 fIdSens2=0;
100 SetBufferSize(128000);
73042f01 101
102 SetGasMixt(2,20,10,-1,0.9,0.1,0.); // Ne-CO2 90-10
103
104 // Default sectors
105
106 SetSecAL(4);
107 SetSecAU(4);
108 SetSecLows(1, 2, 3, 19, 20, 21);
109 SetSecUps(37, 38, 39, 37+18, 38+18, 39+18, -1, -1, -1, -1, -1, -1);
110 SetSens(1); // sensitive strips
111
112 if (fTPCParam)
113 fTPCParam->Write(fTPCParam->GetTitle());
fe4da5cc 114}
115
116//_____________________________________________________________________________
117void AliTPCv2::CreateGeometry()
118{
119 //
120 // Create the geometry of Time Projection Chamber version 2
121 //
122 //Begin_Html
123 /*
1439f98e 124 <img src="picts/AliTPCv2.gif">
fe4da5cc 125 */
126 //End_Html
127 //Begin_Html
128 /*
1439f98e 129 <img src="picts/AliTPCv2Tree.gif">
fe4da5cc 130 */
131 //End_Html
132
8c555625 133
1283eee5 134 Int_t *idtmed = fIdtmed->GetArray();
135
136 Float_t dm[21];
62a73ee5 137 Int_t idrotm[120];
1283eee5 138
139 Int_t nRotMat = 0;
140
73042f01 141 Int_t i,ifl1,ifl2=0;
1283eee5 142
143 Int_t nInnerSector = fTPCParam->GetNInnerSector()/2;
144 Int_t nOuterSector = fTPCParam->GetNOuterSector()/2;
fe4da5cc 145
146 // ---------------------------------------------------
147 // sector specification check
148 // ---------------------------------------------------
149 if (fSecAL >= 0) {
150 ifl1 = 0;
151
152 for (i = 0; i < 6; ++i) {
1283eee5 153 if (fSecLows[i] >= 0 && fSecLows[i] < 2*nInnerSector) {
fe4da5cc 154 ifl1 = 1;
155 printf("*** SECTOR %d selected\n",fSecLows[i]);
156 }
157 }
158
159 } else {
160 printf("*** ALL LOWER SECTORS SELECTED ***\n");
8c555625 161 ifl1 = 1;
fe4da5cc 162 }
163
164 if (fSecAU >= 0) {
165 ifl2 = 0;
166
167 for (i = 0; i < 12; ++i) {
1283eee5 168 if (fSecUps[i] > 2*nInnerSector-1 &&
169 fSecUps[i] < 2*(nInnerSector+nOuterSector)) {
fe4da5cc 170 ifl2 = 1;
171 printf("*** SECTOR %d selected\n",fSecUps[i]);
172 }
173 }
174
175 } else {
176 printf("*** ALL UPPER SECTORS SELECTED ***\n");
8c555625 177 ifl1 = 1;
fe4da5cc 178 }
179
180 if (ifl1 == 0 && ifl2 == 0) {
181 printf("*** ERROR: AT LEAST ONE SECTOR MUST BE SPECIFIED ***\n");
182 printf("!!! PROGRAM STOPPED !!!\n");
183 exit(1);
184 }
185
186 if ((fSecAL < 0 || fSecAU < 0) && fSens >= 0) {
187 printf("** ERROR: STRIPS CANNOT BE SPECIFIED FOR ALL SECTORS **\n");
188 printf("!!! PROGRAM STOPPED !!!\n");
189 exit(1);
190 }
1283eee5 191
fe4da5cc 192 // ----------------------------------------------------
1283eee5 193 // FIELD CAGE WITH ENDCAPS - G10
fe4da5cc 194 // THIS IS ALSO A TPC MOTHER VOLUME
195 // ----------------------------------------------------
1283eee5 196
fe4da5cc 197 dm[0] = 76.;
198 dm[1] = 278.;
199 dm[2] = 275.;
1283eee5 200
201 gMC->Gsvolu("TPC ", "TUBE", idtmed[8], dm, 3);
202
203 //-----------------------------------------------------
204 // Endcap cover c-fibre 0.86% X0
205 //-----------------------------------------------------
206
207 dm[0] = 78.;
208 dm[1] = 258.;
209 dm[2] = 0.95;
210
211 gMC->Gsvolu("TPEC","TUBE",idtmed[10],dm,3);
212
213 //-----------------------------------------------------
214 // Drift gas , leave 2 cm at the outer radius
215 // and inner raddius
216 //-----------------------------------------------------
217
218 dm[0] = 78.;
219 dm[1] = 258.;
fe4da5cc 220 dm[2] = 250.;
1283eee5 221
222 gMC->Gsvolu("TGAS", "TUBE", idtmed[3], dm, 3);
223
224 //------------------------------------------------------
225 // membrane holder - carbon fiber
226 //------------------------------------------------------
227
228
229 gMC->Gsvolu("TPMH","TUBE",idtmed[6],dm,0);
230
231 dm[0] = 252.;
232 dm[1] = 258.;
233 dm[2] = 0.2;
234
235 gMC->Gsposp("TPMH",1,"TGAS",0.,0.,0.,0,"ONLY",dm,3);
236
237 dm[0] = 78.;
cdde5b1e 238 dm[1] = 82.;
1283eee5 239 dm[2] = 0.1;
240
241 gMC->Gsposp("TPMH",2,"TGAS",0.,0.,0.,0,"ONLY",dm,3);
242
243 //----------------------------------------------------------
244 // HV membrane - 25 microns of mylar
245 //----------------------------------------------------------
246
247 dm[0] = 82.;
248 dm[1] = 252.;
249 dm[2] = 0.00125;
250
251 gMC->Gsvolu("TPHV","TUBE",idtmed[5],dm,3);
252
253 gMC->Gspos("TPHV",1,"TGAS",0.,0.,0.,0,"ONLY");
254
255 gMC->Gspos("TGAS",1,"TPC ",0.,0.,0.,0,"ONLY");
256
257 //----------------------------------------------------------
258 // "side" gas volume, the same as the drift gas
259 // the readout chambers are placed there.
260 //----------------------------------------------------------
261
262 dm[0] = 78.;
263 dm[1] = 258.;
264 dm[2] = 0.5*(275. - 250.);
265
266 gMC->Gsvolu("TPSG", "TUBE", idtmed[2], dm, 3);
267
73042f01 268 Float_t zSide = dm[2]; // 1/2 of the side gas thickness
1283eee5 269
cc80f89e 270 //------------------------------------------------------------
1283eee5 271 // Readout chambers , 25% of X0, I use Al as the material
cc80f89e 272 //------------------------------------------------------------
1283eee5 273
73042f01 274 Float_t innerOpenAngle = fTPCParam->GetInnerAngle();
275 Float_t outerOpenAngle = fTPCParam->GetOuterAngle();
1283eee5 276
73042f01 277 Float_t innerAngleShift = fTPCParam->GetInnerAngleShift();
278 Float_t outerAngleShift = fTPCParam->GetOuterAngleShift();
1283eee5 279
73042f01 280 Float_t inSecLowEdge = fTPCParam->GetInnerRadiusLow();
281 Float_t inSecUpEdge = fTPCParam->GetInnerRadiusUp();
1283eee5 282
73042f01 283 Float_t ouSecLowEdge = fTPCParam->GetOuterRadiusLow();
284 Float_t ouSecUpEdge = fTPCParam->GetOuterRadiusUp();
1283eee5 285
286
73042f01 287 Float_t secThick = 2.225; // Al
1283eee5 288
73042f01 289 Float_t lowEdge = fTPCParam->GetInnerFrameSpace();
1283eee5 290
291 // S (Inner) sectors
292
73042f01 293 dm[0] = inSecLowEdge*TMath::Tan(0.5*innerOpenAngle)-lowEdge;
294 dm[1] = inSecUpEdge*TMath::Tan(0.5*innerOpenAngle)-lowEdge;
295 dm[2] = 0.5*secThick;
296 dm[3] = 0.5*(inSecUpEdge-inSecLowEdge);
1283eee5 297
73042f01 298 Float_t xCenterS = inSecLowEdge+dm[3];
1283eee5 299
300 gMC->Gsvolu("TRCS", "TRD1", idtmed[0], dm, 4);
301
302 // L (Outer) sectors
303
73042f01 304 Float_t upEdge = fTPCParam->GetOuterFrameSpace();
cc80f89e 305
73042f01 306 dm[0] = ouSecLowEdge*TMath::Tan(0.5*outerOpenAngle)-upEdge;
307 dm[1] = ouSecUpEdge*TMath::Tan(0.5*outerOpenAngle)-upEdge;
308 dm[2] = 0.5*secThick;
309 dm[3] = 0.5*(ouSecUpEdge-ouSecLowEdge);
1283eee5 310
73042f01 311 Float_t xCenterL = ouSecLowEdge+dm[3];
1283eee5 312
313 gMC->Gsvolu("TRCL", "TRD1", idtmed[0], dm, 4);
314
73042f01 315 Float_t z1 = -zSide + secThick*0.5;
1283eee5 316
317 //------------------------------------------------------------------
318 // S sectors - "gas sectors" (TRD1)
319 //------------------------------------------------------------------
320
73042f01 321 dm[0] = inSecLowEdge*TMath::Tan(0.5*innerOpenAngle)-0.01;
322 dm[1] = inSecUpEdge*TMath::Tan(0.5*innerOpenAngle)-0.01;
1283eee5 323 dm[2] = 0.5*(250. - 0.001);
73042f01 324 dm[3] = 0.5*(inSecUpEdge-inSecLowEdge);
1283eee5 325
326 gMC->Gsvolu("TSGA", "TRD1", idtmed[4], dm, 4); // sensitive
327
fe4da5cc 328 // -------------------------------------------------------------
329 // Only for the debugging purpose and resolution calculation
330 // Sensitive strips at the pad-row center
331 // -------------------------------------------------------------
1283eee5 332
333 Int_t ns;
334
335 if(fSens>=0){
336
337 Float_t r1,r2,zz;
338
73042f01 339 Float_t stripThick = 0.01; // 100 microns
cc80f89e 340 Float_t dead;
1283eee5 341
342 gMC->Gsvolu("TSST", "TRD1", idtmed[4], dm, 0);
343
344 dm[2] = 0.5*(250. - 0.002);
73042f01 345 dm[3] = 0.5 * stripThick;
1283eee5 346
cc80f89e 347 dead= fTPCParam->GetInnerWireMount();
348
1283eee5 349
350 for (ns = 0; ns < fTPCParam->GetNRowLow(); ns++) {
351
352 r1 = fTPCParam->GetPadRowRadiiLow(ns);
73042f01 353 r2 = r1 + stripThick;
354 dm[0] = r1 * TMath::Tan(0.5*innerOpenAngle) - dead;
355 dm[1] = r2 * TMath::Tan(0.5*innerOpenAngle) - dead;
1283eee5 356
73042f01 357 zz = -inSecLowEdge -0.5*(inSecUpEdge-inSecLowEdge);
1283eee5 358 zz += r1;
359 zz += dm[3];
360
361 gMC->Gsposp("TSST", ns+1, "TSGA", 0., 0., zz, 0, "ONLY", dm, 4);
362
fe4da5cc 363
1283eee5 364 }
365
366 gMC->Gsord("TSGA", 3);
367
368 } // if strips selected
369
370
371 //-----------------------------------------------------------------
372 // L sectors - "gas sectors" (PGON to avoid overlaps)
373 //-----------------------------------------------------------------
374
73042f01 375 dm[0] = 360.*kDegrad - 0.5*outerOpenAngle;
1283eee5 376 dm[0] *= kRaddeg;
377 dm[0] = (Float_t)TMath::Nint(dm[0]);
378
73042f01 379 dm[1] = outerOpenAngle*kRaddeg;
1283eee5 380 dm[1] = (Float_t)TMath::Nint(dm[1]);
381
382 dm[2] = 1.;
383 dm[3] = 4.;
384
385 dm[4] = 0.002;
73042f01 386 dm[5] = ouSecLowEdge;
387 dm[6] = 252.*TMath::Cos(0.5*outerOpenAngle)-0.002;
1283eee5 388
389 dm[7] = dm[4]+0.2;
390 dm[8] = dm[5];
391 dm[9] = dm[6];
392
393 dm[10] = dm[7];
73042f01 394 dm[11] = ouSecLowEdge;
395 dm[12] = ouSecUpEdge;
1283eee5 396
397 dm[13] = 250.;
398 dm[14] = dm[11];
399 dm[15] = dm[12];
400
401 gMC->Gsvolu("TLGA","PGON",idtmed[4],dm,16);
8c555625 402
fe4da5cc 403 if (fSens >= 0) {
fe4da5cc 404
1283eee5 405 Float_t rmax = dm[6];
406 Float_t r1,r2;
cc80f89e 407 Float_t dead = fTPCParam->GetOuterWireMount();
8c555625 408
73042f01 409 Float_t stripThick = 0.01; // 100 microns
8c555625 410
1283eee5 411 gMC->Gsvolu("TLST", "PGON", idtmed[4], dm, 0);
412
73042f01 413 dm[0] = 360.*kDegrad - 0.5*outerOpenAngle;
1283eee5 414 dm[0] *= kRaddeg;
415 dm[0] = (Float_t)TMath::Nint(dm[0]);
416
73042f01 417 dm[1] = outerOpenAngle*kRaddeg;
1283eee5 418 dm[1] = (Float_t)TMath::Nint(dm[1]);
8c555625 419
fe4da5cc 420 dm[2] = 1.;
1283eee5 421 dm[3] = 2.;
fe4da5cc 422
1283eee5 423 dm[7] = 250.;
fe4da5cc 424
73042f01 425 Float_t xx = dead/TMath::Tan(0.5*outerOpenAngle);
fe4da5cc 426
1283eee5 427 for(ns=0;ns<fTPCParam->GetNRowUp();ns++){
fe4da5cc 428
1283eee5 429 r1 = fTPCParam->GetPadRowRadiiUp(ns)-xx;
73042f01 430 r2 = r1 + stripThick;
1283eee5 431
432 dm[5] = r1;
433 dm[6] = r2;
434
435 dm[8] = r1;
436 dm[9] = r2;
437
438 if(r2+xx < rmax){
439 dm[4] = 0.002;
fe4da5cc 440 }
1283eee5 441 else{
442 dm[4] = 0.202;
443 }
444
445 gMC->Gsposp("TLST",ns+1,"TLGA",xx,0.,0.,0,"ONLY",dm,10);
446
447 }
448
62a73ee5 449 gMC->Gsord("TLGA", 4);
1283eee5 450
451 } // if strips selected
452
453 //------------------------------------------------------------------
454 // Positioning of the S-sector readout chambers
455 //------------------------------------------------------------------
456
457 Float_t zs = 0.5*(250.+0.002);
458
459 Float_t theta1,theta2,theta3;
460 Float_t phi1,phi2,phi3;
461 Float_t alpha;
462 Float_t x,y;
463
464 for(ns=0;ns<nInnerSector;ns++){
465
73042f01 466 phi1 = ns * innerOpenAngle + 270.*kDegrad + innerAngleShift;
1283eee5 467 phi1 *= kRaddeg; // in degrees
468
469 phi1 = (Float_t)TMath::Nint(phi1);
470
471 if (phi1 > 360.) phi1 -= 360.;
fe4da5cc 472
1283eee5 473 theta1 = 90.;
474 phi2 = 90.;
475 theta2 = 180.;
73042f01 476 phi3 = ns * innerOpenAngle + innerAngleShift;
1283eee5 477 phi3 *= kRaddeg; // in degrees
478
479 phi3 = (Float_t)TMath::Nint(phi3);
fe4da5cc 480
1283eee5 481 if(phi3 > 360.) phi3 -= 360.;
482
483 theta3 = 90.;
484
485 alpha = phi3*kDegrad;
486
487 x = xCenterS * TMath::Cos(alpha);
488 y = xCenterS * TMath::Sin(alpha);
489
490 AliMatrix(idrotm[nRotMat], theta1, phi1, theta2, phi2, theta3, phi3);
491
492 gMC->Gspos("TRCS", ns+1, "TPSG", x, y, z1, idrotm[nRotMat], "ONLY");
493
494 if(fSecAL < 0){
495
496 //---------------------------------------------------------------
497 // position all sectors
498 //---------------------------------------------------------------
499
500 gMC->Gspos("TSGA",ns+1,"TGAS",x,y,zs,idrotm[nRotMat], "ONLY");
501 gMC->Gspos("TSGA",ns+1+nInnerSector,"TGAS",x,y,-zs,idrotm[nRotMat], "ONLY");
fe4da5cc 502 }
1283eee5 503
504 else{
505
506 //---------------------------------------------------------------
507 // position selected sectors
508 //---------------------------------------------------------------
509
510 for(Int_t sel=0;sel<6;sel++){
511
512 if(fSecLows[sel] == ns){
513 gMC->Gspos("TSGA", ns+1, "TGAS", x, y, zs, idrotm[nRotMat], "ONLY");
514 }
515 else if(fSecLows[sel] == ns+nInnerSector){
516 gMC->
517 Gspos("TSGA",ns+1+nInnerSector,"TGAS", x, y,-zs,idrotm[nRotMat],"ONLY");
518 }
fe4da5cc 519 }
fe4da5cc 520 }
1283eee5 521
522 nRotMat++;
523
524 }
fe4da5cc 525
1283eee5 526 //-------------------------------------------------------------------
527 // Positioning of the L-sectors readout chambers
528 //-------------------------------------------------------------------
fe4da5cc 529
1283eee5 530 for(ns=0;ns<nOuterSector;ns++){
73042f01 531 phi1 = ns * outerOpenAngle + 270.*kDegrad + outerAngleShift;
1283eee5 532 phi1 *= kRaddeg; // in degrees
533
534 phi1 = (Float_t)TMath::Nint(phi1);
fe4da5cc 535
1283eee5 536
537 if (phi1 > 360.) phi1 -= 360.;
538
fe4da5cc 539 theta1 = 90.;
1283eee5 540 phi2 = 90.;
541 theta2 = 180.;
73042f01 542 phi3 = ns * outerOpenAngle+outerAngleShift;
1283eee5 543 phi3 *= kRaddeg; // in degrees
fe4da5cc 544
1283eee5 545 phi3 = (Float_t)TMath::Nint(phi3);
fe4da5cc 546
1283eee5 547
548 if(phi3 > 360.) phi3 -= 360.;
549
550 theta3 = 90.;
551
552 alpha = phi3*kDegrad;
553
554 x = xCenterL * TMath::Cos(alpha);
555 y = xCenterL * TMath::Sin(alpha);
556
557 AliMatrix(idrotm[nRotMat], theta1, phi1, theta2, phi2, theta3, phi3);
558
559
560 gMC->Gspos("TRCL", ns+1, "TPSG", x, y, z1, idrotm[nRotMat], "ONLY");
561
562 nRotMat++;
563
564 }
565
566 //-------------------------------------------------------------------
567 // Positioning of the L-sectors (gas sectors)
568 //-------------------------------------------------------------------
569
570 for(ns=0;ns<nOuterSector;ns++){
571
73042f01 572 phi1 = ns*outerOpenAngle + outerAngleShift;
1283eee5 573 phi1 *= kRaddeg;
fe4da5cc 574
1283eee5 575 phi1 = (Float_t)TMath::Nint(phi1);
576 if(phi1>360.) phi1 -= 360.;
577
578 theta1 = 90.;
579
580 phi2 = 90. + phi1;
581 if(phi2>360.) phi2 -= 360.;
582
583 theta2 = 90.;
584
585 phi3 = 0.;
586 theta3 = 0.;
587
588 if(fSecAU < 0) {
589
590 //--------------------------------------------------------------
591 // position all sectors
592 //--------------------------------------------------------------
593
594 AliMatrix(idrotm[nRotMat], theta1, phi1, theta2, phi2, theta3, phi3);
595
596 gMC->Gspos("TLGA",ns+1,"TGAS" ,0.,0.,0.,idrotm[nRotMat],"ONLY");
597
598 nRotMat++;
599
600 // reflection !!
601
602 phi3 = 0.;
603 theta3 = 180.;
604
605 AliMatrix(idrotm[nRotMat], theta1, phi1, theta2, phi2, theta3, phi3);
606
607 gMC->Gspos("TLGA",ns+1+nOuterSector,"TGAS" ,0.,0.,0.,idrotm[nRotMat],"ONLY");
608
609 nRotMat++;
610 }
611
612 else{
613
614 //---------------------------------------------------------------
615 // position selected sectors
616 //---------------------------------------------------------------
617
618 for(Int_t sel=0;sel<12;sel++){
619
620 if(fSecUps[sel] == ns+2*nInnerSector){
621
622 AliMatrix(idrotm[nRotMat], theta1, phi1, theta2, phi2, theta3, phi3);
623 gMC->Gspos("TLGA",ns+1,"TGAS" ,0.,0.,0.,idrotm[nRotMat],"ONLY");
624 nRotMat++;
625
626 }
627 else if(fSecUps[sel] == ns+2*nInnerSector+nOuterSector){
628
629 // reflection
630
631 phi3 = 0.;
632 theta3 = 180.;
633
634 AliMatrix(idrotm[nRotMat], theta1, phi1, theta2, phi2, theta3, phi3);
635 gMC->
636 Gspos("TLGA",ns+1+nOuterSector,"TGAS" ,0.,0.,0.,idrotm[nRotMat],"ONLY");
637 nRotMat++;
638
639 }
640
641 }
642
643 }
644
645 }
646
73042f01 647 Float_t z0 = zSide - 0.95;
1283eee5 648
649 gMC->Gspos("TPEC",1,"TPSG",0.,0.,z0,0,"ONLY");
650
651 // ==========================================================
652 // wheels
653 // ==========================================================
654
655 //
656 // auxilary structures
657 //
658
659
660 gMC->Gsvolu("TPWI","TUBE",idtmed[24],dm,0); // "air"
661
662 // ----------------------------------------------------------
663 // Large wheel -> positioned in the TPC
664 // ----------------------------------------------------------
665
666
667 z0 = 263.5; // TPC length - 1/2 spoke wheel width
668
669 dm[0] = 258.;
670 dm[1] = 278.;
671 dm[2] = 11.5;
672
673 gMC->Gsvolu("TPWL", "TUBE", idtmed[0], dm, 3);
674
675 dm[0] = dm[0]+2.;
676 dm[1] = 278.;
677 dm[2] = dm[2]-2.;
678
679 gMC->Gsposp("TPWI",1,"TPWL",0.,0.,0.,0,"ONLY",dm,3);
680
681 gMC->Gspos("TPWL", 1, "TPC ", 0, 0, z0, 0, "ONLY");
682 gMC->Gspos("TPWL", 2, "TPC ", 0, 0, -z0, 0, "ONLY");
683
684 //
685 // Outer vessel + CO2 HV degrader
686 //
687
688 dm[0] = 260.;
689 dm[1] = 278.;
690 dm[2] = 252.;
691
692 gMC->Gsvolu("TPCO","TUBE",idtmed[12],dm,3);
693
694 dm[0] = 275.;
695 dm[1] = 278.;
696
697 gMC->Gsvolu("TPOV","TUBE",idtmed[10],dm,3);
698
699 gMC->Gspos("TPOV",1,"TPCO",0.,0.,0.,0,"ONLY");
700
701
1283eee5 702
703 gMC->Gspos("TPCO",1,"TPC ",0.,0.,0.,0,"ONLY");
704
705
706 //----------------------------------------------------------
707 // Small wheel -> positioned in "side gas
708 //----------------------------------------------------------
709
710 dm[0] = 78.;
711 dm[1] = 82.;
712 dm[2] = 11.5;
713
714 gMC->Gsvolu("TPWS", "TUBE", idtmed[0], dm, 3);
715
716 dm[0] = 78.;
717 dm[1] = dm[1]-2;
718 dm[2] = dm[2]-2.;
719
720 gMC->Gsvolu("TPW1", "TUBE", idtmed[2], dm, 3);
721
722 gMC->Gspos("TPW1", 1, "TPWS", 0., 0., 0., 0, "ONLY");
723
724 z0 = 1.; // spoke wheel is shifted w.r.t. center of the "side gas"
725
726 gMC->Gspos("TPWS", 1, "TPSG", 0, 0, z0, 0, "ONLY");
727
728
729 // to avoid overlaps
730
731 dm[0] = 76.;
732 dm[1] = 78.;
733 dm[2] = 11.5;
734
735 gMC->Gsvolu("TPS1","TUBE",idtmed[0],dm,3);
736
737 dm[2] = 9.5;
738
739 gMC->Gsvolu("TPS2","TUBE",idtmed[24],dm,3);
740
741 gMC->Gspos("TPS2",1,"TPS1",0.,0.,0.,0,"ONLY");
742
743 z0= 263.5;
744
745 gMC->Gspos("TPS1",1,"TPC ",0.,0.,z0,0,"ONLY");
746 gMC->Gspos("TPS1",2,"TPC ",0.,0.,-z0,0,"ONLY");
747
748 // G10 plug
749
750 dm[0] = 76.;
7d7bb9e5 751 dm[1] = 78.;
752 dm[2] = 1.;
1283eee5 753
754 gMC->Gsvolu("TPG2","TUBE",idtmed[8],dm,3);
755
756 z0 = 251.;
757
758 gMC->Gspos("TPG2",1,"TPC ",0.,0.,z0,0,"ONLY");
759 gMC->Gspos("TPG2",2,"TPC ",0.,0.,-z0,0,"ONLY");
760
761
762 //---------------------------------------------------------
763 // central wheel 6 (radial direction) x 4 (along z) cm2
764 //---------------------------------------------------------
765
766 dm[0] = 140.;
767 dm[1] = 146.;
768 dm[2] = 2.;
769
770 gMC->Gsvolu("TPWC","TUBE",idtmed[0],dm,3);
771
772 dm[0] = dm[0] + 2.;
773 dm[1] = dm[1] - 2.;
774 dm[2] = dm[2] - 1.;
775
776 gMC->Gsposp("TPWI",2,"TPWC",0.,0.,0.,0,"ONLY",dm,3);
777
73042f01 778 z0 = zSide - 1.9 - 2.;
1283eee5 779
780 gMC->Gspos("TPWC",1,"TPSG",0.,0.,z0,0,"ONLY");
781
782 //
783
784 gMC->Gsvolu("TPSE","BOX ",idtmed[24],dm,0); // "empty" part of the spoke
785
786
787 //---------------------------------------------------------
788 // inner spokes (nSectorInner)
789 //---------------------------------------------------------
790
791 dm[0] = 0.5*(139.9-82.1);
792 dm[1] = 3.;
793 dm[2] = 2.;
794
795 Float_t x1 = dm[0]+82.;
796
797 gMC->Gsvolu("TPSI","BOX",idtmed[0],dm,3);
798
799 dm[1] = dm[1]-1.;
800 dm[2] = dm[2]-1.;
801
802 gMC->Gsposp("TPSE",1,"TPSI",0.,0.,0.,0,"ONLY",dm,3);
803
804 for(ns=0;ns<nInnerSector;ns++){
805
73042f01 806 phi1 = 0.5*innerOpenAngle + ns*innerOpenAngle + innerAngleShift;
1283eee5 807 theta1=90.;
808 phi1 *=kRaddeg;
809
810 phi1 = (Float_t)TMath::Nint(phi1);
811 if(phi1>360.) phi1 -= 360.;
812
813 phi2 = phi1+90.;
814 if(phi2>360.) phi2 -= 360.;
815 theta2=90.;
816 phi3=0.;
817 theta3=0.;
818
819 alpha = phi1 * kDegrad;
820 x = x1 * TMath::Cos(alpha);
821 y = x1 * TMath::Sin(alpha);
822
823 AliMatrix(idrotm[nRotMat],theta1,phi1,theta2,phi2,theta3,phi3);
824
825 gMC->Gspos("TPSI",ns+1,"TPSG",x,y,z0,idrotm[nRotMat],"ONLY");
826
827 nRotMat++;
828
829 }
830
831 //-------------------------------------------------------------
832 // outer spokes (nSectorOuter)
833 //-------------------------------------------------------------
834
835 dm[0] = 0.5*(257.9-146.1);
836 dm[1] = 3.;
837 dm[2] = 2.;
838
839 x1 = dm[0] + 146.;
840
841 gMC->Gsvolu("TPSO","BOX ",idtmed[0],dm,3);
842
843 dm[1] = dm[1] - 1.;
844 dm[2] = dm[2] - 1.;
845
846 gMC->Gsposp("TPSE",2,"TPSO",0.,0.,0.,0,"ONLY",dm,3);
847
848 for(ns=0;ns<nOuterSector;ns++){
849
73042f01 850 phi1 = 0.5*outerOpenAngle + ns*outerOpenAngle + outerAngleShift;
1283eee5 851 theta1=90.;
852 phi1 *=kRaddeg;
853
854 phi1 = (Float_t)TMath::Nint(phi1);
855 if(phi1>360.) phi1 -= 360.;
856
857 phi2 = phi1+90.;
858 if(phi2>360.) phi2 -= 360.;
859 theta2=90.;
860 phi3=0.;
861 theta3=0.;
862
863 alpha = phi1 * kDegrad;
864 x = x1 * TMath::Cos(alpha);
865 y = x1 * TMath::Sin(alpha);
866
867 AliMatrix(idrotm[nRotMat],theta1,phi1,theta2,phi2,theta3,phi3);
868
869 gMC->Gspos("TPSO",ns+1,"TPSG",x,y,z0,idrotm[nRotMat],"ONLY");
870
871 nRotMat++;
872
873 }
874
875
876
877 // --------------------------------------------------------
878 // put the readout chambers into the TPC
879 // --------------------------------------------------------
880
881 theta1 = 90.;
882 phi1 = 0.;
883 theta2 = 90.;
884 phi2 = 270.;
885 theta3 = 180.;
886 phi3 = 0.;
887
888 AliMatrix(idrotm[nRotMat], theta1, phi1, theta2, phi2, theta3, phi3);
889
73042f01 890 z0 = zSide + 250.;
1283eee5 891
892 gMC->Gspos("TPSG", 1, "TPC ", 0, 0, z0, 0, "ONLY");
893 gMC->Gspos("TPSG", 2, "TPC ", 0, 0, -z0, idrotm[nRotMat], "ONLY");
894
895 gMC->Gspos("TPC ", 1, "ALIC", 0, 0, 0, 0, "ONLY");
896
897 //----------------------------------------------------
898 // Inner vessel and HV degrader
899 //----------------------------------------------------
900
901 dm[0] = 0.;
902 dm[1] = 360.;
903 dm[2] = 4.;
904
905 dm[3] = -250.;
906 dm[4] = 74.4;
907 dm[5] = 76.;
908
909 dm[6] = -64.5;
910 dm[7] = 50.;
911 dm[8] = 76.;
912
d183a600 913 dm[9] = 64.5;
1283eee5 914 dm[10] = 50.;
915 dm[11] = 76.;
916
917 dm[12] = 250.;
918 dm[13] = 74.4;
919 dm[14] = 76.;
920
921 gMC->Gsvolu("TPVD", "PCON", idtmed[12], dm, 15); // CO2
922
923 // cone parts
924
925 dm[0] = 0.;
926 dm[1] = 360.;
927 dm[2] = 2.;
928
929 dm[3] = 64.5;
930 dm[4] = 50.;
931 dm[5] = 51.6;
932
933 dm[6] = 250.;
934 dm[7] = 74.4;
935 dm[8] = 76.;
936
937
938 gMC->Gsvolu("TIVC","PCON",idtmed[11],dm,9); // C-fibre
939
940 gMC->Gspos("TIVC",1,"TPVD",0.,0.,0.,0,"ONLY");
941 gMC->Gspos("TIVC",2,"TPVD",0.,0.,0.,idrotm[nRotMat],"ONLY");
942
943 // barrel part
944
945 dm[0] = 50.;
946 dm[1] = 50.5;
a5371c42 947 dm[2] = 64.5;
1283eee5 948
949 gMC->Gsvolu("TIVB","TUBE",idtmed[9],dm,3);
950
951 gMC->Gspos("TIVB",1,"TPVD",0.,0.,0.,0,"ONLY");
952
953 gMC->Gspos("TPVD",1,"ALIC",0.,0.,0.,0,"ONLY");
954
955
956 // ---------------------------------------------------
957 // volumes ordering
958 // ---------------------------------------------------
959
960 gMC->Gsord("TGAS", 6);
961 gMC->Gsord("TPSG", 6);
962
963
964
965} // end of function
fe4da5cc 966
967//_____________________________________________________________________________
8c555625 968void AliTPCv2::DrawDetector()
fe4da5cc 969{
970 //
971 // Draw a shaded view of the Time Projection Chamber version 1
972 //
973
fe4da5cc 974 // Set everything unseen
cfce8870 975 gMC->Gsatt("*", "seen", -1);
fe4da5cc 976 //
977 // Set ALIC mother transparent
cfce8870 978 gMC->Gsatt("ALIC","SEEN",0);
fe4da5cc 979 //
980 // Set the volumes visible
cfce8870 981 gMC->Gsatt("TPC","SEEN",0);
982 gMC->Gsatt("TGAS","SEEN",0);
983 gMC->Gsatt("TPSG","SEEN",0);
984 gMC->Gsatt("TPHV","SEEN",1);
1283eee5 985 gMC->Gsatt("TPMH","SEEN",1);
986 gMC->Gsatt("TPEC","SEEN",0);
cfce8870 987 gMC->Gsatt("TRCS","SEEN",1);
988 gMC->Gsatt("TRCL","SEEN",1);
1283eee5 989 gMC->Gsatt("TPWL","SEEN",1);
990 gMC->Gsatt("TPWI","SEEN",1);
991 gMC->Gsatt("TPWS","SEEN",1);
cfce8870 992 gMC->Gsatt("TPW1","SEEN",1);
1283eee5 993 gMC->Gsatt("TPS1","SEEN",1);
994 gMC->Gsatt("TPS2","SEEN",1);
995 gMC->Gsatt("TPG1","SEEN",1);
996 gMC->Gsatt("TPG2","SEEN",1);
997 gMC->Gsatt("TPWC","SEEN",1);
998 gMC->Gsatt("TPSI","SEEN",1);
999 gMC->Gsatt("TPSO","SEEN",1);
1000 gMC->Gsatt("TPCO","SEEN",1);
1001 gMC->Gsatt("TPOV","SEEN",1);
cfce8870 1002 gMC->Gsatt("TPVD","SEEN",1);
fe4da5cc 1003 //
cfce8870 1004 gMC->Gdopt("hide", "on");
1005 gMC->Gdopt("shad", "on");
1006 gMC->Gsatt("*", "fill", 7);
1007 gMC->SetClipBox(".");
1008 gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000);
1009 gMC->DefaultRange();
1010 gMC->Gdraw("alic", 40, 30, 0, 12, 9.5, .025, .025);
1011 gMC->Gdhead(1111, "Time Projection Chamber");
1012 gMC->Gdman(18, 4, "MAN");
1013 gMC->Gdopt("hide","off");
fe4da5cc 1014}
1015
1016//_____________________________________________________________________________
1017void AliTPCv2::CreateMaterials()
1018{
1019 //
1020 // Define materials for version 2 of the Time Projection Chamber
1021 //
1022
fe4da5cc 1023 //
1024 // Increase maximum number of steps
cfce8870 1025 gMC->SetMaxNStep(30000);
fe4da5cc 1026 //
1027 AliTPC::CreateMaterials();
1028}
1029
1030//_____________________________________________________________________________
1031void AliTPCv2::Init()
1032{
1033 //
1034 // Initialises version 2 of the TPC after that it has been built
1035 //
ad51aeb0 1036 Int_t *idtmed = fIdtmed->GetArray()-399;
fe4da5cc 1037 AliTPC::Init();
cfce8870 1038 fIdSens1=gMC->VolId("TLGA"); // L-sector
1039 fIdSens2=gMC->VolId("TSGA"); // S-sector
1040 fIdSens3=gMC->VolId("TSST"); // strip - S-sector (not always used)
1041 fIdSens4=gMC->VolId("TLST"); // strip - S-sector (not always used)
fe4da5cc 1042
cfce8870 1043 gMC->SetMaxNStep(30000); // max. number of steps increased
fe4da5cc 1044
cfce8870 1045 gMC->Gstpar(idtmed[403],"LOSS",5);
fe4da5cc 1046
1047 printf("*** TPC version 2 initialized ***\n");
cfce8870 1048 printf("Maximum number of steps = %d\n",gMC->GetMaxNStep());
fe4da5cc 1049
1050 //
1051
1052}
1053
1054//_____________________________________________________________________________
1055void AliTPCv2::StepManager()
1056{
1057 //
1058 // Called for every step in the Time Projection Chamber
1059 //
1060
1061 //
1062 // parameters used for the energy loss calculations
1063 //
73042f01 1064 const Float_t kprim = 14.35; // number of primary collisions per 1 cm
1065 const Float_t kpoti = 20.77e-9; // first ionization potential for Ne/CO2
1066 const Float_t kwIon = 35.97e-9; // energy for the ion-electron pair creation
fe4da5cc 1067
1068
73042f01 1069 const Float_t kbig = 1.e10;
fe4da5cc 1070
1071 Int_t id,copy;
1072 Float_t hits[4];
1073 Int_t vol[2];
1074 TClonesArray &lhits = *fHits;
0a6d8768 1075 TLorentzVector pos;
fe4da5cc 1076
1077 vol[1]=0;
1078
1079 //
1080
73042f01 1081 gMC->SetMaxStep(kbig);
fe4da5cc 1082
0a6d8768 1083 if(!gMC->IsTrackAlive()) return; // particle has disappeared
fe4da5cc 1084
cfce8870 1085 Float_t charge = gMC->TrackCharge();
fe4da5cc 1086
1087 if(TMath::Abs(charge)<=0.) return; // take only charged particles
1088
1089
0a6d8768 1090 id=gMC->CurrentVolID(copy);
fe4da5cc 1091
1092 // Check the sensitive volume
1093
1094 if(id == fIdSens1)
1095 {
1283eee5 1096 vol[0] = copy + fTPCParam->GetNInnerSector()-1; // L-sector number
fe4da5cc 1097 }
1098 else if(id == fIdSens2)
1099 {
1283eee5 1100 vol[0] = copy-1; // S-sector number
fe4da5cc 1101 }
0a6d8768 1102 else if(id == fIdSens3 && gMC->IsTrackEntering())
fe4da5cc 1103 {
1283eee5 1104 vol[1] = copy-1; // row number
0a6d8768 1105 id = gMC->CurrentVolOffID(1,copy);
1283eee5 1106 vol[0] = copy-1; // sector number (S-sector)
cc80f89e 1107
1108 //I.Belikov's modification
1109 if (vol[1]==0) {
1110 gMC->TrackMomentum(pos);
1111 hits[0]=pos[0];
1112 hits[1]=pos[1];
1113 hits[2]=pos[2];
1114 hits[3]=0.; // this hit has no energy loss
1115 new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits);
1116 }
1117 //end of I.Belikov's modification
fe4da5cc 1118
0a6d8768 1119 gMC->TrackPosition(pos);
1120 hits[0]=pos[0];
1121 hits[1]=pos[1];
1122 hits[2]=pos[2];
fe4da5cc 1123 hits[3]=0.; // this hit has no energy loss
1124 new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits);
1125 }
0a6d8768 1126 else if(id == fIdSens4 && gMC->IsTrackEntering())
fe4da5cc 1127 {
1283eee5 1128 vol[1] = copy-1; // row number
0a6d8768 1129 id = gMC->CurrentVolOffID(1,copy);
1283eee5 1130 vol[0] = copy+fTPCParam->GetNInnerSector()-1; // sector number (L-sector)
cc80f89e 1131
1132 //I.Belikov's modification
1133 if (vol[1]==0) {
1134 gMC->TrackMomentum(pos);
1135 hits[0]=pos[0];
1136 hits[1]=pos[1];
1137 hits[2]=pos[2];
1138 hits[3]=0.; // this hit has no energy loss
1139 new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits);
1140 }
1141 //end of I.Belikov's modification
fe4da5cc 1142
0a6d8768 1143 gMC->TrackPosition(pos);
1144 hits[0]=pos[0];
1145 hits[1]=pos[1];
1146 hits[2]=pos[2];
fe4da5cc 1147 hits[3]=0.; // this hit has no energy loss
1148 new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits);
1149 }
1150 else return;
1151
1152 //
1153 // charged particle is in the sensitive volume
1154 //
1155
cfce8870 1156 if(gMC->TrackStep() > 0) {
fe4da5cc 1157
73042f01 1158 Int_t nel = (Int_t)(((gMC->Edep())-kpoti)/kwIon) + 1;
fe4da5cc 1159 nel=TMath::Min(nel,300); // 300 electrons corresponds to 10 keV
1160
0a6d8768 1161 gMC->TrackPosition(pos);
1162 hits[0]=pos[0];
1163 hits[1]=pos[1];
1164 hits[2]=pos[2];
fe4da5cc 1165 hits[3]=(Float_t)nel;
1166
1167 // Add this hit
1168
1169 new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits);
1170
1171 }
1172
1173 // Stemax calculation for the next step
1174
1175 Float_t pp;
0a6d8768 1176 TLorentzVector mom;
1177 gMC->TrackMomentum(mom);
1178 Float_t ptot=mom.Rho();
73042f01 1179 Float_t betaGamma = ptot/gMC->TrackMass();
fe4da5cc 1180
69e40cce 1181 Int_t pid=gMC->TrackPid();
cc80f89e 1182 if((pid==kElectron || pid==kPositron) && ptot > 0.002)
fe4da5cc 1183 {
73042f01 1184 pp = kprim*1.58; // electrons above 20 MeV/c are on the plateau!
fe4da5cc 1185 }
1186 else
1187 {
73042f01 1188 pp=kprim*BetheBloch(betaGamma);
fe4da5cc 1189 if(TMath::Abs(charge) > 1.) pp *= (charge*charge);
1190 }
1191
1192 Float_t random[1];
cfce8870 1193 gMC->Rndm(random,1); // good, old GRNDM from Geant3
fe4da5cc 1194
1195 Double_t rnd = (Double_t)random[0];
1196
cfce8870 1197 gMC->SetMaxStep(-TMath::Log(rnd)/pp);
fe4da5cc 1198
1199}
1200
1201//_____________________________________________________________________________
1202Float_t AliTPCv2::BetheBloch(Float_t bg)
1203{
1204 //
1205 // Bethe-Bloch energy loss formula
1206 //
73042f01 1207 const Double_t kp1=0.76176e-1;
1208 const Double_t kp2=10.632;
1209 const Double_t kp3=0.13279e-4;
1210 const Double_t kp4=1.8631;
1211 const Double_t kp5=1.9479;
fe4da5cc 1212
1213 Double_t dbg = (Double_t) bg;
1214
1215 Double_t beta = dbg/TMath::Sqrt(1.+dbg*dbg);
1216
73042f01 1217 Double_t aa = TMath::Power(beta,kp4);
1218 Double_t bb = TMath::Power(1./dbg,kp5);
fe4da5cc 1219
73042f01 1220 bb=TMath::Log(kp3+bb);
fe4da5cc 1221
73042f01 1222 return ((Float_t)((kp2-aa-bb)*kp1/aa));
fe4da5cc 1223}
73042f01 1224
1225