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