1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 /////////////////////////////////////////////////////////////////////
19 // FIT detector full geometry version 1 //
23 <img src="gif/AliFITv1Class.gif">
28 //////////////////////////////////////////////////////////////////////
30 #include <Riostream.h>
33 #include "TGeoCompositeShape.h"
34 #include "TGeoManager.h"
35 #include "TGeoMatrix.h"
36 #include "TGeoVolume.h"
42 #include <TGeoGlobalMagField.h>
44 #include <TLorentzVector.h>
46 #include <TVirtualMC.h>
53 #include "AliFITHits.h"
57 #include "AliCDBLocal.h"
58 #include "AliCDBStorage.h"
59 #include "AliCDBManager.h"
60 #include "AliCDBEntry.h"
61 #include "AliTrackReference.h"
66 //--------------------------------------------------------------------
67 AliFITv1::AliFITv1(): AliFIT(),
73 // Standart constructor for T0 Detector version 0
75 //--------------------------------------------------------------------
76 AliFITv1::AliFITv1(const char *name, const char *title):
83 // Standart constructor for T0 Detector version 0
88 //_____________________________________________________________________________
95 //-------------------------------------------------------------------------
96 void AliFITv1::CreateGeometry()
99 // Create the geometry of FIT Detector version 1 full geometry
104 Int_t *idtmed = fIdtmed->GetArray();
105 Float_t zdetC = 85; //center of mother volume
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
119 Float_t pV0Amother[3] = {4.25, 41.25, 0.6};
120 Float_t pV0A[3] = {4.3, 41.2, 0.5};
122 AliMatrix(idrotm[901], 90., 0., 90., 90., 180., 0.);
124 //-------------------------------------------------------------------
126 //-------------------------------------------------------------------
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,
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,
141 Float_t xa[20] = {0.0, 0.0, 0.0, 0.0, 6.4,
143 -6.4, -6.4, -6.4, -6.4, -6.4,
145 -12.8, -12.8, -12.8};
147 Float_t ya[20] = { 6.4, 12.8, -6.4, -12.8,
149 -12.8, 0., 6.4, 12.8,
151 -6.4, 0.0, 6.4, -6.4};
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};
157 TGeoVolumeAssembly * stlinA = new TGeoVolumeAssembly("0STL"); // A side mother
158 TGeoVolumeAssembly * stlinC = new TGeoVolumeAssembly("0STR"); // C side mother
160 TVirtualMC::GetMC()->Gsvolu("0INS","BOX",idtmed[kAir],pinstart,3);
161 TGeoVolume *ins = gGeoManager->GetVolume("0INS");
163 TGeoTranslation *tr[40];
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);
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) );
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");
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];
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) );
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);
214 z=-pinstart[2] + 2*ptop[2] + 2*preg[2] + pmcp[2];
215 ins->AddNode(mcp, 1 , new TGeoTranslation(0,0,z) );
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");
226 //------------------------------------------------------------------------
227 void AliFITv1::AddAlignableVolumes() const
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.
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"; }
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()));
251 //------------------------------------------------------------------------
252 void AliFITv1::CreateMaterials()
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];
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.};
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);
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);
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);
287 AliDebugClass(1,": ++++++++++++++Medium set++++++++++");
292 //-------------------------------------------------------------------
293 void AliFITv1::DefineOpticalProperties()
297 // Optical properties definition.
298 Int_t *idtmed = fIdtmed->GetArray();
299 // Definition Cherenkov parameters
301 const Int_t kNbins=31;
303 Float_t rindexSiO2[kNbins], efficAll[kNbins], rindexAir[kNbins], absorAir[kNbins],rindexCathodeNext[kNbins], absorbCathodeNext[kNbins];
304 Double_t efficMet[kNbins], aReflMet[kNbins];
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 };
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 };
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};
335 // Float_t aAbsSiO2[kNbins]; //quartz 30mm
336 for(i=0;i<kNbins;i++)
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;
343 rindexSiO2[i]=1.458; //refractive index for qwarts
344 rindexCathodeNext[i]=0;
348 // aAbsSiO2[i]=28.5; //quartz 30mm
350 absorbCathodeNext[i]=0;
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);
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);
368 //-------------------------------------------------------------------
369 void AliFITv1::Init()
371 // Initialises version 0 of the Forward Multiplicity Detector
374 fIdSens1=TVirtualMC::GetMC()->VolId("0REG");
375 fIdSens2=TVirtualMC::GetMC()->VolId("0V0A");
377 AliDebug(1,Form("%s: *** FIT version 1 initialized ***\n",ClassName()));
380 //-------------------------------------------------------------------
382 void AliFITv1::StepManager()
385 // Called for every step in the T0 Detector
388 static Float_t hits[6];
393 // TClonesArray &lhits = *fHits;
395 if(!TVirtualMC::GetMC()->IsTrackAlive()) return; // particle has disappeared
397 id=TVirtualMC::GetMC()->CurrentVolID(copy);
398 // Check the sensetive volume
400 if(TVirtualMC::GetMC()->IsTrackEntering()) {
401 TVirtualMC::GetMC()->CurrentVolOffID(1,copy1);
404 TVirtualMC::GetMC()->TrackPosition(pos);
408 if(pos[2]<0) vol[2] = 0;
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] );
412 Float_t etot=TVirtualMC::GetMC()->Etot();
414 Int_t iPart= TVirtualMC::GetMC()->TrackPid();
415 Int_t partID=TVirtualMC::GetMC()->IdFromPDG(iPart);
417 Float_t ttime=TVirtualMC::GetMC()->TrackTime();
419 if (TVirtualMC::GetMC()->TrackPid() == 50000050) // If particles is photon then ...
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
429 if ( TVirtualMC::GetMC()->TrackCharge() )
430 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kFIT);
436 if ( TVirtualMC::GetMC()->TrackCharge() ) {
437 if(TVirtualMC::GetMC()->IsTrackEntering()) {
438 TVirtualMC::GetMC()->TrackPosition(pos);
446 Float_t etot=TVirtualMC::GetMC()->Etot();
448 Int_t iPart= TVirtualMC::GetMC()->TrackPid();
449 Int_t partID=TVirtualMC::GetMC()->IdFromPDG(iPart);
451 Float_t ttime=TVirtualMC::GetMC()->TrackTime();
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]);
462 //------------------------------------------------------------------------
463 Bool_t AliFITv1::RegisterPhotoE(Double_t energy)
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();
479 //----------------------------------------------------------------------------
481 void AliFITv1::SetPMTeff()
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;
496 fPMTeff = new TGraph(50,lambda,eff);