new geometry from WT with module size 6.4x6.4 and shifted inner ring by 2cm
[u/mrichter/AliRoot.git] / FIT / AliFITv1.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 /////////////////////////////////////////////////////////////////////
18 //                                                                 //
19 // FIT detector full geometry  version 1                             //
20 //
21 //Begin Html       
22 /*
23 <img src="gif/AliFITv1Class.gif">
24 */
25 //End Html
26 //                                                                  //
27 //                                                                  //
28 //////////////////////////////////////////////////////////////////////
29
30 #include <Riostream.h>
31 #include <stdlib.h>
32
33 #include "TGeoCompositeShape.h"
34 #include "TGeoManager.h"
35 #include "TGeoMatrix.h"
36 #include "TGeoVolume.h"
37 #include "TGeoTube.h"
38 #include "TGeoBBox.h"
39 #include "TGeoNode.h"
40
41
42 #include <TGeoGlobalMagField.h>
43 #include <TGraph.h>
44 #include <TLorentzVector.h>
45 #include <TMath.h>
46 #include <TVirtualMC.h>
47 #include <TString.h>
48
49 #include "AliLog.h"
50 #include "AliMagF.h"
51 #include "AliRun.h"
52
53 #include "AliFITHits.h"
54 #include "AliFITv1.h"
55
56 #include "AliMC.h"
57 #include "AliCDBLocal.h"
58 #include "AliCDBStorage.h"
59 #include "AliCDBManager.h"
60 #include "AliCDBEntry.h"
61 #include "AliTrackReference.h"
62
63 ClassImp(AliFITv1)
64
65
66 //--------------------------------------------------------------------
67 AliFITv1::AliFITv1():  AliFIT(),
68                      fIdSens1(0),
69                      fPMTeff(0x0)
70
71 {
72   //
73   // Standart constructor for T0 Detector version 0
74 }
75 //--------------------------------------------------------------------
76 AliFITv1::AliFITv1(const char *name, const char *title):
77   AliFIT(name,title),
78   fIdSens1(0),
79   fPMTeff(0x0)
80
81 {
82   //
83   // Standart constructor for T0 Detector version 0
84   //
85   fIshunt = 2; 
86   SetPMTeff();
87 }
88 //_____________________________________________________________________________
89
90 AliFITv1::~AliFITv1() 
91 {
92   // desctructor  
93 }
94
95 //-------------------------------------------------------------------------
96 void AliFITv1::CreateGeometry()
97 {
98   //
99   // Create the geometry of FIT Detector version 1 full geometry
100   //
101   // begin Html
102   //
103
104   Int_t *idtmed = fIdtmed->GetArray();
105   Float_t zdetC = 85; //center of mother volume
106   Float_t zdetA = 333;
107   
108   Int_t idrotm[999];
109   Double_t x,y,z;
110   Float_t pstartC[3] = {6., 20 ,5};
111   Float_t pstartA[3] = {2.55, 20 ,5};
112   // Float_t pinstart[3] = {3.2,3.2,3.9};
113   Float_t pinstart[3] = {3.2,3.2,4.};
114   Float_t  pmcp[3] = {3.19, 3.19, 2.8}; //MCP
115   Float_t ptop[3] = {1.324, 1.324, 1.};//cherenkov radiator
116   Float_t preg[3] = {1.324, 1.324, 0.05};//photcathode 
117  
118   Float_t zV0A = 329.;
119   Float_t pV0Amother[3] = {4.25, 41.25, 0.6};
120   Float_t pV0A[3] = {4.3, 41.2, 0.5};
121
122   AliMatrix(idrotm[901], 90., 0., 90., 90., 180., 0.);
123   
124   //-------------------------------------------------------------------
125   //  T0 volume 
126   //-------------------------------------------------------------------
127   //C side
128
129
130   Float_t xc[20] = {9.6,  16, -9.6, -16, 9.6, 16,
131                     -9.6, -16, -9.6, -3.2, 3.2, 9.6,
132                     -9.6, -3.2, 3.2, 9.6, -3.2, 3.2, 
133                     -3.2, 3.2};
134   
135   Float_t yc[20] = {3.2, 3.2, 3.2, 3.2, -3.2, -3.2, 
136                     -3.2, -3.2, 9.6, 9.6, 9.6, 9.6,
137                     -9.6, -9.6, -9.6, -9.6, 16, 16,
138                     -16, -16};
139   
140   // A side
141   Float_t xa[20] = {0.0, 0.0, 0.0, 0.0, 6.4,
142                     6.4, 6.4, 6.4, 6.4,
143                     -6.4, -6.4, -6.4, -6.4, -6.4,
144                     12.8, 12.8, 12.8, 
145                     -12.8, -12.8, -12.8};
146   
147   Float_t ya[20] = { 6.4, 12.8, -6.4, -12.8,
148                      0, 6.4, 12.8, -6.4,
149                      -12.8, 0., 6.4, 12.8,
150                      -6.4, -12.8, 0, 6.4,
151                      -6.4, 0.0, 6.4, -6.4};  
152   
153   Float_t zc[20] = {2,0, 2,0, 2,0, 2,0, 2,2, 2,2, 2,2, 2,2, 0,0,0,0};
154   Float_t za[20] = {2,0, 2,0, 2,2, 0,2, 0,2, 2,0, 2,0, 0,0, 0,0,0,0};
155   
156    
157   TGeoVolumeAssembly * stlinA = new TGeoVolumeAssembly("0STL");  // A side mother 
158   TGeoVolumeAssembly * stlinC = new TGeoVolumeAssembly("0STR");  // C side mother 
159  //T0 interior
160   TVirtualMC::GetMC()->Gsvolu("0INS","BOX",idtmed[kAir],pinstart,3);
161   TGeoVolume *ins = gGeoManager->GetVolume("0INS");
162  // 
163   TGeoTranslation *tr[40];
164   TString nameTr;
165   //C side
166   for (Int_t itr=0; itr<20; itr++) {
167     nameTr = Form("0TR%i",itr+1);
168     z=-pstartA[2]+pinstart[2]+za[itr];
169     tr[itr] = new TGeoTranslation(nameTr.Data(),xa[itr],ya[itr], z );
170     printf(" A %f %f %f \n",xa[itr], ya[itr], z+zdetA);
171     tr[itr]->RegisterYourself();
172     stlinA->AddNode(ins,itr,tr[itr]);
173     z=-pstartC[2]+pinstart[2]+zc[itr];
174     tr[itr+20] = new TGeoTranslation(nameTr.Data(),xc[itr],yc[itr], z );
175     tr[itr+20]->RegisterYourself();
176     stlinC->AddNode(ins,itr+20,tr[itr+20]);
177     printf(" C %f %f %f \n",xc[itr], yc[itr], z+zdetC);
178   }
179   TGeoVolume *alice = gGeoManager->GetVolume("ALIC");
180   alice->AddNode(stlinA,1,new TGeoTranslation(0,0, zdetA ) );
181   //  alice->AddNode(stlinC,1,new TGeoTranslation(0,0, zdetC ) );
182   TGeoRotation * rotC = new TGeoRotation( "rotC",90., 0., 90., 90., 180., 0.);
183   alice->AddNode(stlinC,1, new TGeoCombiTrans(0., 0., -zdetC , rotC) );
184   
185   x=0;
186   y=0;
187    
188   // Entry window (glass)
189   TVirtualMC::GetMC()->Gsvolu("0TOP","BOX",idtmed[kOpGlass],ptop,3); //glass
190   TGeoVolume *top = gGeoManager->GetVolume("0TOP");
191   TVirtualMC::GetMC()->Gsvolu ("0REG", "BOX", idtmed[kOpGlassCathode], preg, 3); 
192   TGeoVolume *cat = gGeoManager->GetVolume("0REG");
193   TVirtualMC::GetMC()->Gsvolu("0MCP","BOX",idtmed[kGlass],pmcp,3); //glass
194   TGeoVolume *mcp = gGeoManager->GetVolume("0MCP");
195  
196   Int_t ntops=0;
197    Float_t xin=0, yin=0;
198    for (Int_t ix=0; ix<2; ix++) {
199      xin = - pinstart[0] + 0.55 + (ix+0.5)*2*ptop[0] ;
200      for (Int_t iy=0; iy<2 ; iy++) {
201        z = - pinstart[2]+ptop[2];
202        yin = - pinstart[1] + 0.55 + (iy+0.5)*2*ptop[1];
203        ntops++;
204        ins->AddNode(top, ntops, new TGeoTranslation(xin,yin,z) );
205        // printf(" 0TOP  full x %f y %f z %f \n", xin, yin, z);
206        z = -pinstart[2] + 2 * ptop[2] + preg[2];
207        ins->AddNode(cat, ntops, new TGeoTranslation(xin,yin,z) );
208
209        // printf(" GEOGEO  %i %i %i %f %f %f %f %f %f \n", ntops, ix, iy,
210        //  xin,yin,x1[ntops],y1[ntops],x1[ntops]+xin,y1[ntops]+yin);
211      }
212    }
213 // MCP
214    z=-pinstart[2] + 2*ptop[2] + 2*preg[2] + pmcp[2];
215   ins->AddNode(mcp, 1 , new TGeoTranslation(0,0,z) );
216 /*
217   //V0A 
218    TVirtualMC::GetMC()->Gsvolu("0V0AM","TUBE",idtmed[kAir],pV0Amother,3);
219    TVirtualMC::GetMC()->Gspos ("0V0AM",1, "ALIC", 0,0,zV0A , 0, "ONLY");
220    TVirtualMC::GetMC()->Gsvolu("0V0A","TUBE",idtmed[kSensAir],pV0A,3);
221    TVirtualMC::GetMC()->Gspos ("0V0A",1, "0V0AM", 0, 0, 0, 0, "ONLY");
222 */
223
224  
225 }    
226 //------------------------------------------------------------------------
227 void AliFITv1::AddAlignableVolumes() const
228 {
229   //
230   // Create entries for alignable volumes associating the symbolic volume
231   // name with the corresponding volume path. Needs to be syncronized with
232   // eventual changes in the geometry.
233   //
234   TString volPath;
235   TString symName, sn;
236   TString vpAalign = "/ALIC_1/0STL_1";
237   TString vpCalign = "/ALIC_1/0STR_1";
238   for (Int_t imod=0; imod<2; imod++)  {
239     if (imod==0) {volPath  = vpCalign; symName="/ALIC_1/0STL"; }
240     if (imod==1) {volPath  = vpAalign; symName="/ALIC_1/0STR"; }
241     
242     AliDebug(2,"--------------------------------------------");
243     AliDebug(2,Form("volPath=%s\n",volPath.Data()));
244     AliDebug(2,Form("symName=%s\n",symName.Data()));
245     AliDebug(2,"--------------------------------------------");
246     if(!gGeoManager->SetAlignableEntry(symName.Data(),volPath.Data()))
247       AliFatal(Form("Alignable entry %s not created. Volume path %s not valid",
248 symName.Data(),volPath.Data()));
249    }
250 }   
251 //------------------------------------------------------------------------
252 void AliFITv1::CreateMaterials()
253 {
254
255    Int_t isxfld   = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
256    Float_t sxmgmx = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
257    //   Float_t a,z,d,radl,absl,buf[1];
258    // Int_t nbuf;
259 // AIR
260                                                                                 
261    Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
262    Float_t zAir[4]={6.,7.,8.,18.};
263    Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
264    Float_t dAir = 1.20479E-3;
265    Float_t dAir1 = 1.20479E-11;
266  // Radiator  glass SiO2
267    Float_t aglass[2]={28.0855,15.9994};
268    Float_t zglass[2]={14.,8.};
269    Float_t wglass[2]={1.,2.};
270    Float_t dglass=2.65;
271  // MCP glass SiO2
272    Float_t dglass_mcp=1.3;
273 //*** Definition Of avaible T0 materials ***
274    AliMixture(1, "Vacuum$", aAir, zAir, dAir1,4,wAir);
275    AliMixture(2, "Air$", aAir, zAir, dAir,4,wAir);
276    AliMixture( 4, "MCP glass   $",aglass,zglass,dglass_mcp,-2,wglass);
277    AliMixture( 24, "Radiator Optical glass$",aglass,zglass,dglass,-2,wglass);
278    
279    AliMedium(1, "Air$", 2, 0, isxfld, sxmgmx, 10., .1, 1., .003, .003);
280    AliMedium(3, "Vacuum$", 1, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
281    AliMedium(6, "Glass$", 4, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
282   
283    AliMedium(16, "OpticalGlass$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .003);
284     AliMedium(19, "OpticalGlassCathode$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .003);
285    AliMedium(22, "SensAir$", 2, 1, isxfld, sxmgmx, 10., .1, 1., .003, .003);
286    
287    AliDebugClass(1,": ++++++++++++++Medium set++++++++++");
288    
289    
290 }
291
292 //-------------------------------------------------------------------
293 void AliFITv1::DefineOpticalProperties()
294 {
295
296
297 // Optical properties definition.
298    Int_t *idtmed = fIdtmed->GetArray();
299 // Definition Cherenkov parameters
300    int i;
301    const Int_t kNbins=31;
302    
303    Float_t rindexSiO2[kNbins],  efficAll[kNbins], rindexAir[kNbins], absorAir[kNbins],rindexCathodeNext[kNbins], absorbCathodeNext[kNbins];
304    Double_t efficMet[kNbins], aReflMet[kNbins];
305            
306    // quartz 20mm
307    Float_t aAbsSiO2[kNbins]={29.0, 28.6, 28.3, 27.7, 27.3, 26.7, 26.4, 
308                              25.9, 25.3, 24.9, 24.5, 23.7, 
309                              23.2, 22.8, 22.4, 21.8, 21.3,
310                              22.8, 22.1, 21.7, 21.2, 20.5, 
311                              19.9, 19.3, 18.7, 18.0, 17.1, 
312                              16.3, 15.3, 14.3, 14.3   };
313           
314    Float_t aPckov[kNbins]  ={3.87, 3.94, 4.02, 4.11, 4.19, 4.29, 4.38,
315                              4.48, 4.58, 4.69, 4.81, 4.93, 
316                              5.05, 5.19, 5.33, 5.48, 5.63,
317                              5.8,  5.97, 6.16, 6.36, 6.57, 
318                              6.8,  7.04, 7.3,  7.58, 7.89, 
319                              8.22, 8.57, 8.97, 9.39 };  
320   Double_t dPckov[kNbins]  ={3.87, 3.94, 4.02, 4.11, 4.19, 4.29, 4.38,
321                              4.48, 4.58, 4.69, 4.81, 4.93,
322                              5.05, 5.19, 5.33, 5.48, 5.63,
323                              5.8,  5.97, 6.16, 6.36, 6.57,
324                              6.8,  7.04, 7.3,  7.58, 7.89,
325                              8.22, 8.57, 8.97, 9.39 };
326
327    /*     
328    Float_t effCathode[kNbins]={0.11, 0.13, 0.15, 0.16, 0.18, 0.19, 0.20,
329                               0.21, 0.22, 0.23, 0.24, 0.26, 
330                               0.27, 0.29, 0.30, 0.29, 0.29, 
331                               0.28, 0.28, 0.27, 0.26, 0.25, 
332                               0.25, 0.23, 0.20, 0.19, 0.17,
333                               0.17, 0.17, 0.2, 0.23};
334    */     
335    //  Float_t aAbsSiO2[kNbins]; //quartz 30mm
336  for(i=0;i<kNbins;i++)
337
338     {
339       aPckov[i]=aPckov[i]*1e-9;//Photons energy bins 4 eV - 8.5 eV step 0.1 eV
340       dPckov[i]=dPckov[i]*1e-9;//Photons energy bins 4 eV - 8.5 eV step 0.1 eV 
341       //      rindexAir[i]=0.0001;
342       rindexAir[i] = 1.;
343       rindexSiO2[i]=1.458; //refractive index for qwarts
344       rindexCathodeNext[i]=0;
345       efficAll[i]=1.;
346       efficMet[i]=0.;
347       aReflMet[i]=1.;
348       //      aAbsSiO2[i]=28.5; //quartz 30mm
349       absorAir[i]=0.3;      
350       absorbCathodeNext[i]=0;
351
352     }
353   
354   TVirtualMC::GetMC()->SetCerenkov (idtmed[kOpGlass], kNbins, aPckov, aAbsSiO2, efficAll, rindexSiO2 );
355    // TVirtualMC::GetMC()->SetCerenkov (idtmed[kOpGlassCathode], kNbins, aPckov, aAbsSiO2, effCathode, rindexSiO2 );
356    TVirtualMC::GetMC()->SetCerenkov (idtmed[kOpGlassCathode], kNbins, aPckov, aAbsSiO2,efficAll , rindexSiO2 );
357    //  TVirtualMC::GetMC()->SetCerenkov (idtmed[kOpAir], kNbins, aPckov,absorAir , efficAll,rindexAir );
358    //   TVirtualMC::GetMC()->SetCerenkov (idtmed[kOpAirNext], kNbins, aPckov,absorbCathodeNext , efficAll, rindexCathodeNext);
359
360    //Define a boarder for radiator optical properties
361    TVirtualMC::GetMC()->DefineOpSurface("surfRd", kUnified /*kGlisur*/,kDielectric_metal,kPolished, 0.);
362    TVirtualMC::GetMC()->SetMaterialProperty("surfRd", "EFFICIENCY", kNbins, dPckov, efficMet);
363    TVirtualMC::GetMC()->SetMaterialProperty("surfRd", "REFLECTIVITY", kNbins, dPckov, aReflMet);
364
365
366 }
367
368 //-------------------------------------------------------------------
369 void AliFITv1::Init()
370 {
371 // Initialises version 0 of the Forward Multiplicity Detector
372 //
373   AliFIT::Init();
374   fIdSens1=TVirtualMC::GetMC()->VolId("0REG");
375   fIdSens2=TVirtualMC::GetMC()->VolId("0V0A");
376
377    AliDebug(1,Form("%s: *** FIT version 1 initialized ***\n",ClassName()));
378 }
379
380 //-------------------------------------------------------------------
381
382 void AliFITv1::StepManager()
383 {
384   //
385   // Called for every step in the T0 Detector
386   //
387   Int_t id,copy,copy1;
388   static Float_t hits[6];
389   static Int_t vol[3];
390   TLorentzVector pos;
391   TLorentzVector mom;
392   
393   //   TClonesArray &lhits = *fHits;
394   
395   if(!TVirtualMC::GetMC()->IsTrackAlive()) return; // particle has disappeared
396   
397   id=TVirtualMC::GetMC()->CurrentVolID(copy);  
398   // Check the sensetive volume
399   if(id==fIdSens1 ) { 
400     if(TVirtualMC::GetMC()->IsTrackEntering()) {
401       TVirtualMC::GetMC()->CurrentVolOffID(1,copy1);
402       vol[1] = copy1;
403       vol[0]=copy;
404       TVirtualMC::GetMC()->TrackPosition(pos);
405       hits[0] = pos[0];
406       hits[1] = pos[1];
407       hits[2] = pos[2];
408       if(pos[2]<0) vol[2] = 0;
409       else vol[2] = 1 ;
410       //      printf(" volumes pmt %i mcp %i side %i x %f y %f z %f\n",  vol[0], vol[1],  vol[2], hits[0], hits[1], hits[2] );
411       
412       Float_t etot=TVirtualMC::GetMC()->Etot();
413       hits[3]=etot;
414       Int_t iPart= TVirtualMC::GetMC()->TrackPid();
415       Int_t partID=TVirtualMC::GetMC()->IdFromPDG(iPart);
416       hits[4]=partID;
417       Float_t ttime=TVirtualMC::GetMC()->TrackTime();
418       hits[5]=ttime*1e12;
419       if (TVirtualMC::GetMC()->TrackPid() == 50000050)   // If particles is photon then ...
420         {
421           //      if(RegisterPhotoE(vol[1]-1,hits[3])) {
422           if(RegisterPhotoE(hits[3])) {
423             AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber(),vol,hits);
424             // Create a track reference at the exit of photocatode
425           }         
426         }
427       
428       //charge particle 
429       if ( TVirtualMC::GetMC()->TrackCharge() )
430         AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kFIT);
431       
432      }// trck entering          
433   } //sensitive
434   //V0A
435   if(id==fIdSens2 ) { 
436     if ( TVirtualMC::GetMC()->TrackCharge()  ) {
437       if(TVirtualMC::GetMC()->IsTrackEntering()) {
438         TVirtualMC::GetMC()->TrackPosition(pos);
439         hits[0] = pos[0];
440         hits[1] = pos[1];
441         hits[2] = pos[2];
442         vol[0]=0;
443         vol[1]=0;
444         vol[2]=2;
445         
446         Float_t etot=TVirtualMC::GetMC()->Etot();
447         hits[3]=etot;
448         Int_t iPart= TVirtualMC::GetMC()->TrackPid();
449         Int_t partID=TVirtualMC::GetMC()->IdFromPDG(iPart);
450         hits[4]=partID;
451         Float_t ttime=TVirtualMC::GetMC()->TrackTime();
452         hits[5]=ttime*1e12;
453         AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber(),vol,hits);
454         //      printf(" volumes pmt %i mcp %i vol %i x %f y %f z %f particle %i all \n",  vol[0], vol[1],  vol[2], hits[0], hits[1], hits[2], hits[4]);
455       }
456     }    
457   }
458
459 }
460
461
462 //------------------------------------------------------------------------
463 Bool_t AliFITv1::RegisterPhotoE(Double_t energy)
464 {
465   
466   
467   //  Float_t hc=197.326960*1.e6; //mev*nm
468   Double_t hc=1.973*1.e-6; //gev*nm
469   Float_t lambda=hc/energy;
470   Float_t eff = fPMTeff->Eval(lambda);
471   Double_t  p = gRandom->Rndm();
472   
473   if (p > eff)
474     return kFALSE;
475   
476   return kTRUE;
477 }
478
479 //----------------------------------------------------------------------------
480
481 void AliFITv1::SetPMTeff()
482 {
483   Float_t lambda[50];
484   Float_t eff[50 ] = {0,        0,       0.23619,  0.202909, 0.177913, 
485                     0.175667, 0.17856, 0.190769, 0.206667, 0.230286,
486                     0.252276, 0.256267,0.26,     0.27125,  0.281818,
487                     0.288118, 0.294057,0.296222, 0.301622, 0.290421, 
488                     0.276615, 0.2666,  0.248,    0.23619,  0.227814, 
489                     0.219818, 0.206667,0.194087, 0.184681, 0.167917, 
490                     0.154367, 0.1364,  0.109412, 0.0834615,0.0725283, 
491                     0.0642963,0.05861, 0.0465,   0.0413333,0.032069, 
492                     0.0252203,0.02066, 0.016262, 0.012,    0.00590476,
493                     0.003875, 0.00190, 0,        0,        0          } ;
494   for (Int_t i=0; i<50; i++) lambda[i]=200+10*i; 
495
496   fPMTeff = new TGraph(50,lambda,eff);
497  
498 }
499
500
501
502
503