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/AliFITv2Class.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 AliFITv2::AliFITv2(): AliFIT(),
74 // Standart constructor for T0 Detector version 0
76 //--------------------------------------------------------------------
77 AliFITv2::AliFITv2(const char *name, const char *title):
85 // Standart constructor for T0 Detector version 0
90 //_____________________________________________________________________________
97 //-------------------------------------------------------------------------
98 void AliFITv2::CreateGeometry()
101 // Create the geometry of FIT Detector version 1 full geometry
106 Int_t *idtmed = fIdtmed->GetArray();
112 Float_t pstartC[3] = {6., 20 ,5};
113 Float_t pstartA[3] = {2.55, 20 ,5};
114 // Float_t pinstart[3] = {3.2,3.2,3.9};
115 Float_t pinstart[3] = {3.2,3.2,4.};
116 Float_t pmcp[3] = {3.19, 3.19, 2.8}; //MCP
117 Float_t ptop[3] = {1.324, 1.324, 1.};//cherenkov radiator
118 Float_t preg[3] = {1.324, 1.324, 0.05};//photcathode
121 Float_t pV0Amother[3] = {4.25, 41.25, 0.6};
122 Float_t pV0A[3] = {4.3, 41.2, 0.5};
124 AliMatrix(idrotm[901], 90., 0., 90., 90., 180., 0.);
126 //-------------------------------------------------------------------
128 //-------------------------------------------------------------------
131 Float_t zc[36] = {2,0, 2,0, 2,0, 2,0, 2,2, 2,2, 2,2, 2,2, 0,0,0,0};
132 Float_t za[25] = {2,0, 2,0, 2,2, 0,2, 0,2, 2,0, 2,0, 0,0, 0,0,0,0};
135 TGeoVolumeAssembly * stlinA = new TGeoVolumeAssembly("0STL"); // A side mother
136 TGeoVolumeAssembly * stlinC = new TGeoVolumeAssembly("0STR"); // C side mother
138 TVirtualMC::GetMC()->Gsvolu("0INS","BOX",idtmed[kAir],pinstart,3);
139 TGeoVolume *ins = gGeoManager->GetVolume("0INS");
141 TGeoTranslation *tr[40];
147 for (Int_t itrx=0; itrx<5; itrx++) {
148 for (Int_t itry=0; itry<5; itry++) {
149 nameTr = Form("0TR%i",itr+1);
150 z=-pstartA[2]+pinstart[2]/* +za[itr]*/;
152 if(TMath::Abs(xa)<10 && TMath::Abs(ya)<10) z= z-2;
153 tr[itr] = new TGeoTranslation(nameTr.Data(),xa,ya, z );
154 tr[itr]->RegisterYourself();
155 stlinA->AddNode(ins,itr,tr[itr]);
157 printf(" A %i %f %f %f \n",itr, xa, ya, z+zdetA);
166 for (Int_t itrx=0; itrx<6; itrx++) {
167 for (Int_t itry=0; itry<6; itry++) {
168 nameTr = Form("0TR%i",itr+1);
169 z=-pstartC[2]+pinstart[2] /*+ zc[itr] */;
170 if (itr!=39 && itr!=40 && itr!=45 &&itr!=46) {
171 if( TMath::Abs(xc)<10 && TMath::Abs(yc)<10) z= z+2;
172 tr[itr] = new TGeoTranslation(nameTr.Data(),xc,yc, z );
173 tr[itr]->RegisterYourself();
174 stlinC->AddNode(ins,itr,tr[itr]);
176 printf(" C %i %f %f %f \n",itr,xc, yc, z+zdetC);
183 TGeoVolume *alice = gGeoManager->GetVolume("ALIC");
184 alice->AddNode(stlinA,1,new TGeoTranslation(0,0, zdetA ) );
185 // alice->AddNode(stlinC,1,new TGeoTranslation(0,0, zdetC ) );
186 TGeoRotation * rotC = new TGeoRotation( "rotC",90., 0., 90., 90., 180., 0.);
187 alice->AddNode(stlinC,1, new TGeoCombiTrans(0., 0., -zdetC , rotC) );
192 // Entry window (glass)
193 TVirtualMC::GetMC()->Gsvolu("0TOP","BOX",idtmed[kOpGlass],ptop,3); //glass
194 TGeoVolume *top = gGeoManager->GetVolume("0TOP");
195 TVirtualMC::GetMC()->Gsvolu ("0REG", "BOX", idtmed[kOpGlassCathode], preg, 3);
196 TGeoVolume *cat = gGeoManager->GetVolume("0REG");
197 TVirtualMC::GetMC()->Gsvolu("0MCP","BOX",idtmed[kGlass],pmcp,3); //glass
198 TGeoVolume *mcp = gGeoManager->GetVolume("0MCP");
201 Float_t xin=0, yin=0;
202 for (Int_t ix=0; ix<2; ix++) {
203 xin = - pinstart[0] + 0.55 + (ix+0.5)*2*ptop[0] ;
204 for (Int_t iy=0; iy<2 ; iy++) {
205 z = - pinstart[2]+ptop[2];
206 yin = - pinstart[1] + 0.55 + (iy+0.5)*2*ptop[1];
208 ins->AddNode(top, ntops, new TGeoTranslation(xin,yin,z) );
209 // printf(" 0TOP full x %f y %f z %f \n", xin, yin, z);
210 z = -pinstart[2] + 2 * ptop[2] + preg[2];
211 ins->AddNode(cat, ntops, new TGeoTranslation(xin,yin,z) );
213 // printf(" GEOGEO %i %i %i %f %f %f %f %f %f \n", ntops, ix, iy,
214 // xin,yin,x1[ntops],y1[ntops],x1[ntops]+xin,y1[ntops]+yin);
218 z=-pinstart[2] + 2*ptop[2] + 2*preg[2] + pmcp[2];
219 ins->AddNode(mcp, 1 , new TGeoTranslation(0,0,z) );
222 TVirtualMC::GetMC()->Gsvolu("0V0AM","TUBE",idtmed[kAir],pV0Amother,3);
223 TVirtualMC::GetMC()->Gspos ("0V0AM",1, "ALIC", 0,0,zV0A , 0, "ONLY");
224 TVirtualMC::GetMC()->Gsvolu("0V0A","TUBE",idtmed[kSensAir],pV0A,3);
225 TVirtualMC::GetMC()->Gspos ("0V0A",1, "0V0AM", 0, 0, 0, 0, "ONLY");
230 //------------------------------------------------------------------------
231 void AliFITv2::AddAlignableVolumes() const
234 // Create entries for alignable volumes associating the symbolic volume
235 // name with the corresponding volume path. Needs to be syncronized with
236 // eventual changes in the geometry.
240 TString vpAalign = "/ALIC_1/0STL_1";
241 TString vpCalign = "/ALIC_1/0STR_1";
242 for (Int_t imod=0; imod<2; imod++) {
243 if (imod==0) {volPath = vpCalign; symName="/ALIC_1/0STL"; }
244 if (imod==1) {volPath = vpAalign; symName="/ALIC_1/0STR"; }
246 AliDebug(2,"--------------------------------------------");
247 AliDebug(2,Form("volPath=%s\n",volPath.Data()));
248 AliDebug(2,Form("symName=%s\n",symName.Data()));
249 AliDebug(2,"--------------------------------------------");
250 if(!gGeoManager->SetAlignableEntry(symName.Data(),volPath.Data()))
251 AliFatal(Form("Alignable entry %s not created. Volume path %s not valid",
252 symName.Data(),volPath.Data()));
255 //------------------------------------------------------------------------
256 void AliFITv2::CreateMaterials()
259 Int_t isxfld = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
260 Float_t sxmgmx = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
261 // Float_t a,z,d,radl,absl,buf[1];
265 Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
266 Float_t zAir[4]={6.,7.,8.,18.};
267 Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
268 Float_t dAir = 1.20479E-3;
269 Float_t dAir1 = 1.20479E-11;
270 // Radiator glass SiO2
271 Float_t aglass[2]={28.0855,15.9994};
272 Float_t zglass[2]={14.,8.};
273 Float_t wglass[2]={1.,2.};
276 Float_t dglass_mcp=1.3;
277 //*** Definition Of avaible T0 materials ***
278 AliMixture(1, "Vacuum$", aAir, zAir, dAir1,4,wAir);
279 AliMixture(2, "Air$", aAir, zAir, dAir,4,wAir);
280 AliMixture( 4, "MCP glass $",aglass,zglass,dglass_mcp,-2,wglass);
281 AliMixture( 24, "Radiator Optical glass$",aglass,zglass,dglass,-2,wglass);
283 AliMedium(1, "Air$", 2, 0, isxfld, sxmgmx, 10., .1, 1., .003, .003);
284 AliMedium(3, "Vacuum$", 1, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
285 AliMedium(6, "Glass$", 4, 0, isxfld, sxmgmx, 10., .01, .1, .003, .003);
287 AliMedium(16, "OpticalGlass$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .003);
288 AliMedium(19, "OpticalGlassCathode$", 24, 1, isxfld, sxmgmx, 10., .01, .1, .003, .003);
289 AliMedium(22, "SensAir$", 2, 1, isxfld, sxmgmx, 10., .1, 1., .003, .003);
291 AliDebugClass(1,": ++++++++++++++Medium set++++++++++");
296 //-------------------------------------------------------------------
297 void AliFITv2::DefineOpticalProperties()
301 // Optical properties definition.
302 Int_t *idtmed = fIdtmed->GetArray();
303 // Definition Cherenkov parameters
305 const Int_t kNbins=31;
307 Float_t rindexSiO2[kNbins], efficAll[kNbins], rindexAir[kNbins], absorAir[kNbins],rindexCathodeNext[kNbins], absorbCathodeNext[kNbins];
308 Double_t efficMet[kNbins], aReflMet[kNbins];
311 Float_t aAbsSiO2[kNbins]={29.0, 28.6, 28.3, 27.7, 27.3, 26.7, 26.4,
312 25.9, 25.3, 24.9, 24.5, 23.7,
313 23.2, 22.8, 22.4, 21.8, 21.3,
314 22.8, 22.1, 21.7, 21.2, 20.5,
315 19.9, 19.3, 18.7, 18.0, 17.1,
316 16.3, 15.3, 14.3, 14.3 };
318 Float_t aPckov[kNbins] ={3.87, 3.94, 4.02, 4.11, 4.19, 4.29, 4.38,
319 4.48, 4.58, 4.69, 4.81, 4.93,
320 5.05, 5.19, 5.33, 5.48, 5.63,
321 5.8, 5.97, 6.16, 6.36, 6.57,
322 6.8, 7.04, 7.3, 7.58, 7.89,
323 8.22, 8.57, 8.97, 9.39 };
324 Double_t dPckov[kNbins] ={3.87, 3.94, 4.02, 4.11, 4.19, 4.29, 4.38,
325 4.48, 4.58, 4.69, 4.81, 4.93,
326 5.05, 5.19, 5.33, 5.48, 5.63,
327 5.8, 5.97, 6.16, 6.36, 6.57,
328 6.8, 7.04, 7.3, 7.58, 7.89,
329 8.22, 8.57, 8.97, 9.39 };
332 Float_t effCathode[kNbins]={0.11, 0.13, 0.15, 0.16, 0.18, 0.19, 0.20,
333 0.21, 0.22, 0.23, 0.24, 0.26,
334 0.27, 0.29, 0.30, 0.29, 0.29,
335 0.28, 0.28, 0.27, 0.26, 0.25,
336 0.25, 0.23, 0.20, 0.19, 0.17,
337 0.17, 0.17, 0.2, 0.23};
339 // Float_t aAbsSiO2[kNbins]; //quartz 30mm
340 for(i=0;i<kNbins;i++)
343 aPckov[i]=aPckov[i]*1e-9;//Photons energy bins 4 eV - 8.5 eV step 0.1 eV
344 dPckov[i]=dPckov[i]*1e-9;//Photons energy bins 4 eV - 8.5 eV step 0.1 eV
345 // rindexAir[i]=0.0001;
347 rindexSiO2[i]=1.458; //refractive index for qwarts
348 rindexCathodeNext[i]=0;
352 // aAbsSiO2[i]=28.5; //quartz 30mm
354 absorbCathodeNext[i]=0;
358 TVirtualMC::GetMC()->SetCerenkov (idtmed[kOpGlass], kNbins, aPckov, aAbsSiO2, efficAll, rindexSiO2 );
359 // TVirtualMC::GetMC()->SetCerenkov (idtmed[kOpGlassCathode], kNbins, aPckov, aAbsSiO2, effCathode, rindexSiO2 );
360 TVirtualMC::GetMC()->SetCerenkov (idtmed[kOpGlassCathode], kNbins, aPckov, aAbsSiO2,efficAll , rindexSiO2 );
361 // TVirtualMC::GetMC()->SetCerenkov (idtmed[kOpAir], kNbins, aPckov,absorAir , efficAll,rindexAir );
362 // TVirtualMC::GetMC()->SetCerenkov (idtmed[kOpAirNext], kNbins, aPckov,absorbCathodeNext , efficAll, rindexCathodeNext);
364 //Define a boarder for radiator optical properties
365 TVirtualMC::GetMC()->DefineOpSurface("surfRd", kUnified /*kGlisur*/,kDielectric_metal,kPolished, 0.);
366 TVirtualMC::GetMC()->SetMaterialProperty("surfRd", "EFFICIENCY", kNbins, dPckov, efficMet);
367 TVirtualMC::GetMC()->SetMaterialProperty("surfRd", "REFLECTIVITY", kNbins, dPckov, aReflMet);
372 //-------------------------------------------------------------------
373 void AliFITv2::Init()
375 // Initialises version 0 of the Forward Multiplicity Detector
378 fIdSens1=TVirtualMC::GetMC()->VolId("0REG");
379 fIdSens2=TVirtualMC::GetMC()->VolId("0V0A");
381 AliDebug(1,Form("%s: *** FIT version 1 initialized ***\n",ClassName()));
384 //-------------------------------------------------------------------
386 void AliFITv2::StepManager()
389 // Called for every step in the T0 Detector
392 static Float_t hits[6];
397 // TClonesArray &lhits = *fHits;
399 if(!TVirtualMC::GetMC()->IsTrackAlive()) return; // particle has disappeared
401 id=TVirtualMC::GetMC()->CurrentVolID(copy);
402 // Check the sensetive volume
404 if(TVirtualMC::GetMC()->IsTrackEntering()) {
405 TVirtualMC::GetMC()->CurrentVolOffID(1,copy1);
408 TVirtualMC::GetMC()->TrackPosition(pos);
412 if(pos[2]<0) vol[2] = 0;
414 // 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] );
416 Float_t etot=TVirtualMC::GetMC()->Etot();
418 Int_t iPart= TVirtualMC::GetMC()->TrackPid();
419 Int_t partID=TVirtualMC::GetMC()->IdFromPDG(iPart);
421 Float_t ttime=TVirtualMC::GetMC()->TrackTime();
423 if (TVirtualMC::GetMC()->TrackPid() == 50000050) // If particles is photon then ...
425 // if(RegisterPhotoE(vol[1]-1,hits[3])) {
426 if(RegisterPhotoE(hits[3])) {
427 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber(),vol,hits);
428 // Create a track reference at the exit of photocatode
433 if ( TVirtualMC::GetMC()->TrackCharge() )
434 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kFIT);
440 if ( TVirtualMC::GetMC()->TrackCharge() ) {
441 if(TVirtualMC::GetMC()->IsTrackEntering()) {
442 TVirtualMC::GetMC()->TrackPosition(pos);
450 Float_t etot=TVirtualMC::GetMC()->Etot();
452 Int_t iPart= TVirtualMC::GetMC()->TrackPid();
453 Int_t partID=TVirtualMC::GetMC()->IdFromPDG(iPart);
455 Float_t ttime=TVirtualMC::GetMC()->TrackTime();
457 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber(),vol,hits);
458 // 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]);
466 //------------------------------------------------------------------------
467 Bool_t AliFITv2::RegisterPhotoE(Double_t energy)
471 // Float_t hc=197.326960*1.e6; //mev*nm
472 Double_t hc=1.973*1.e-6; //gev*nm
473 Float_t lambda=hc/energy;
474 Float_t eff = fPMTeff->Eval(lambda);
475 Double_t p = gRandom->Rndm();
483 //----------------------------------------------------------------------------
485 void AliFITv2::SetPMTeff()
488 Float_t eff[50 ] = {0, 0, 0.23619, 0.202909, 0.177913,
489 0.175667, 0.17856, 0.190769, 0.206667, 0.230286,
490 0.252276, 0.256267,0.26, 0.27125, 0.281818,
491 0.288118, 0.294057,0.296222, 0.301622, 0.290421,
492 0.276615, 0.2666, 0.248, 0.23619, 0.227814,
493 0.219818, 0.206667,0.194087, 0.184681, 0.167917,
494 0.154367, 0.1364, 0.109412, 0.0834615,0.0725283,
495 0.0642963,0.05861, 0.0465, 0.0413333,0.032069,
496 0.0252203,0.02066, 0.016262, 0.012, 0.00590476,
497 0.003875, 0.00190, 0, 0, 0 } ;
498 for (Int_t i=0; i<50; i++) lambda[i]=200+10*i;
500 fPMTeff = new TGraph(50,lambda,eff);