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.3 2000/06/13 13:06:38 jbarbosa
19 Fixed compiling error for HP (multiple declaration)
21 Revision 1.2 2000/06/12 15:36:16 jbarbosa
24 Revision 1.1 2000/06/09 15:00:31 jbarbosa
25 New full version. All parameters configurable.
27 Revision 1.9 2000/05/31 08:19:38 jbarbosa
28 Fixed bug in StepManager
30 Revision 1.8 2000/05/26 17:30:08 jbarbosa
31 Cerenkov angle now stored within cerenkov data structure.
33 Revision 1.7 2000/05/18 10:31:36 jbarbosa
34 Fixed positioning of spacers inside freon.
35 Fixed positioning of proximity gap
37 Fixed cut on neutral particles in the StepManager.
39 Revision 1.6 2000/04/28 11:51:58 morsch
40 Dimensions of arrays hits and Ckov_data corrected.
42 Revision 1.5 2000/04/19 13:28:46 morsch
43 Major changes in geometry (parametrised), materials (updated) and
44 step manager (diagnostics) (JB, AM)
50 //////////////////////////////////////////////////////////
51 // Manager and hits classes for set: RICH full version //
52 //////////////////////////////////////////////////////////
57 #include <TParticle.h>
59 #include "AliRICHv1.h"
60 #include "AliRICHHit.h"
64 #include "AliCallf77.h"
71 //___________________________________________
72 AliRICHv1::AliRICHv1() : AliRICHv0()
75 // Default constructor fo AliRICHvv1 (full version)
80 //___________________________________________
81 AliRICHv1::AliRICHv1(const char *name, const char *title)
82 : AliRICHv0(name,title)
85 // Full version of RICH with hits and diagnostics
90 fChambers = new TObjArray(kNCH);
91 for (Int_t i=0; i<kNCH; i++) {
93 (*fChambers)[i] = new AliRICHChamber();
98 void AliRICHv1::Init()
101 printf("*********************************** RICH_INIT ***********************************\n");
103 printf("* AliRICHv1 Configurable version started *\n");
107 AliRICHSegmentation* segmentation;
108 AliRICHGeometry* geometry;
109 AliRICHResponse* response;
113 // Initialize Tracking Chambers
115 for (Int_t i=1; i<kNCH; i++) {
117 ( (AliRICHChamber*) (*fChambers)[i])->Init();
121 // Set the chamber (sensitive region) GEANT identifier
123 ((AliRICHChamber*)(*fChambers)[0])->SetGid(1);
124 ((AliRICHChamber*)(*fChambers)[1])->SetGid(2);
125 ((AliRICHChamber*)(*fChambers)[2])->SetGid(3);
126 ((AliRICHChamber*)(*fChambers)[3])->SetGid(4);
127 ((AliRICHChamber*)(*fChambers)[4])->SetGid(5);
128 ((AliRICHChamber*)(*fChambers)[5])->SetGid(6);
129 ((AliRICHChamber*)(*fChambers)[6])->SetGid(7);
131 Float_t pos1[3]={0,471.8999,165.2599};
132 Chamber(0).SetChamberTransform(pos1[0],pos1[1],pos1[2],new TRotMatrix("rot993","rot993",90,0,70.69,90,19.30999,-90));
134 Float_t pos2[3]={171,470,0};
135 Chamber(1).SetChamberTransform(pos2[0],pos2[1],pos2[2],new TRotMatrix("rot994","rot994",90,-20,90,70,0,0));
137 Float_t pos3[3]={0,500,0};
138 Chamber(2).SetChamberTransform(pos3[0],pos3[1],pos3[2],new TRotMatrix("rot995","rot995",90,0,90,90,0,0));
140 Float_t pos4[3]={-171,470,0};
141 Chamber(3).SetChamberTransform(pos4[0],pos4[1],pos4[2], new TRotMatrix("rot996","rot996",90,20,90,110,0,0));
143 Float_t pos5[3]={161.3999,443.3999,-165.3};
144 Chamber(4).SetChamberTransform(pos5[0],pos5[1],pos5[2],new TRotMatrix("rot997","rot997",90,340,108.1999,70,18.2,70));
146 Float_t pos6[3]={0., 471.9, -165.3,};
147 Chamber(5).SetChamberTransform(pos6[0],pos6[1],pos6[2],new TRotMatrix("rot998","rot998",90,0,109.3099,90,19.30999,90));
149 Float_t pos7[3]={-161.399,443.3999,-165.3};
150 Chamber(6).SetChamberTransform(pos7[0],pos7[1],pos7[2],new TRotMatrix("rot999","rot999",90,20,108.1999,110,18.2,110));
152 segmentation=Chamber(0).GetSegmentationModel(0);
153 geometry=Chamber(0).GetGeometryModel();
154 response=Chamber(0).GetResponseModel();
157 printf("* Pads : %3dx%3d *\n",segmentation->Npx(),segmentation->Npy());
158 printf("* Pad size : %5.2f x%5.2f mm2 *\n",segmentation->Dpx(),segmentation->Dpy());
159 printf("* Gap Thickness : %5.1f mm *\n",geometry->GetGapThickness());
160 printf("* Radiator Width : %5.1f mm *\n",geometry->GetQuartzWidth());
161 printf("* Radiator Length : %5.1f mm *\n",geometry->GetQuartzLength());
162 printf("* Freon Thickness : %5.1f mm *\n",geometry->GetFreonThickness());
163 printf("* Charge Slope : %5.1f ADC *\n",response->ChargeSlope());
164 printf("* Feedback Prob. : %5.2f %% *\n",response->AlphaFeedback());
166 printf("* Success! *\n");
168 printf("*********************************************************************************\n");
172 //___________________________________________
173 void AliRICHv1::StepManager()
182 static Float_t hits[18];
183 static Float_t ckovData[19];
184 TLorentzVector position;
185 TLorentzVector momentum;
190 Float_t localTheta,localPhi;
192 Float_t destep, step;
196 static Float_t eloss, xhit, yhit, tlength;
197 const Float_t kBig=1.e10;
199 TClonesArray &lhits = *fHits;
200 TGeant3 *geant3 = (TGeant3*) gMC;
201 TParticle *current = (TParticle*)(*gAlice->Particles())[gAlice->CurrentTrack()];
203 //if (current->Energy()>1)
206 // Only gas gap inside chamber
207 // Tag chambers and record hits when track enters
210 id=gMC->CurrentVolID(copy);
211 Float_t cherenkovLoss=0;
212 //gAlice->KeepTrack(gAlice->CurrentTrack());
214 gMC->TrackPosition(position);
218 ckovData[1] = pos[0]; // X-position for hit
219 ckovData[2] = pos[1]; // Y-position for hit
220 ckovData[3] = pos[2]; // Z-position for hit
221 //ckovData[11] = gAlice->CurrentTrack();
223 //AliRICH *RICH = (AliRICH *) gAlice->GetDetector("RICH");
225 /********************Store production parameters for Cerenkov photons************************/
226 //is it a Cerenkov photon?
227 if (gMC->TrackPid() == 50000050) {
229 //if (gMC->VolId("GAP ")==gMC->CurrentVolID(copy))
231 Float_t ckovEnergy = current->Energy();
232 //energy interval for tracking
233 if (ckovEnergy > 5.6e-09 && ckovEnergy < 7.8e-09 )
234 //if (ckovEnergy > 0)
236 if (gMC->IsTrackEntering()){ //is track entering?
237 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
239 if (geant3->Gctrak()->nstep<1){ //is it the first step?
240 Int_t mother = current->GetFirstMother();
242 //printf("Second Mother:%d\n",current->GetSecondMother());
244 ckovData[10] = mother;
245 ckovData[11] = gAlice->CurrentTrack();
246 ckovData[12] = 1; //Media where photon was produced 1->Freon, 2->Quarz
249 //printf("Index: %d\n",fCkovNumber);
250 } //first step question
253 if (geant3->Gctrak()->nstep<1){ //is it first step?
254 if (gMC->VolId("QUAR")==gMC->CurrentVolID(copy)) //is it in quarz?
258 } //first step question
260 //printf("Before %d\n",fFreonProd);
261 } //track entering question
263 if (ckovData[12] == 1) //was it produced in Freon?
264 //if (fFreonProd == 1)
266 if (gMC->IsTrackEntering()){ //is track entering?
268 if (gMC->VolId("META")==gMC->CurrentVolID(copy)) //is it in gap?
270 //printf("Got in\n");
271 gMC->TrackMomentum(momentum);
276 // Z-position for hit
279 /**************** Photons lost in second grid have to be calculated by hand************/
281 Float_t cophi = TMath::Cos(TMath::ATan2(mom[0], mom[1]));
282 Float_t t = (1. - .025 / cophi) * (1. - .05 / cophi);
284 //printf("grid calculation:%f\n",t);
286 //geant3->StopTrack();
288 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
289 //printf("Lost one in grid\n");
291 /**********************************************************************************/
294 if (gMC->VolId("CSI ")==gMC->CurrentVolID(copy)) //is it in csi?
296 gMC->TrackMomentum(momentum);
302 /********* Photons lost by Fresnel reflection have to be calculated by hand********/
303 /***********************Cerenkov phtons (always polarised)*************************/
305 Float_t cophi = TMath::Cos(TMath::ATan2(mom[0], mom[1]));
306 Float_t t = Fresnel(ckovEnergy*1e9,cophi,1);
309 //geant3->StopTrack();
311 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
312 //printf("Lost by Fresnel\n");
314 /**********************************************************************************/
319 /********************Evaluation of losses************************/
320 /******************still in the old fashion**********************/
322 Int_t i1 = geant3->Gctrak()->nmec; //number of physics mechanisms acting on the particle
323 for (Int_t i = 0; i < i1; ++i) {
325 if (geant3->Gctrak()->lmec[i] == 106) { //was it reflected
327 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
329 if (gMC->CurrentVolID(copy) == gMC->VolId("QUAR"))
331 //geant3->StopTrack();
332 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
333 } //reflection question
337 else if (geant3->Gctrak()->lmec[i] == 101) { //was it absorbed?
339 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
341 if (gMC->CurrentVolID(copy) == gMC->VolId("QUAR"))
343 if (gMC->CurrentVolID(copy) == gMC->VolId("META"))
345 if (gMC->CurrentVolID(copy) == gMC->VolId("GAP "))
348 if (gMC->CurrentVolID(copy) == gMC->VolId("SRIC"))
352 if (gMC->CurrentVolID(copy) == gMC->VolId("CSI ")) {
355 //geant3->StopTrack();
356 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
357 //printf("Added cerenkov %d\n",fCkovNumber);
358 } //absorption question
361 // Photon goes out of tracking scope
362 else if (geant3->Gctrak()->lmec[i] == 30) { //is it below energy treshold?
364 //geant3->StopTrack();
365 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
366 } // energy treshold question
367 } //number of mechanisms cycle
368 /**********************End of evaluation************************/
369 } //freon production question
370 } //energy interval question
371 //}//inside the proximity gap question
372 } //cerenkov photon question
374 /**************************************End of Production Parameters Storing*********************/
377 /*******************************Treat photons that hit the CsI (Ckovs and Feedbacks)************/
379 if (gMC->TrackPid() == 50000050 || gMC->TrackPid() == 50000051) {
380 //printf("Cerenkov\n");
381 if (gMC->VolId("CSI ")==gMC->CurrentVolID(copy))
384 if (gMC->Edep() > 0.){
385 gMC->TrackPosition(position);
386 gMC->TrackMomentum(momentum);
394 Double_t tc = mom[0]*mom[0]+mom[1]*mom[1];
395 Double_t rt = TMath::Sqrt(tc);
396 theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg;
397 phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg;
398 gMC->Gmtod(pos,localPos,1);
399 gMC->Gmtod(mom,localMom,2);
401 gMC->CurrentVolOffID(2,copy);
405 //Int_t sector=((AliRICHChamber*) (*fChambers)[idvol])
406 //->Sector(localPos[0], localPos[2]);
407 //printf("Sector:%d\n",sector);
409 /*if (gMC->TrackPid() == 50000051){
411 printf("Feedbacks:%d\n",fFeedbacks);
414 ((AliRICHChamber*) (*fChambers)[idvol])
415 ->SigGenInit(localPos[0], localPos[2], localPos[1]);
417 ckovData[0] = gMC->TrackPid(); // particle type
418 ckovData[1] = pos[0]; // X-position for hit
419 ckovData[2] = pos[1]; // Y-position for hit
420 ckovData[3] = pos[2]; // Z-position for hit
421 ckovData[4] = theta; // theta angle of incidence
422 ckovData[5] = phi; // phi angle of incidence
423 ckovData[8] = (Float_t) fNPadHits; // first padhit
424 ckovData[9] = -1; // last pad hit
425 ckovData[13] = 4; // photon was detected
426 ckovData[14] = mom[0];
427 ckovData[15] = mom[1];
428 ckovData[16] = mom[2];
430 destep = gMC->Edep();
431 gMC->SetMaxStep(kBig);
432 cherenkovLoss += destep;
433 ckovData[7]=cherenkovLoss;
435 nPads = MakePadHits(localPos[0],localPos[2],cherenkovLoss,idvol,kCerenkov);
436 if (fNPadHits > (Int_t)ckovData[8]) {
437 ckovData[8]= ckovData[8]+1;
438 ckovData[9]= (Float_t) fNPadHits;
441 ckovData[17] = nPads;
442 //printf("nPads:%d",nPads);
444 //TClonesArray *Hits = RICH->Hits();
445 AliRICHHit *mipHit = (AliRICHHit*) (fHits->UncheckedAt(0));
448 mom[0] = current->Px();
449 mom[1] = current->Py();
450 mom[2] = current->Pz();
451 Float_t mipPx = mipHit->fMomX;
452 Float_t mipPy = mipHit->fMomY;
453 Float_t mipPz = mipHit->fMomZ;
455 Float_t r = mom[0]*mom[0] + mom[1]*mom[1] + mom[2]*mom[2];
456 Float_t rt = TMath::Sqrt(r);
457 Float_t mipR = mipPx*mipPx + mipPy*mipPy + mipPz*mipPz;
458 Float_t mipRt = TMath::Sqrt(mipR);
461 coscerenkov = (mom[0]*mipPx + mom[1]*mipPy + mom[2]*mipPz)/(rt*mipRt);
467 Float_t cherenkov = TMath::ACos(coscerenkov);
468 ckovData[18]=cherenkov;
472 AddHit(gAlice->CurrentTrack(),vol,ckovData);
473 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
480 /***********************************************End of photon hits*********************************************/
483 /**********************************************Charged particles treatment*************************************/
485 else if (gMC->TrackCharge())
489 /*if (gMC->IsTrackEntering())
491 hits[13]=20;//is track entering?
493 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
498 if (gMC->VolId("GAP ")== gMC->CurrentVolID(copy)) {
499 // Get current particle id (ipart), track position (pos) and momentum (mom)
501 gMC->CurrentVolOffID(3,copy);
505 //Int_t sector=((AliRICHChamber*) (*fChambers)[idvol])
506 //->Sector(localPos[0], localPos[2]);
507 //printf("Sector:%d\n",sector);
509 gMC->TrackPosition(position);
510 gMC->TrackMomentum(momentum);
518 gMC->Gmtod(pos,localPos,1);
519 gMC->Gmtod(mom,localMom,2);
521 ipart = gMC->TrackPid();
523 // momentum loss and steplength in last step
524 destep = gMC->Edep();
525 step = gMC->TrackStep();
528 // record hits when track enters ...
529 if( gMC->IsTrackEntering()) {
530 // gMC->SetMaxStep(fMaxStepGas);
531 Double_t tc = mom[0]*mom[0]+mom[1]*mom[1];
532 Double_t rt = TMath::Sqrt(tc);
533 theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg;
534 phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg;
537 Double_t localTc = localMom[0]*localMom[0]+localMom[2]*localMom[2];
538 Double_t localRt = TMath::Sqrt(localTc);
539 localTheta = Float_t(TMath::ATan2(localRt,Double_t(localMom[1])))*kRaddeg;
540 localPhi = Float_t(TMath::ATan2(Double_t(localMom[2]),Double_t(localMom[0])))*kRaddeg;
542 hits[0] = Float_t(ipart); // particle type
543 hits[1] = localPos[0]; // X-position for hit
544 hits[2] = localPos[1]; // Y-position for hit
545 hits[3] = localPos[2]; // Z-position for hit
546 hits[4] = localTheta; // theta angle of incidence
547 hits[5] = localPhi; // phi angle of incidence
548 hits[8] = (Float_t) fNPadHits; // first padhit
549 hits[9] = -1; // last pad hit
550 hits[13] = fFreonProd; // did id hit the freon?
559 Chamber(idvol).LocaltoGlobal(localPos,hits+1);
562 //To make chamber coordinates x-y had to pass localPos[0], localPos[2]
565 // Only if not trigger chamber
568 // Initialize hit position (cursor) in the segmentation model
569 ((AliRICHChamber*) (*fChambers)[idvol])
570 ->SigGenInit(localPos[0], localPos[2], localPos[1]);
575 // Calculate the charge induced on a pad (disintegration) in case
577 // Mip left chamber ...
578 if( gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()){
579 gMC->SetMaxStep(kBig);
584 // Only if not trigger chamber
588 if(gMC->TrackPid() == kNeutron)
589 printf("\n\n\n\n\n Neutron Making Pad Hit!!! \n\n\n\n");
590 nPads = MakePadHits(xhit,yhit,eloss,idvol,kMip);
592 //printf("nPads:%d",nPads);
598 if (fNPadHits > (Int_t)hits[8]) {
600 hits[9]= (Float_t) fNPadHits;
604 new(lhits[fNhits++]) AliRICHHit(fIshunt,gAlice->CurrentTrack(),vol,hits);
607 // Check additional signal generation conditions
608 // defined by the segmentation
609 // model (boundary crossing conditions)
611 (((AliRICHChamber*) (*fChambers)[idvol])
612 ->SigGenCond(localPos[0], localPos[2], localPos[1]))
614 ((AliRICHChamber*) (*fChambers)[idvol])
615 ->SigGenInit(localPos[0], localPos[2], localPos[1]);
618 if(gMC->TrackPid() == kNeutron)
619 printf("\n\n\n\n\n Neutron Making Pad Hit!!! \n\n\n\n");
620 nPads = MakePadHits(xhit,yhit,eloss,idvol,kMip);
622 //printf("Npads:%d",NPads);
629 // nothing special happened, add up energy loss
636 /*************************************************End of MIP treatment**************************************/