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 **************************************************************************/
18 Revision 1.9 2000/05/31 08:19:38 jbarbosa
19 Fixed bug in StepManager
21 Revision 1.8 2000/05/26 17:30:08 jbarbosa
22 Cerenkov angle now stored within cerenkov data structure.
24 Revision 1.7 2000/05/18 10:31:36 jbarbosa
25 Fixed positioning of spacers inside freon.
26 Fixed positioning of proximity gap
28 Fixed cut on neutral particles in the StepManager.
30 Revision 1.6 2000/04/28 11:51:58 morsch
31 Dimensions of arrays hits and Ckov_data corrected.
33 Revision 1.5 2000/04/19 13:28:46 morsch
34 Major changes in geometry (parametrised), materials (updated) and
35 step manager (diagnostics) (JB, AM)
41 //////////////////////////////////////////////////////////
42 // Manager and hits classes for set: RICH full version //
43 //////////////////////////////////////////////////////////
49 #include "AliRICHv1.h"
53 #include "AliCallf77.h"
60 //___________________________________________
61 AliRICHv1::AliRICHv1() : AliRICHv0()
66 //___________________________________________
67 AliRICHv1::AliRICHv1(const char *name, const char *title)
68 : AliRICHv0(name,title)
73 fChambers = new TObjArray(7);
74 for (Int_t i=0; i<7; i++) {
76 (*fChambers)[i] = new AliRICHChamber();
82 //___________________________________________
83 void AliRICHv1::StepManager()
89 static Float_t hits[18];
90 static Float_t Ckov_data[19];
91 TLorentzVector Position;
92 TLorentzVector Momentum;
97 Float_t Localtheta,Localphi;
103 static Float_t eloss, xhit, yhit, tlength;
104 const Float_t big=1.e10;
106 TClonesArray &lhits = *fHits;
107 TGeant3 *geant3 = (TGeant3*) gMC;
108 TParticle *current = (TParticle*)(*gAlice->Particles())[gAlice->CurrentTrack()];
110 //if (current->Energy()>1)
113 // Only gas gap inside chamber
114 // Tag chambers and record hits when track enters
117 id=gMC->CurrentVolID(copy);
118 Float_t cherenkov_loss=0;
119 //gAlice->KeepTrack(gAlice->CurrentTrack());
121 gMC->TrackPosition(Position);
125 Ckov_data[1] = pos[0]; // X-position for hit
126 Ckov_data[2] = pos[1]; // Y-position for hit
127 Ckov_data[3] = pos[2]; // Z-position for hit
128 //Ckov_data[11] = gAlice->CurrentTrack();
130 //AliRICH *RICH = (AliRICH *) gAlice->GetDetector("RICH");
132 /********************Store production parameters for Cerenkov photons************************/
133 //is it a Cerenkov photon?
134 if (gMC->TrackPid() == 50000050) {
136 //if (gMC->VolId("GAP ")==gMC->CurrentVolID(copy))
138 Float_t Ckov_energy = current->Energy();
139 //energy interval for tracking
140 if (Ckov_energy > 5.6e-09 && Ckov_energy < 7.8e-09 )
141 //if (Ckov_energy > 0)
143 if (gMC->IsTrackEntering()){ //is track entering?
144 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
146 if (geant3->Gctrak()->nstep<1){ //is it the first step?
147 Int_t mother = current->GetFirstMother();
149 //printf("Second Mother:%d\n",current->GetSecondMother());
151 Ckov_data[10] = mother;
152 Ckov_data[11] = gAlice->CurrentTrack();
153 Ckov_data[12] = 1; //Media where photon was produced 1->Freon, 2->Quarz
156 //printf("Index: %d\n",fCkov_number);
157 } //first step question
160 if (geant3->Gctrak()->nstep<1){ //is it first step?
161 if (gMC->VolId("QUAR")==gMC->CurrentVolID(copy)) //is it in quarz?
165 } //first step question
167 //printf("Before %d\n",fFreon_prod);
168 } //track entering question
170 if (Ckov_data[12] == 1) //was it produced in Freon?
171 //if (fFreon_prod == 1)
173 if (gMC->IsTrackEntering()){ //is track entering?
175 if (gMC->VolId("META")==gMC->CurrentVolID(copy)) //is it in gap?
177 //printf("Got in\n");
178 gMC->TrackMomentum(Momentum);
183 // Z-position for hit
186 /**************** Photons lost in second grid have to be calculated by hand************/
188 Float_t cophi = TMath::Cos(TMath::ATan2(mom[0], mom[1]));
189 Float_t t = (1. - .025 / cophi) * (1. - .05 / cophi);
191 //printf("grid calculation:%f\n",t);
193 //geant3->StopTrack();
195 AddCerenkov(gAlice->CurrentTrack(),vol,Ckov_data);
196 //printf("Lost one in grid\n");
198 /**********************************************************************************/
201 if (gMC->VolId("CSI ")==gMC->CurrentVolID(copy)) //is it in csi?
203 gMC->TrackMomentum(Momentum);
209 /********* Photons lost by Fresnel reflection have to be calculated by hand********/
210 /***********************Cerenkov phtons (always polarised)*************************/
212 Float_t cophi = TMath::Cos(TMath::ATan2(mom[0], mom[1]));
213 Float_t t = Fresnel(Ckov_energy*1e9,cophi,1);
216 //geant3->StopTrack();
218 AddCerenkov(gAlice->CurrentTrack(),vol,Ckov_data);
219 //printf("Lost by Fresnel\n");
221 /**********************************************************************************/
226 /********************Evaluation of losses************************/
227 /******************still in the old fashion**********************/
229 Int_t i1 = geant3->Gctrak()->nmec; //number of physics mechanisms acting on the particle
230 for (Int_t i = 0; i < i1; ++i) {
232 if (geant3->Gctrak()->lmec[i] == 106) { //was it reflected
234 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
236 if (gMC->CurrentVolID(copy) == gMC->VolId("QUAR"))
238 //geant3->StopTrack();
239 AddCerenkov(gAlice->CurrentTrack(),vol,Ckov_data);
240 } //reflection question
244 else if (geant3->Gctrak()->lmec[i] == 101) { //was it absorbed?
246 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
248 if (gMC->CurrentVolID(copy) == gMC->VolId("QUAR"))
250 if (gMC->CurrentVolID(copy) == gMC->VolId("META"))
252 if (gMC->CurrentVolID(copy) == gMC->VolId("GAP "))
255 if (gMC->CurrentVolID(copy) == gMC->VolId("SRIC"))
259 if (gMC->CurrentVolID(copy) == gMC->VolId("CSI ")) {
262 //geant3->StopTrack();
263 AddCerenkov(gAlice->CurrentTrack(),vol,Ckov_data);
264 //printf("Added cerenkov %d\n",fCkov_number);
265 } //absorption question
268 // Photon goes out of tracking scope
269 else if (geant3->Gctrak()->lmec[i] == 30) { //is it below energy treshold?
271 //geant3->StopTrack();
272 AddCerenkov(gAlice->CurrentTrack(),vol,Ckov_data);
273 } // energy treshold question
274 } //number of mechanisms cycle
275 /**********************End of evaluation************************/
276 } //freon production question
277 } //energy interval question
278 //}//inside the proximity gap question
279 } //cerenkov photon question
281 /**************************************End of Production Parameters Storing*********************/
284 /*******************************Treat photons that hit the CsI (Ckovs and Feedbacks)************/
286 if (gMC->TrackPid() == 50000050 || gMC->TrackPid() == 50000051) {
287 //printf("Cerenkov\n");
288 if (gMC->VolId("CSI ")==gMC->CurrentVolID(copy))
291 if (gMC->Edep() > 0.){
292 gMC->TrackPosition(Position);
293 gMC->TrackMomentum(Momentum);
301 Double_t tc = mom[0]*mom[0]+mom[1]*mom[1];
302 Double_t rt = TMath::Sqrt(tc);
303 theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg;
304 phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg;
305 gMC->Gmtod(pos,Localpos,1);
306 gMC->Gmtod(mom,Localmom,2);
308 gMC->CurrentVolOffID(2,copy);
312 //Int_t sector=((AliRICHChamber*) (*fChambers)[idvol])
313 //->Sector(Localpos[0], Localpos[2]);
314 //printf("Sector:%d\n",sector);
316 /*if (gMC->TrackPid() == 50000051){
318 printf("Feedbacks:%d\n",fFeedbacks);
321 ((AliRICHChamber*) (*fChambers)[idvol])
322 ->SigGenInit(Localpos[0], Localpos[2], Localpos[1]);
324 Ckov_data[0] = gMC->TrackPid(); // particle type
325 Ckov_data[1] = pos[0]; // X-position for hit
326 Ckov_data[2] = pos[1]; // Y-position for hit
327 Ckov_data[3] = pos[2]; // Z-position for hit
328 Ckov_data[4] = theta; // theta angle of incidence
329 Ckov_data[5] = phi; // phi angle of incidence
330 Ckov_data[8] = (Float_t) fNPadHits; // first padhit
331 Ckov_data[9] = -1; // last pad hit
332 Ckov_data[13] = 4; // photon was detected
333 Ckov_data[14] = mom[0];
334 Ckov_data[15] = mom[1];
335 Ckov_data[16] = mom[2];
337 destep = gMC->Edep();
338 gMC->SetMaxStep(big);
339 cherenkov_loss += destep;
340 Ckov_data[7]=cherenkov_loss;
342 NPads = MakePadHits(Localpos[0],Localpos[2],cherenkov_loss,idvol,cerenkov);
343 if (fNPadHits > (Int_t)Ckov_data[8]) {
344 Ckov_data[8]= Ckov_data[8]+1;
345 Ckov_data[9]= (Float_t) fNPadHits;
348 Ckov_data[17] = NPads;
349 //printf("Npads:%d",NPads);
351 //TClonesArray *Hits = RICH->Hits();
352 AliRICHHit *mipHit = (AliRICHHit*) (fHits->UncheckedAt(0));
355 mom[0] = current->Px();
356 mom[1] = current->Py();
357 mom[2] = current->Pz();
358 Float_t Mip_px = mipHit->fMomX;
359 Float_t Mip_py = mipHit->fMomY;
360 Float_t Mip_pz = mipHit->fMomZ;
362 Float_t r = mom[0]*mom[0] + mom[1]*mom[1] + mom[2]*mom[2];
363 Float_t rt = TMath::Sqrt(r);
364 Float_t Mip_r = Mip_px*Mip_px + Mip_py*Mip_py + Mip_pz*Mip_pz;
365 Float_t Mip_rt = TMath::Sqrt(Mip_r);
368 coscerenkov = (mom[0]*Mip_px + mom[1]*Mip_py + mom[2]*Mip_pz)/(rt*Mip_rt);
374 Float_t cherenkov = TMath::ACos(coscerenkov);
375 Ckov_data[18]=cherenkov;
379 AddHit(gAlice->CurrentTrack(),vol,Ckov_data);
380 AddCerenkov(gAlice->CurrentTrack(),vol,Ckov_data);
387 /***********************************************End of photon hits*********************************************/
390 /**********************************************Charged particles treatment*************************************/
392 else if (gMC->TrackCharge())
396 /*if (gMC->IsTrackEntering())
398 hits[13]=20;//is track entering?
400 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
405 if (gMC->VolId("GAP ")== gMC->CurrentVolID(copy)) {
406 // Get current particle id (ipart), track position (pos) and momentum (mom)
408 gMC->CurrentVolOffID(3,copy);
412 //Int_t sector=((AliRICHChamber*) (*fChambers)[idvol])
413 //->Sector(Localpos[0], Localpos[2]);
414 //printf("Sector:%d\n",sector);
416 gMC->TrackPosition(Position);
417 gMC->TrackMomentum(Momentum);
425 gMC->Gmtod(pos,Localpos,1);
426 gMC->Gmtod(mom,Localmom,2);
428 ipart = gMC->TrackPid();
430 // momentum loss and steplength in last step
431 destep = gMC->Edep();
432 step = gMC->TrackStep();
435 // record hits when track enters ...
436 if( gMC->IsTrackEntering()) {
437 // gMC->SetMaxStep(fMaxStepGas);
438 Double_t tc = mom[0]*mom[0]+mom[1]*mom[1];
439 Double_t rt = TMath::Sqrt(tc);
440 theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg;
441 phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg;
444 Double_t Localtc = Localmom[0]*Localmom[0]+Localmom[2]*Localmom[2];
445 Double_t Localrt = TMath::Sqrt(Localtc);
446 Localtheta = Float_t(TMath::ATan2(Localrt,Double_t(Localmom[1])))*kRaddeg;
447 Localphi = Float_t(TMath::ATan2(Double_t(Localmom[2]),Double_t(Localmom[0])))*kRaddeg;
449 hits[0] = Float_t(ipart); // particle type
450 hits[1] = Localpos[0]; // X-position for hit
451 hits[2] = Localpos[1]; // Y-position for hit
452 hits[3] = Localpos[2]; // Z-position for hit
453 hits[4] = Localtheta; // theta angle of incidence
454 hits[5] = Localphi; // phi angle of incidence
455 hits[8] = (Float_t) fNPadHits; // first padhit
456 hits[9] = -1; // last pad hit
457 hits[13] = fFreon_prod; // did id hit the freon?
466 Chamber(idvol).LocaltoGlobal(Localpos,hits+1);
469 //To make chamber coordinates x-y had to pass LocalPos[0], LocalPos[2]
472 // Only if not trigger chamber
475 // Initialize hit position (cursor) in the segmentation model
476 ((AliRICHChamber*) (*fChambers)[idvol])
477 ->SigGenInit(Localpos[0], Localpos[2], Localpos[1]);
482 // Calculate the charge induced on a pad (disintegration) in case
484 // Mip left chamber ...
485 if( gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()){
486 gMC->SetMaxStep(big);
491 // Only if not trigger chamber
495 if(gMC->TrackPid() == kNeutron)
496 printf("\n\n\n\n\n Neutron Making Pad Hit!!! \n\n\n\n");
497 NPads = MakePadHits(xhit,yhit,eloss,idvol,mip);
499 //printf("Npads:%d",NPads);
505 if (fNPadHits > (Int_t)hits[8]) {
507 hits[9]= (Float_t) fNPadHits;
511 new(lhits[fNhits++]) AliRICHHit(fIshunt,gAlice->CurrentTrack(),vol,hits);
514 // Check additional signal generation conditions
515 // defined by the segmentation
516 // model (boundary crossing conditions)
518 (((AliRICHChamber*) (*fChambers)[idvol])
519 ->SigGenCond(Localpos[0], Localpos[2], Localpos[1]))
521 ((AliRICHChamber*) (*fChambers)[idvol])
522 ->SigGenInit(Localpos[0], Localpos[2], Localpos[1]);
525 if(gMC->TrackPid() == kNeutron)
526 printf("\n\n\n\n\n Neutron Making Pad Hit!!! \n\n\n\n");
527 NPads = MakePadHits(xhit,yhit,eloss,idvol,mip);
529 //printf("Npads:%d",NPads);
536 // nothing special happened, add up energy loss
543 /*************************************************End of MIP treatment**************************************/