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