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