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 ///////////////////////////////////////////////////////////////////////////////
20 // Transition Radiation Detector version 1 -- slow simulator //
24 <img src="picts/AliTRDfullClass.gif">
29 ///////////////////////////////////////////////////////////////////////////////
34 #include <TLorentzVector.h>
38 #include <TVirtualMC.h>
44 #include "AliTRDgeometry.h"
45 #include "AliTRDhit.h"
46 #include "AliTRDsim.h"
51 //_____________________________________________________________________________
52 AliTRDv1::AliTRDv1():AliTRD()
55 // Default constructor
64 fTypeOfStepManager = 1;
68 //_____________________________________________________________________________
69 AliTRDv1::AliTRDv1(const char *name, const char *title)
73 // Standard constructor for Transition Radiation Detector version 1
81 fTypeOfStepManager = 1;
83 SetBufferSize(128000);
87 //_____________________________________________________________________________
88 AliTRDv1::AliTRDv1(const AliTRDv1 &trd):AliTRD(trd)
94 ((AliTRDv1 &) trd).Copy(*this);
98 //_____________________________________________________________________________
102 // AliTRDv1 destructor
105 if (fDeltaE) delete fDeltaE;
106 if (fDeltaG) delete fDeltaG;
111 //_____________________________________________________________________________
112 AliTRDv1 &AliTRDv1::operator=(const AliTRDv1 &trd)
115 // Assignment operator
118 if (this != &trd) ((AliTRDv1 &) trd).Copy(*this);
123 //_____________________________________________________________________________
124 void AliTRDv1::Copy(TObject &trd) const
126 printf("void AliTRDv1::Copy(TObject &trd) const\n");
131 ((AliTRDv1 &) trd).fTypeOfStepManager = fTypeOfStepManager;
132 ((AliTRDv1 &) trd).fStepSize = fStepSize;
134 ((AliTRDv1 &) trd).fTRon = fTRon;
136 fDeltaE->Copy(*((AliTRDv1 &) trd).fDeltaE);
137 fDeltaG->Copy(*((AliTRDv1 &) trd).fDeltaG);
138 fTR->Copy(*((AliTRDv1 &) trd).fTR);
142 //_____________________________________________________________________________
143 void AliTRDv1::CreateGeometry()
146 // Create the GEANT geometry for the Transition Radiation Detector - Version 1
147 // This version covers the full azimuth.
150 // Check that FRAME is there otherwise we have no place where to put the TRD
151 AliModule* frame = gAlice->GetModule("FRAME");
154 // Define the chambers
155 AliTRD::CreateGeometry();
159 //_____________________________________________________________________________
160 void AliTRDv1::CreateMaterials()
163 // Create materials for the Transition Radiation Detector version 1
166 AliTRD::CreateMaterials();
170 //_____________________________________________________________________________
171 void AliTRDv1::CreateTRhit(Int_t det)
174 // Creates an electron cluster from a TR photon.
175 // The photon is assumed to be created a the end of the radiator. The
176 // distance after which it deposits its energy takes into account the
177 // absorbtion of the entrance window and of the gas mixture in drift
182 const Int_t kPdgElectron = 11;
185 const Float_t kWion = 23.53;
187 // Maximum number of TR photons per track
188 const Int_t kNTR = 50;
190 TLorentzVector mom, pos;
192 // Create TR at the entrance of the chamber
193 if (gMC->IsTrackEntering()) {
195 // Create TR only for electrons
196 Int_t iPdg = gMC->TrackPid();
197 if (TMath::Abs(iPdg) != kPdgElectron) return;
203 gMC->TrackMomentum(mom);
204 Float_t pTot = mom.Rho();
205 fTR->CreatePhotons(iPdg,pTot,nTR,eTR);
207 AliFatal(Form("Boundary error: nTR = %d, kNTR = %d",nTR,kNTR));
210 // Loop through the TR photons
211 for (Int_t iTR = 0; iTR < nTR; iTR++) {
213 Float_t energyMeV = eTR[iTR] * 0.001;
214 Float_t energyeV = eTR[iTR] * 1000.0;
215 Float_t absLength = 0;
218 // Take the absorbtion in the entrance window into account
219 Double_t muMy = fTR->GetMuMy(energyMeV);
220 sigma = muMy * fFoilDensity;
222 absLength = gRandom->Exp(1.0/sigma);
223 if (absLength < AliTRDgeometry::MyThick()) continue;
229 // The absorbtion cross sections in the drift gas
230 // Gas-mixture (Xe/CO2)
231 Double_t muXe = fTR->GetMuXe(energyMeV);
232 Double_t muCO = fTR->GetMuCO(energyMeV);
233 sigma = (0.85 * muXe + 0.15 * muCO) * fGasDensity * fTR->GetTemp();
235 // The distance after which the energy of the TR photon
238 absLength = gRandom->Exp(1.0/sigma);
239 if (absLength > (AliTRDgeometry::DrThick()
240 + AliTRDgeometry::AmThick())) {
248 // The position of the absorbtion
250 gMC->TrackPosition(pos);
251 posHit[0] = pos[0] + mom[0] / pTot * absLength;
252 posHit[1] = pos[1] + mom[1] / pTot * absLength;
253 posHit[2] = pos[2] + mom[2] / pTot * absLength;
256 Int_t q = ((Int_t) (energyeV / kWion));
258 // Add the hit to the array. TR photon hits are marked
259 // by negative charge
260 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber(),det,posHit,-q,kTRUE);
268 //_____________________________________________________________________________
269 void AliTRDv1::Init()
272 // Initialise Transition Radiation Detector after geometry has been built.
277 AliDebug(1,"Slow simulator\n");
279 // Switch on TR simulation as default
281 AliInfo("TR simulation off");
284 fTR = new AliTRDsim();
287 // First ionization potential (eV) for the gas mixture (90% Xe + 10% CO2)
288 const Float_t kPoti = 12.1;
289 // Maximum energy (50 keV);
290 const Float_t kEend = 50000.0;
291 // Ermilova distribution for the delta-ray spectrum
292 Float_t poti = TMath::Log(kPoti);
293 Float_t eEnd = TMath::Log(kEend);
295 // Ermilova distribution for the delta-ray spectrum
296 fDeltaE = new TF1("deltae" ,Ermilova ,poti,eEnd,0);
298 // Geant3 distribution for the delta-ray spectrum
299 fDeltaG = new TF1("deltag",IntSpecGeant,2.421257,28.536469,0);
301 AliDebug(1,"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
305 //_____________________________________________________________________________
306 void AliTRDv1::StepManager()
309 // Slow simulator. Every charged track produces electron cluster as hits
310 // along its path across the drift volume.
313 switch (fTypeOfStepManager) {
314 case 0 : StepManagerErmilova(); break; // 0 is Ermilova
315 case 1 : StepManagerGeant(); break; // 1 is Geant
316 case 2 : StepManagerFixedStep(); break; // 2 is fixed step
317 default : AliWarning("Not a valid Step Manager.");
322 //_____________________________________________________________________________
323 void AliTRDv1::SelectStepManager(Int_t t)
326 // Selects a step manager type:
329 // 2 - Fixed step size
332 fTypeOfStepManager = t;
333 AliInfo(Form("Step Manager type %d was selected",fTypeOfStepManager));
337 //_____________________________________________________________________________
338 void AliTRDv1::StepManagerGeant()
341 // Slow simulator. Every charged track produces electron cluster as hits
342 // along its path across the drift volume. The step size is set acording
343 // to Bethe-Bloch. The energy distribution of the delta electrons follows
344 // a spectrum taken from Geant3.
346 // Version by A. Bercuci
362 Double_t betaGamma, pp;
363 Double_t stepSize = 0;
365 Bool_t drRegion = kFALSE;
366 Bool_t amRegion = kFALSE;
369 TString cIdSensDr = "J";
370 TString cIdSensAm = "K";
371 Char_t cIdChamber[3];
374 TLorentzVector pos, mom;
378 const Int_t kNplan = AliTRDgeometry::Nplan();
379 const Int_t kNcham = AliTRDgeometry::Ncham();
380 const Int_t kNdetsec = kNplan * kNcham;
382 const Double_t kBig = 1.0E+12; // Infinitely big
383 const Float_t kWion = 23.53; // Ionization energy
384 const Float_t kPTotMaxEl = 0.002; // Maximum momentum for e+ e- g
386 // Minimum energy for the step size adjustment
387 const Float_t kEkinMinStep = 1.0e-5;
388 // energy threshold for production of delta electrons
389 const Float_t kECut = 1.0e4;
390 // Parameters entering the parametrized range for delta electrons
391 const Float_t kRa = 5.37E-4;
392 const Float_t kRb = 0.9815;
393 const Float_t kRc = 3.123E-3;
394 // Gas density -> To be made user adjustable !
395 const Float_t kRho = 0.004945 ; //[0.85*0.00549+0.15*0.00186 (Xe-CO2 85-15)]
397 // Plateau value of the energy-loss for electron in xenon
398 // taken from: Allison + Comb, Ann. Rev. Nucl. Sci. (1980), 30, 253
399 //const Double_t kPlateau = 1.70;
400 // the averaged value (26/3/99)
401 const Float_t kPlateau = 1.55;
403 const Float_t kPrim = 19.34; // dN1/dx|min for the gas mixture (90% Xe + 10% CO2)
404 // First ionization potential (eV) for the gas mixture (90% Xe + 10% CO2)
405 const Float_t kPoti = 12.1;
407 const Int_t kPdgElectron = 11; // PDG code electron
409 // Set the maximum step size to a very large number for all
410 // neutral particles and those outside the driftvolume
411 gMC->SetMaxStep(kBig);
413 // Use only charged tracks
414 if (( gMC->TrackCharge() ) &&
415 (!gMC->IsTrackDisappeared())) {
417 // Inside a sensitive volume?
420 cIdCurrent = gMC->CurrentVolName();
421 if (cIdSensDr == cIdCurrent[1]) {
424 if (cIdSensAm == cIdCurrent[1]) {
427 if (drRegion || amRegion) {
429 // The hit coordinates and charge
430 gMC->TrackPosition(pos);
435 // The sector number (0 - 17)
436 // The numbering goes clockwise and starts at y = 0
437 Float_t phi = kRaddeg*TMath::ATan2(pos[0],pos[1]);
442 sec = ((Int_t) (phi / 20));
444 // The plane and chamber number
445 cIdChamber[0] = cIdCurrent[2];
446 cIdChamber[1] = cIdCurrent[3];
447 Int_t idChamber = (atoi(cIdChamber) % kNdetsec);
448 cha = kNcham - ((Int_t) idChamber / kNplan) - 1;
449 pla = ((Int_t) idChamber % kNplan);
451 // Check on selected volumes
452 Int_t addthishit = 1;
457 // The detector number
458 det = fGeometry->GetDetector(pla,cha,sec);
460 // Special hits only in the drift region
463 // Create a track reference at the entrance and
464 // exit of each chamber that contain the
465 // momentum components of the particle
466 if (gMC->IsTrackEntering() || gMC->IsTrackExiting()) {
467 gMC->TrackMomentum(mom);
468 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
471 if (gMC->IsTrackEntering() && !gMC->IsNewTrack()) {
472 // determine if hit belong to primary track
473 fPrimaryTrackPid = gAlice->GetMCApp()->GetCurrentTrackNumber();
474 // determine track length when entering the detector
475 fTrackLength0 = gMC->TrackLength();
478 // Create the hits from TR photons
479 if (fTR) CreateTRhit(det);
483 // Calculate the energy of the delta-electrons
484 // modified by Alex Bercuci (A.Bercuci@gsi.de) on 26.01.06
485 // take into account correlation with the underlying GEANT tracking
487 // http://www-linux.gsi.de/~abercuci/Contributions/TRD/index.html
489 // determine the most significant process (last on the processes list)
490 // which caused this hit
491 gMC->StepProcesses(processes);
492 Int_t nofprocesses = processes.GetSize();
498 pid = processes[nofprocesses-1];
501 // generate Edep according to GEANT parametrisation
502 eDelta = TMath::Exp(fDeltaG->GetRandom()) - kPoti;
503 eDelta = TMath::Max(eDelta,0.0);
504 Float_t pr_range = 0.0;
505 Float_t range = gMC->TrackLength() - fTrackLength0;
506 // merge GEANT tracker information with locally cooked one
507 if (gAlice->GetMCApp()->GetCurrentTrackNumber() == fPrimaryTrackPid) {
508 // printf("primary pid=%d eDelta=%f\n",pid,eDelta);
510 if (eDelta >= kECut) {
511 pr_range = kRa*eDelta*0.001*(1.0-kRb/(1.0+kRc*eDelta*0.001))/kRho;
512 if (pr_range >= (3.7-range)) eDelta *= 0.1;
516 if (eDelta < kECut) {
520 pr_range = kRa*eDelta*0.001*(1.0-kRb/(1.0+kRc*eDelta*0.001))/kRho;
521 if (pr_range >= ((AliTRDgeometry::DrThick()
522 + AliTRDgeometry::AmThick()) - range)) {
538 // Generate the electron cluster size
543 qTot = ((Int_t) (eDelta / kWion) + 1);
546 // Create a new dEdx hit
547 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber(),det,hits,qTot, drRegion);
549 // Calculate the maximum step size for the next tracking step
550 // Produce only one hit if Ekin is below cutoff
551 aMass = gMC->TrackMass();
552 if ((gMC->Etot() - aMass) > kEkinMinStep) {
554 // The energy loss according to Bethe Bloch
555 iPdg = TMath::Abs(gMC->TrackPid());
556 if ((iPdg != kPdgElectron) ||
557 ((iPdg == kPdgElectron) && (pTot < kPTotMaxEl))) {
558 gMC->TrackMomentum(mom);
560 betaGamma = pTot / aMass;
561 pp = BetheBlochGeant(betaGamma);
562 // Take charge > 1 into account
563 charge = gMC->TrackCharge();
564 if (TMath::Abs(charge) > 1) {
565 pp = pp * charge*charge;
569 // Electrons above 20 Mev/c are at the plateau
570 pp = kPrim * kPlateau;
574 do {nsteps = gRandom->Poisson(pp);} while(!nsteps);
575 stepSize = 1./nsteps;
576 gMC->SetMaxStep(stepSize);
588 //_____________________________________________________________________________
589 void AliTRDv1::StepManagerErmilova()
592 // Slow simulator. Every charged track produces electron cluster as hits
593 // along its path across the drift volume. The step size is set acording
594 // to Bethe-Bloch. The energy distribution of the delta electrons follows
595 // a spectrum taken from Ermilova et al.
612 Double_t betaGamma, pp;
615 Bool_t drRegion = kFALSE;
616 Bool_t amRegion = kFALSE;
619 TString cIdSensDr = "J";
620 TString cIdSensAm = "K";
621 Char_t cIdChamber[3];
624 TLorentzVector pos, mom;
626 const Int_t kNplan = AliTRDgeometry::Nplan();
627 const Int_t kNcham = AliTRDgeometry::Ncham();
628 const Int_t kNdetsec = kNplan * kNcham;
630 const Double_t kBig = 1.0E+12; // Infinitely big
631 const Float_t kWion = 23.53; // Ionization energy
632 const Float_t kPTotMaxEl = 0.002; // Maximum momentum for e+ e- g
634 // energy threshold for production of delta electrons
635 //const Float_t kECut = 1.0e4;
636 // Parameters entering the parametrized range for delta electrons
637 //const float ra=5.37E-4, rb=0.9815, rc=3.123E-3;
638 // Gas density -> To be made user adjustable !
639 //const float rho=0.004945 ; //[0.85*0.00549+0.15*0.00186 (Xe-CO2 85-15)]
641 // Minimum energy for the step size adjustment
642 const Float_t kEkinMinStep = 1.0e-5;
644 // Plateau value of the energy-loss for electron in xenon
645 // taken from: Allison + Comb, Ann. Rev. Nucl. Sci. (1980), 30, 253
646 //const Double_t kPlateau = 1.70;
647 // the averaged value (26/3/99)
648 const Float_t kPlateau = 1.55;
650 const Float_t kPrim = 48.0; // dN1/dx|min for the gas mixture (90% Xe + 10% CO2)
651 // First ionization potential (eV) for the gas mixture (90% Xe + 10% CO2)
652 const Float_t kPoti = 12.1;
654 const Int_t kPdgElectron = 11; // PDG code electron
656 // Set the maximum step size to a very large number for all
657 // neutral particles and those outside the driftvolume
658 gMC->SetMaxStep(kBig);
660 // Use only charged tracks
661 if (( gMC->TrackCharge() ) &&
662 (!gMC->IsTrackDisappeared())) {
664 // Inside a sensitive volume?
667 cIdCurrent = gMC->CurrentVolName();
668 if (cIdSensDr == cIdCurrent[1]) {
671 if (cIdSensAm == cIdCurrent[1]) {
674 if (drRegion || amRegion) {
676 // The hit coordinates and charge
677 gMC->TrackPosition(pos);
682 // The sector number (0 - 17)
683 // The numbering goes clockwise and starts at y = 0
684 Float_t phi = kRaddeg*TMath::ATan2(pos[0],pos[1]);
689 sec = ((Int_t) (phi / 20));
691 // The plane and chamber number
692 cIdChamber[0] = cIdCurrent[2];
693 cIdChamber[1] = cIdCurrent[3];
694 Int_t idChamber = (atoi(cIdChamber) % kNdetsec);
695 cha = kNcham - ((Int_t) idChamber / kNplan) - 1;
696 pla = ((Int_t) idChamber % kNplan);
698 // Check on selected volumes
699 Int_t addthishit = 1;
704 // The detector number
705 det = fGeometry->GetDetector(pla,cha,sec);
707 // Special hits only in the drift region
710 // Create a track reference at the entrance and
711 // exit of each chamber that contain the
712 // momentum components of the particle
713 if (gMC->IsTrackEntering() || gMC->IsTrackExiting()) {
714 gMC->TrackMomentum(mom);
715 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
717 // Create the hits from TR photons
718 if (fTR) CreateTRhit(det);
722 // Calculate the energy of the delta-electrons
723 eDelta = TMath::Exp(fDeltaE->GetRandom()) - kPoti;
724 eDelta = TMath::Max(eDelta,0.0);
725 // Generate the electron cluster size
726 if(eDelta==0.) qTot=0;
727 else qTot = ((Int_t) (eDelta / kWion) + 1);
729 // Create a new dEdx hit
731 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
732 ,det,hits,qTot, kTRUE);
735 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
736 ,det,hits,qTot,kFALSE);
739 // Calculate the maximum step size for the next tracking step
740 // Produce only one hit if Ekin is below cutoff
741 aMass = gMC->TrackMass();
742 if ((gMC->Etot() - aMass) > kEkinMinStep) {
744 // The energy loss according to Bethe Bloch
745 iPdg = TMath::Abs(gMC->TrackPid());
746 if ( (iPdg != kPdgElectron) ||
747 ((iPdg == kPdgElectron) && (pTot < kPTotMaxEl))) {
748 gMC->TrackMomentum(mom);
750 betaGamma = pTot / aMass;
751 pp = kPrim * BetheBloch(betaGamma);
752 // Take charge > 1 into account
753 charge = gMC->TrackCharge();
754 if (TMath::Abs(charge) > 1) pp = pp * charge*charge;
755 } else { // Electrons above 20 Mev/c are at the plateau
756 pp = kPrim * kPlateau;
761 gMC->GetRandom()->RndmArray(1, random);
762 while ((random[0] == 1.) || (random[0] == 0.));
763 stepSize = - TMath::Log(random[0]) / pp;
764 gMC->SetMaxStep(stepSize);
772 //_____________________________________________________________________________
773 void AliTRDv1::StepManagerFixedStep()
776 // Slow simulator. Every charged track produces electron cluster as hits
777 // along its path across the drift volume. The step size is fixed in
778 // this version of the step manager.
790 Bool_t drRegion = kFALSE;
791 Bool_t amRegion = kFALSE;
794 TString cIdSensDr = "J";
795 TString cIdSensAm = "K";
796 Char_t cIdChamber[3];
799 TLorentzVector pos, mom;
801 const Int_t kNplan = AliTRDgeometry::Nplan();
802 const Int_t kNcham = AliTRDgeometry::Ncham();
803 const Int_t kNdetsec = kNplan * kNcham;
805 const Double_t kBig = 1.0E+12;
807 const Float_t kWion = 23.53; // Ionization energy
808 const Float_t kEkinMinStep = 1.0e-5; // Minimum energy for the step size adjustment
810 // Set the maximum step size to a very large number for all
811 // neutral particles and those outside the driftvolume
812 gMC->SetMaxStep(kBig);
814 // If not charged track or already stopped or disappeared, just return.
815 if ((!gMC->TrackCharge()) ||
816 gMC->IsTrackDisappeared()) return;
818 // Inside a sensitive volume?
819 cIdCurrent = gMC->CurrentVolName();
821 if (cIdSensDr == cIdCurrent[1]) drRegion = kTRUE;
822 if (cIdSensAm == cIdCurrent[1]) amRegion = kTRUE;
824 if ((!drRegion) && (!amRegion)) return;
826 // The hit coordinates and charge
827 gMC->TrackPosition(pos);
832 // The sector number (0 - 17)
833 // The numbering goes clockwise and starts at y = 0
834 Float_t phi = kRaddeg*TMath::ATan2(pos[0],pos[1]);
835 if (phi < 90.) phi += 270.;
837 sec = ((Int_t) (phi / 20.));
839 // The plane and chamber number
840 cIdChamber[0] = cIdCurrent[2];
841 cIdChamber[1] = cIdCurrent[3];
842 Int_t idChamber = (atoi(cIdChamber) % kNdetsec);
843 cha = kNcham - ((Int_t) idChamber / kNplan) - 1;
844 pla = ((Int_t) idChamber % kNplan);
846 // Check on selected volumes
847 Int_t addthishit = 1;
849 if (!addthishit) return;
851 det = fGeometry->GetDetector(pla,cha,sec); // The detector number
853 Int_t trkStat = 0; // 0: InFlight 1:Entering 2:Exiting
855 // Special hits only in the drift region
858 // Create a track reference at the entrance and exit of each
859 // chamber that contain the momentum components of the particle
861 if (gMC->IsTrackEntering()) {
862 gMC->TrackMomentum(mom);
863 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
866 if (gMC->IsTrackExiting()) {
867 gMC->TrackMomentum(mom);
868 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
872 // Create the hits from TR photons
873 if (fTR) CreateTRhit(det);
877 // Calculate the charge according to GEANT Edep
878 // Create a new dEdx hit
879 eDep = TMath::Max(gMC->Edep(),0.0) * 1.0e+09;
880 qTot = (Int_t) (eDep / kWion);
881 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
882 ,det,hits,qTot,drRegion);
884 // Set Maximum Step Size
885 // Produce only one hit if Ekin is below cutoff
886 if ((gMC->Etot() - gMC->TrackMass()) < kEkinMinStep) return;
887 gMC->SetMaxStep(fStepSize);
891 //_____________________________________________________________________________
892 Double_t AliTRDv1::BetheBloch(Double_t bg)
895 // Parametrization of the Bethe-Bloch-curve
896 // The parametrization is the same as for the TPC and is taken from Lehrhaus.
899 // This parameters have been adjusted to averaged values from GEANT
900 const Double_t kP1 = 7.17960e-02;
901 const Double_t kP2 = 8.54196;
902 const Double_t kP3 = 1.38065e-06;
903 const Double_t kP4 = 5.30972;
904 const Double_t kP5 = 2.83798;
906 // This parameters have been adjusted to Xe-data found in:
907 // Allison & Cobb, Ann. Rev. Nucl. Sci. (1980), 30, 253
908 //const Double_t kP1 = 0.76176E-1;
909 //const Double_t kP2 = 10.632;
910 //const Double_t kP3 = 3.17983E-6;
911 //const Double_t kP4 = 1.8631;
912 //const Double_t kP5 = 1.9479;
914 // Lower cutoff of the Bethe-Bloch-curve to limit step sizes
915 const Double_t kBgMin = 0.8;
916 const Double_t kBBMax = 6.83298;
917 //const Double_t kBgMin = 0.6;
918 //const Double_t kBBMax = 17.2809;
919 //const Double_t kBgMin = 0.4;
920 //const Double_t kBBMax = 82.0;
923 Double_t yy = bg / TMath::Sqrt(1. + bg*bg);
924 Double_t aa = TMath::Power(yy,kP4);
925 Double_t bb = TMath::Power((1./bg),kP5);
926 bb = TMath::Log(kP3 + bb);
927 return ((kP2 - aa - bb)*kP1 / aa);
935 //_____________________________________________________________________________
936 Double_t AliTRDv1::BetheBlochGeant(Double_t bg)
939 // Return dN/dx (number of primary collisions per centimeter)
940 // for given beta*gamma factor.
942 // Implemented by K.Oyama according to GEANT 3 parametrization shown in
943 // A.Andronic's webpage: http://www-alice.gsi.de/trd/papers/dedx/dedx.html
944 // This must be used as a set with IntSpecGeant.
947 Double_t arr_g[20] = {
948 1.100000, 1.200000, 1.300000, 1.500000,
949 1.800000, 2.000000, 2.500000, 3.000000,
950 4.000000, 7.000000, 10.000000, 20.000000,
951 40.000000, 70.000000, 100.000000, 300.000000,
952 600.000000, 1000.000000, 3000.000000, 10000.000000 };
954 Double_t arr_nc[20] = {
955 75.009056, 45.508083, 35.299252, 27.116327,
956 22.734999, 21.411915, 19.934095, 19.449375,
957 19.344431, 20.185553, 21.027925, 22.912676,
958 24.933352, 26.504053, 27.387468, 29.566597,
959 30.353779, 30.787134, 31.129285, 31.157350 };
961 // betagamma to gamma
962 Double_t g = TMath::Sqrt( 1. + bg*bg );
964 // Find the index just before the point we need.
966 for( i = 0 ; i < 18 ; i++ )
967 if( arr_g[i] < g && arr_g[i+1] > g )
970 // Simple interpolation.
971 Double_t pp = ((arr_nc[i+1] - arr_nc[i]) /
972 (arr_g[i+1]-arr_g[i])) * (g-arr_g[i]) + arr_nc[i];
974 return pp; //arr_nc[8];
978 //_____________________________________________________________________________
979 void AliTRDv1::Stepping()
998 gMC->TrackPosition(x, y, z);
999 cout << setw(8) << setprecision(3) << x << " "
1000 << setw(8) << setprecision(3) << y << " "
1001 << setw(8) << setprecision(3) << z << " ";
1005 Double_t px, py, pz, etot;
1006 gMC->TrackMomentum(px, py, pz, etot);
1007 Double_t ekin = etot - gMC->TrackMass();
1008 cout << setw(9) << setprecision(4) << ekin*1e03 << " ";
1012 cout << setw(9) << setprecision(4) << gMC->Edep()*1e03 << " ";
1016 cout << setw(8) << setprecision(3) << gMC->TrackStep() << " ";
1020 cout << setw(8) << setprecision(3) << gMC->TrackLength() << " ";
1024 if (gMC->CurrentVolName() != 0)
1025 cout << setw(4) << gMC->CurrentVolName() << " ";
1027 cout << setw(4) << "None" << " ";
1032 Int_t nofProcesses = gMC->StepProcesses(processes);
1033 for(int ip=0;ip<nofProcesses; ip++)
1034 cout << TMCProcessName[processes[ip]]<<" / ";
1040 //_____________________________________________________________________________
1041 Double_t Ermilova(Double_t *x, Double_t *)
1044 // Calculates the delta-ray energy distribution according to Ermilova.
1045 // Logarithmic scale !
1054 const Int_t kNv = 31;
1056 Float_t vxe[kNv] = { 2.3026, 2.9957, 3.4012, 3.6889, 3.9120
1057 , 4.0943, 4.2485, 4.3820, 4.4998, 4.6052
1058 , 4.7005, 5.0752, 5.2983, 5.7038, 5.9915
1059 , 6.2146, 6.5221, 6.9078, 7.3132, 7.6009
1060 , 8.0064, 8.5172, 8.6995, 8.9872, 9.2103
1061 , 9.4727, 9.9035,10.3735,10.5966,10.8198
1064 Float_t vye[kNv] = { 80.0 , 31.0 , 23.3 , 21.1 , 21.0
1065 , 20.9 , 20.8 , 20.0 , 16.0 , 11.0
1066 , 8.0 , 6.0 , 5.2 , 4.6 , 4.0
1067 , 3.5 , 3.0 , 1.4 , 0.67 , 0.44
1068 , 0.3 , 0.18 , 0.12 , 0.08 , 0.056
1069 , 0.04 , 0.023, 0.015, 0.011, 0.01
1074 // Find the position
1078 dpos = energy - vxe[pos2++];
1082 if (pos2 > kNv) pos2 = kNv - 1;
1085 // Differentiate between the sampling points
1086 dnde = (vye[pos1] - vye[pos2]) / (vxe[pos2] - vxe[pos1]);
1092 //_____________________________________________________________________________
1093 Double_t IntSpecGeant(Double_t *x, Double_t *)
1096 // Integrated spectrum from Geant3
1099 const Int_t npts = 83;
1100 Double_t arre[npts] = {
1101 2.421257, 2.483278, 2.534301, 2.592230,
1102 2.672067, 2.813299, 3.015059, 3.216819,
1103 3.418579, 3.620338, 3.868209, 3.920198,
1104 3.978284, 4.063923, 4.186264, 4.308605,
1105 4.430946, 4.553288, 4.724261, 4.837736,
1106 4.999842, 5.161949, 5.324056, 5.486163,
1107 5.679688, 5.752998, 5.857728, 5.962457,
1108 6.067185, 6.171914, 6.315653, 6.393674,
1109 6.471694, 6.539689, 6.597658, 6.655627,
1110 6.710957, 6.763648, 6.816338, 6.876198,
1111 6.943227, 7.010257, 7.106285, 7.252151,
1112 7.460531, 7.668911, 7.877290, 8.085670,
1113 8.302979, 8.353585, 8.413120, 8.483500,
1114 8.541030, 8.592857, 8.668865, 8.820485,
1115 9.037086, 9.253686, 9.470286, 9.686887,
1116 9.930838, 9.994655, 10.085822, 10.176990,
1117 10.268158, 10.359325, 10.503614, 10.627565,
1118 10.804637, 10.981709, 11.158781, 11.335854,
1119 11.593397, 11.781165, 12.049404, 12.317644,
1120 12.585884, 12.854123, 14.278421, 16.975889,
1121 20.829416, 24.682943, 28.536469
1124 Double_t arrdndx[npts] = {
1125 19.344431, 18.664679, 18.136106, 17.567745,
1126 16.836426, 15.677382, 14.281277, 13.140237,
1127 12.207677, 11.445510, 10.697049, 10.562296,
1128 10.414673, 10.182341, 9.775256, 9.172330,
1129 8.240271, 6.898587, 4.808303, 3.889751,
1130 3.345288, 3.093431, 2.897347, 2.692470,
1131 2.436222, 2.340029, 2.208579, 2.086489,
1132 1.975535, 1.876519, 1.759626, 1.705024,
1133 1.656374, 1.502638, 1.330566, 1.200697,
1134 1.101168, 1.019323, 0.943867, 0.851951,
1135 0.755229, 0.671576, 0.570675, 0.449672,
1136 0.326722, 0.244225, 0.188225, 0.149608,
1137 0.121529, 0.116289, 0.110636, 0.103490,
1138 0.096147, 0.089191, 0.079780, 0.063927,
1139 0.047642, 0.036341, 0.028250, 0.022285,
1140 0.017291, 0.016211, 0.014802, 0.013533,
1141 0.012388, 0.011352, 0.009803, 0.008537,
1142 0.007039, 0.005829, 0.004843, 0.004034,
1143 0.003101, 0.002564, 0.001956, 0.001494,
1144 0.001142, 0.000873, 0.000210, 0.000014,
1145 0.000000, 0.000000, 0.000000
1149 // dnde = (arrdndx[i-1] - arrdndx[i]) / (arre[i] - arre[i-1]);
1151 Double_t arrdnde[npts] = {
1152 10.960000, 10.960000, 10.359500, 9.811340,
1153 9.1601500, 8.206670, 6.919630, 5.655430,
1154 4.6221300, 3.777610, 3.019560, 2.591950,
1155 2.5414600, 2.712920, 3.327460, 4.928240,
1156 7.6185300, 10.966700, 12.225800, 8.094750,
1157 3.3586900, 1.553650, 1.209600, 1.263840,
1158 1.3241100, 1.312140, 1.255130, 1.165770,
1159 1.0594500, 0.945450, 0.813231, 0.699837,
1160 0.6235580, 2.260990, 2.968350, 2.240320,
1161 1.7988300, 1.553300, 1.432070, 1.535520,
1162 1.4429900, 1.247990, 1.050750, 0.829549,
1163 0.5900280, 0.395897, 0.268741, 0.185320,
1164 0.1292120, 0.103545, 0.0949525, 0.101535,
1165 0.1276380, 0.134216, 0.123816, 0.104557,
1166 0.0751843, 0.0521745, 0.0373546, 0.0275391,
1167 0.0204713, 0.0169234, 0.0154552, 0.0139194,
1168 0.0125592, 0.0113638, 0.0107354, 0.0102137,
1169 0.00845984, 0.00683338, 0.00556836, 0.00456874,
1170 0.0036227, 0.00285991, 0.00226664, 0.00172234,
1171 0.00131226, 0.00100284, 0.000465492, 7.26607e-05,
1172 3.63304e-06, 0.0000000, 0.0000000
1176 Double_t energy = x[0];
1178 for( i = 0 ; i < npts ; i++ )
1179 if( energy < arre[i] ) break;
1182 AliErrorGeneral("AliTRDv1","Given energy value is too small or zero");