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.1 2000/06/09 15:00:31 jbarbosa
19 New full version. All parameters configurable.
21 Revision 1.9 2000/05/31 08:19:38 jbarbosa
22 Fixed bug in StepManager
24 Revision 1.8 2000/05/26 17:30:08 jbarbosa
25 Cerenkov angle now stored within cerenkov data structure.
27 Revision 1.7 2000/05/18 10:31:36 jbarbosa
28 Fixed positioning of spacers inside freon.
29 Fixed positioning of proximity gap
31 Fixed cut on neutral particles in the StepManager.
33 Revision 1.6 2000/04/28 11:51:58 morsch
34 Dimensions of arrays hits and Ckov_data corrected.
36 Revision 1.5 2000/04/19 13:28:46 morsch
37 Major changes in geometry (parametrised), materials (updated) and
38 step manager (diagnostics) (JB, AM)
44 //////////////////////////////////////////////////////////
45 // Manager and hits classes for set: RICH full version //
46 //////////////////////////////////////////////////////////
51 #include <TParticle.h>
53 #include "AliRICHv1.h"
54 #include "AliRICHHit.h"
58 #include "AliCallf77.h"
65 //___________________________________________
66 AliRICHv1::AliRICHv1() : AliRICHv0()
69 // Default constructor fo AliRICHvv1 (full version)
74 //___________________________________________
75 AliRICHv1::AliRICHv1(const char *name, const char *title)
76 : AliRICHv0(name,title)
79 // Full version of RICH with hits and diagnostics
84 fChambers = new TObjArray(kNCH);
85 for (Int_t i=0; i<kNCH; i++) {
87 (*fChambers)[i] = new AliRICHChamber();
92 void AliRICHv1::Init()
95 printf("*********************************** RICH_INIT ***********************************\n");
97 printf("* AliRICHv1 Configurable version started *\n");
101 AliRICHSegmentation* segmentation;
102 AliRICHGeometry* geometry;
103 AliRICHResponse* response;
107 // Initialize Tracking Chambers
109 for (Int_t i=1; i<kNCH; i++) {
111 ( (AliRICHChamber*) (*fChambers)[i])->Init();
115 // Set the chamber (sensitive region) GEANT identifier
117 ((AliRICHChamber*)(*fChambers)[0])->SetGid(1);
118 ((AliRICHChamber*)(*fChambers)[1])->SetGid(2);
119 ((AliRICHChamber*)(*fChambers)[2])->SetGid(3);
120 ((AliRICHChamber*)(*fChambers)[3])->SetGid(4);
121 ((AliRICHChamber*)(*fChambers)[4])->SetGid(5);
122 ((AliRICHChamber*)(*fChambers)[5])->SetGid(6);
123 ((AliRICHChamber*)(*fChambers)[6])->SetGid(7);
125 Float_t pos1[3]={0,471.8999,165.2599};
126 Chamber(0).SetChamberTransform(pos1[0],pos1[1],pos1[2],new TRotMatrix("rot993","rot993",90,0,70.69,90,19.30999,-90));
128 Float_t pos2[3]={171,470,0};
129 Chamber(1).SetChamberTransform(pos2[0],pos2[1],pos2[2],new TRotMatrix("rot994","rot994",90,-20,90,70,0,0));
131 Float_t pos3[3]={0,500,0};
132 Chamber(2).SetChamberTransform(pos3[0],pos3[1],pos3[2],new TRotMatrix("rot995","rot995",90,0,90,90,0,0));
134 Float_t pos4[3]={-171,470,0};
135 Chamber(3).SetChamberTransform(pos4[0],pos4[1],pos4[2], new TRotMatrix("rot996","rot996",90,20,90,110,0,0));
137 Float_t pos5[3]={161.3999,443.3999,-165.3};
138 Chamber(4).SetChamberTransform(pos5[0],pos5[1],pos5[2],new TRotMatrix("rot997","rot997",90,340,108.1999,70,18.2,70));
140 Float_t pos6[3]={0., 471.9, -165.3,};
141 Chamber(5).SetChamberTransform(pos6[0],pos6[1],pos6[2],new TRotMatrix("rot998","rot998",90,0,109.3099,90,19.30999,90));
143 Float_t pos7[3]={-161.399,443.3999,-165.3};
144 Chamber(6).SetChamberTransform(pos7[0],pos7[1],pos7[2],new TRotMatrix("rot999","rot999",90,20,108.1999,110,18.2,110));
146 segmentation=Chamber(0).GetSegmentationModel(0);
147 geometry=Chamber(0).GetGeometryModel();
148 response=Chamber(0).GetResponseModel();
151 printf("* Pads : %3dx%3d *\n",segmentation->Npx(),segmentation->Npy());
152 printf("* Pad size : %5.2f x%5.2f mm2 *\n",segmentation->Dpx(),segmentation->Dpy());
153 printf("* Gap Thickness : %5.1f mm *\n",geometry->GetGapThickness());
154 printf("* Radiator Width : %5.1f mm *\n",geometry->GetQuartzWidth());
155 printf("* Radiator Length : %5.1f mm *\n",geometry->GetQuartzLength());
156 printf("* Freon Thickness : %5.1f mm *\n",geometry->GetFreonThickness());
157 printf("* Charge Slope : %5.1f ADC *\n",response->ChargeSlope());
158 printf("* Feedback Prob. : %5.2f %% *\n",response->AlphaFeedback());
160 printf("* Success! *\n");
162 printf("*********************************************************************************\n");
166 //___________________________________________
167 void AliRICHv1::StepManager()
176 static Float_t hits[18];
177 static Float_t ckovData[19];
178 TLorentzVector position;
179 TLorentzVector momentum;
184 Float_t localTheta,localPhi;
186 Float_t destep, step;
190 static Float_t eloss, xhit, yhit, tlength;
191 const Float_t kBig=1.e10;
193 TClonesArray &lhits = *fHits;
194 TGeant3 *geant3 = (TGeant3*) gMC;
195 TParticle *current = (TParticle*)(*gAlice->Particles())[gAlice->CurrentTrack()];
197 //if (current->Energy()>1)
200 // Only gas gap inside chamber
201 // Tag chambers and record hits when track enters
204 id=gMC->CurrentVolID(copy);
205 Float_t cherenkovLoss=0;
206 //gAlice->KeepTrack(gAlice->CurrentTrack());
208 gMC->TrackPosition(position);
212 ckovData[1] = pos[0]; // X-position for hit
213 ckovData[2] = pos[1]; // Y-position for hit
214 ckovData[3] = pos[2]; // Z-position for hit
215 //ckovData[11] = gAlice->CurrentTrack();
217 //AliRICH *RICH = (AliRICH *) gAlice->GetDetector("RICH");
219 /********************Store production parameters for Cerenkov photons************************/
220 //is it a Cerenkov photon?
221 if (gMC->TrackPid() == 50000050) {
223 //if (gMC->VolId("GAP ")==gMC->CurrentVolID(copy))
225 Float_t ckovEnergy = current->Energy();
226 //energy interval for tracking
227 if (ckovEnergy > 5.6e-09 && ckovEnergy < 7.8e-09 )
228 //if (ckovEnergy > 0)
230 if (gMC->IsTrackEntering()){ //is track entering?
231 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
233 if (geant3->Gctrak()->nstep<1){ //is it the first step?
234 Int_t mother = current->GetFirstMother();
236 //printf("Second Mother:%d\n",current->GetSecondMother());
238 ckovData[10] = mother;
239 ckovData[11] = gAlice->CurrentTrack();
240 ckovData[12] = 1; //Media where photon was produced 1->Freon, 2->Quarz
243 //printf("Index: %d\n",fCkovNumber);
244 } //first step question
247 if (geant3->Gctrak()->nstep<1){ //is it first step?
248 if (gMC->VolId("QUAR")==gMC->CurrentVolID(copy)) //is it in quarz?
252 } //first step question
254 //printf("Before %d\n",fFreonProd);
255 } //track entering question
257 if (ckovData[12] == 1) //was it produced in Freon?
258 //if (fFreonProd == 1)
260 if (gMC->IsTrackEntering()){ //is track entering?
262 if (gMC->VolId("META")==gMC->CurrentVolID(copy)) //is it in gap?
264 //printf("Got in\n");
265 gMC->TrackMomentum(momentum);
270 // Z-position for hit
273 /**************** Photons lost in second grid have to be calculated by hand************/
275 Float_t cophi = TMath::Cos(TMath::ATan2(mom[0], mom[1]));
276 Float_t t = (1. - .025 / cophi) * (1. - .05 / cophi);
278 //printf("grid calculation:%f\n",t);
280 //geant3->StopTrack();
282 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
283 //printf("Lost one in grid\n");
285 /**********************************************************************************/
288 if (gMC->VolId("CSI ")==gMC->CurrentVolID(copy)) //is it in csi?
290 gMC->TrackMomentum(momentum);
296 /********* Photons lost by Fresnel reflection have to be calculated by hand********/
297 /***********************Cerenkov phtons (always polarised)*************************/
299 Float_t cophi = TMath::Cos(TMath::ATan2(mom[0], mom[1]));
300 Float_t t = Fresnel(ckovEnergy*1e9,cophi,1);
303 //geant3->StopTrack();
305 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
306 //printf("Lost by Fresnel\n");
308 /**********************************************************************************/
313 /********************Evaluation of losses************************/
314 /******************still in the old fashion**********************/
316 Int_t i1 = geant3->Gctrak()->nmec; //number of physics mechanisms acting on the particle
317 for (Int_t i = 0; i < i1; ++i) {
319 if (geant3->Gctrak()->lmec[i] == 106) { //was it reflected
321 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
323 if (gMC->CurrentVolID(copy) == gMC->VolId("QUAR"))
325 //geant3->StopTrack();
326 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
327 } //reflection question
331 else if (geant3->Gctrak()->lmec[i] == 101) { //was it absorbed?
333 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
335 if (gMC->CurrentVolID(copy) == gMC->VolId("QUAR"))
337 if (gMC->CurrentVolID(copy) == gMC->VolId("META"))
339 if (gMC->CurrentVolID(copy) == gMC->VolId("GAP "))
342 if (gMC->CurrentVolID(copy) == gMC->VolId("SRIC"))
346 if (gMC->CurrentVolID(copy) == gMC->VolId("CSI ")) {
349 //geant3->StopTrack();
350 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
351 //printf("Added cerenkov %d\n",fCkovNumber);
352 } //absorption question
355 // Photon goes out of tracking scope
356 else if (geant3->Gctrak()->lmec[i] == 30) { //is it below energy treshold?
358 //geant3->StopTrack();
359 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
360 } // energy treshold question
361 } //number of mechanisms cycle
362 /**********************End of evaluation************************/
363 } //freon production question
364 } //energy interval question
365 //}//inside the proximity gap question
366 } //cerenkov photon question
368 /**************************************End of Production Parameters Storing*********************/
371 /*******************************Treat photons that hit the CsI (Ckovs and Feedbacks)************/
373 if (gMC->TrackPid() == 50000050 || gMC->TrackPid() == 50000051) {
374 //printf("Cerenkov\n");
375 if (gMC->VolId("CSI ")==gMC->CurrentVolID(copy))
378 if (gMC->Edep() > 0.){
379 gMC->TrackPosition(position);
380 gMC->TrackMomentum(momentum);
388 Double_t tc = mom[0]*mom[0]+mom[1]*mom[1];
389 Double_t rt = TMath::Sqrt(tc);
390 theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg;
391 phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg;
392 gMC->Gmtod(pos,localPos,1);
393 gMC->Gmtod(mom,localMom,2);
395 gMC->CurrentVolOffID(2,copy);
399 //Int_t sector=((AliRICHChamber*) (*fChambers)[idvol])
400 //->Sector(localPos[0], localPos[2]);
401 //printf("Sector:%d\n",sector);
403 /*if (gMC->TrackPid() == 50000051){
405 printf("Feedbacks:%d\n",fFeedbacks);
408 ((AliRICHChamber*) (*fChambers)[idvol])
409 ->SigGenInit(localPos[0], localPos[2], localPos[1]);
411 ckovData[0] = gMC->TrackPid(); // particle type
412 ckovData[1] = pos[0]; // X-position for hit
413 ckovData[2] = pos[1]; // Y-position for hit
414 ckovData[3] = pos[2]; // Z-position for hit
415 ckovData[4] = theta; // theta angle of incidence
416 ckovData[5] = phi; // phi angle of incidence
417 ckovData[8] = (Float_t) fNPadHits; // first padhit
418 ckovData[9] = -1; // last pad hit
419 ckovData[13] = 4; // photon was detected
420 ckovData[14] = mom[0];
421 ckovData[15] = mom[1];
422 ckovData[16] = mom[2];
424 destep = gMC->Edep();
425 gMC->SetMaxStep(kBig);
426 cherenkovLoss += destep;
427 ckovData[7]=cherenkovLoss;
429 nPads = MakePadHits(localPos[0],localPos[2],cherenkovLoss,idvol,kCerenkov);
430 if (fNPadHits > (Int_t)ckovData[8]) {
431 ckovData[8]= ckovData[8]+1;
432 ckovData[9]= (Float_t) fNPadHits;
435 ckovData[17] = nPads;
436 //printf("nPads:%d",nPads);
438 //TClonesArray *Hits = RICH->Hits();
439 AliRICHHit *mipHit = (AliRICHHit*) (fHits->UncheckedAt(0));
442 mom[0] = current->Px();
443 mom[1] = current->Py();
444 mom[2] = current->Pz();
445 Float_t mipPx = mipHit->fMomX;
446 Float_t mipPy = mipHit->fMomY;
447 Float_t mipPz = mipHit->fMomZ;
449 Float_t r = mom[0]*mom[0] + mom[1]*mom[1] + mom[2]*mom[2];
450 Float_t rt = TMath::Sqrt(r);
451 Float_t mipR = mipPx*mipPx + mipPy*mipPy + mipPz*mipPz;
452 Float_t mipRt = TMath::Sqrt(mipR);
455 coscerenkov = (mom[0]*mipPx + mom[1]*mipPy + mom[2]*mipPz)/(rt*mipRt);
461 Float_t cherenkov = TMath::ACos(coscerenkov);
462 ckovData[18]=cherenkov;
466 AddHit(gAlice->CurrentTrack(),vol,ckovData);
467 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
474 /***********************************************End of photon hits*********************************************/
477 /**********************************************Charged particles treatment*************************************/
479 else if (gMC->TrackCharge())
483 /*if (gMC->IsTrackEntering())
485 hits[13]=20;//is track entering?
487 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
492 if (gMC->VolId("GAP ")== gMC->CurrentVolID(copy)) {
493 // Get current particle id (ipart), track position (pos) and momentum (mom)
495 gMC->CurrentVolOffID(3,copy);
499 //Int_t sector=((AliRICHChamber*) (*fChambers)[idvol])
500 //->Sector(localPos[0], localPos[2]);
501 //printf("Sector:%d\n",sector);
503 gMC->TrackPosition(position);
504 gMC->TrackMomentum(momentum);
512 gMC->Gmtod(pos,localPos,1);
513 gMC->Gmtod(mom,localMom,2);
515 ipart = gMC->TrackPid();
517 // momentum loss and steplength in last step
518 destep = gMC->Edep();
519 step = gMC->TrackStep();
522 // record hits when track enters ...
523 if( gMC->IsTrackEntering()) {
524 // gMC->SetMaxStep(fMaxStepGas);
525 Double_t tc = mom[0]*mom[0]+mom[1]*mom[1];
526 Double_t rt = TMath::Sqrt(tc);
527 theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg;
528 phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg;
531 Double_t localTc = localMom[0]*localMom[0]+localMom[2]*localMom[2];
532 Double_t localRt = TMath::Sqrt(localTc);
533 localTheta = Float_t(TMath::ATan2(localRt,Double_t(localMom[1])))*kRaddeg;
534 localPhi = Float_t(TMath::ATan2(Double_t(localMom[2]),Double_t(localMom[0])))*kRaddeg;
536 hits[0] = Float_t(ipart); // particle type
537 hits[1] = localPos[0]; // X-position for hit
538 hits[2] = localPos[1]; // Y-position for hit
539 hits[3] = localPos[2]; // Z-position for hit
540 hits[4] = localTheta; // theta angle of incidence
541 hits[5] = localPhi; // phi angle of incidence
542 hits[8] = (Float_t) fNPadHits; // first padhit
543 hits[9] = -1; // last pad hit
544 hits[13] = fFreonProd; // did id hit the freon?
553 Chamber(idvol).LocaltoGlobal(localPos,hits+1);
556 //To make chamber coordinates x-y had to pass localPos[0], localPos[2]
559 // Only if not trigger chamber
562 // Initialize hit position (cursor) in the segmentation model
563 ((AliRICHChamber*) (*fChambers)[idvol])
564 ->SigGenInit(localPos[0], localPos[2], localPos[1]);
569 // Calculate the charge induced on a pad (disintegration) in case
571 // Mip left chamber ...
572 if( gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()){
573 gMC->SetMaxStep(kBig);
578 // Only if not trigger chamber
582 if(gMC->TrackPid() == kNeutron)
583 printf("\n\n\n\n\n Neutron Making Pad Hit!!! \n\n\n\n");
584 nPads = MakePadHits(xhit,yhit,eloss,idvol,kMip);
586 //printf("nPads:%d",nPads);
592 if (fNPadHits > (Int_t)hits[8]) {
594 hits[9]= (Float_t) fNPadHits;
598 new(lhits[fNhits++]) AliRICHHit(fIshunt,gAlice->CurrentTrack(),vol,hits);
601 // Check additional signal generation conditions
602 // defined by the segmentation
603 // model (boundary crossing conditions)
605 (((AliRICHChamber*) (*fChambers)[idvol])
606 ->SigGenCond(localPos[0], localPos[2], localPos[1]))
608 ((AliRICHChamber*) (*fChambers)[idvol])
609 ->SigGenInit(localPos[0], localPos[2], localPos[1]);
612 if(gMC->TrackPid() == kNeutron)
613 printf("\n\n\n\n\n Neutron Making Pad Hit!!! \n\n\n\n");
614 nPads = MakePadHits(xhit,yhit,eloss,idvol,kMip);
616 //printf("Npads:%d",NPads);
623 // nothing special happened, add up energy loss
630 /*************************************************End of MIP treatment**************************************/