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>
42 #include "AliTRDgeometry.h"
43 #include "AliTRDhit.h"
44 #include "AliTRDsim.h"
50 //_____________________________________________________________________________
51 AliTRDv1::AliTRDv1():AliTRD()
54 // Default constructor
68 fTypeOfStepManager = 2;
72 //_____________________________________________________________________________
73 AliTRDv1::AliTRDv1(const char *name, const char *title)
77 // Standard constructor for Transition Radiation Detector version 1
90 fTypeOfStepManager = 2;
92 SetBufferSize(128000);
96 //_____________________________________________________________________________
97 AliTRDv1::AliTRDv1(const AliTRDv1 &trd):AliTRD(trd)
103 ((AliTRDv1 &) trd).Copy(*this);
107 //_____________________________________________________________________________
108 AliTRDv1::~AliTRDv1()
111 // AliTRDv1 destructor
114 if (fDeltaE) delete fDeltaE;
115 if (fDeltaG) delete fDeltaG;
120 //_____________________________________________________________________________
121 AliTRDv1 &AliTRDv1::operator=(const AliTRDv1 &trd)
124 // Assignment operator
127 if (this != &trd) ((AliTRDv1 &) trd).Copy(*this);
132 //_____________________________________________________________________________
133 void AliTRDv1::Copy(TObject &trd) const
139 ((AliTRDv1 &) trd).fSensSelect = fSensSelect;
140 ((AliTRDv1 &) trd).fSensPlane = fSensPlane;
141 ((AliTRDv1 &) trd).fSensChamber = fSensChamber;
142 ((AliTRDv1 &) trd).fSensSector = fSensSector;
143 ((AliTRDv1 &) trd).fSensSectorRange = fSensSectorRange;
145 ((AliTRDv1 &) trd).fTypeOfStepManager = fTypeOfStepManager;
146 ((AliTRDv1 &) trd).fStepSize = fStepSize;
148 fDeltaE->Copy(*((AliTRDv1 &) trd).fDeltaE);
149 fDeltaG->Copy(*((AliTRDv1 &) trd).fDeltaG);
150 fTR->Copy(*((AliTRDv1 &) trd).fTR);
154 //_____________________________________________________________________________
155 void AliTRDv1::CreateGeometry()
158 // Create the GEANT geometry for the Transition Radiation Detector - Version 1
159 // This version covers the full azimuth.
162 // Check that FRAME is there otherwise we have no place where to put the TRD
163 AliModule* frame = gAlice->GetModule("FRAME");
166 // Define the chambers
167 AliTRD::CreateGeometry();
171 //_____________________________________________________________________________
172 void AliTRDv1::CreateMaterials()
175 // Create materials for the Transition Radiation Detector version 1
178 AliTRD::CreateMaterials();
182 //_____________________________________________________________________________
183 void AliTRDv1::CreateTRhit(Int_t det)
186 // Creates an electron cluster from a TR photon.
187 // The photon is assumed to be created a the end of the radiator. The
188 // distance after which it deposits its energy takes into account the
189 // absorbtion of the entrance window and of the gas mixture in drift
194 const Int_t kPdgElectron = 11;
197 const Float_t kWion = 22.04;
199 // Maximum number of TR photons per track
200 const Int_t kNTR = 50;
202 TLorentzVector mom, pos;
204 // Create TR at the entrance of the chamber
205 if (gMC->IsTrackEntering()) {
207 // Create TR only for electrons
208 Int_t iPdg = gMC->TrackPid();
209 if (TMath::Abs(iPdg) != kPdgElectron) return;
215 gMC->TrackMomentum(mom);
216 Float_t pTot = mom.Rho();
217 fTR->CreatePhotons(iPdg,pTot,nTR,eTR);
219 printf("AliTRDv1::CreateTRhit -- ");
220 printf("Boundary error: nTR = %d, kNTR = %d\n",nTR,kNTR);
224 // Loop through the TR photons
225 for (Int_t iTR = 0; iTR < nTR; iTR++) {
227 Float_t energyMeV = eTR[iTR] * 0.001;
228 Float_t energyeV = eTR[iTR] * 1000.0;
229 Float_t absLength = 0;
232 // Take the absorbtion in the entrance window into account
233 Double_t muMy = fTR->GetMuMy(energyMeV);
234 sigma = muMy * fFoilDensity;
236 absLength = gRandom->Exp(1.0/sigma);
237 if (absLength < AliTRDgeometry::MyThick()) continue;
243 // The absorbtion cross sections in the drift gas
244 // Gas-mixture (Xe/CO2)
245 Double_t muXe = fTR->GetMuXe(energyMeV);
246 Double_t muCO = fTR->GetMuCO(energyMeV);
247 sigma = (0.85 * muXe + 0.15 * muCO) * fGasDensity * fTR->GetTemp();
249 // The distance after which the energy of the TR photon
252 absLength = gRandom->Exp(1.0/sigma);
253 if (absLength > (AliTRDgeometry::DrThick()
254 + AliTRDgeometry::AmThick())) {
262 // The position of the absorbtion
264 gMC->TrackPosition(pos);
265 posHit[0] = pos[0] + mom[0] / pTot * absLength;
266 posHit[1] = pos[1] + mom[1] / pTot * absLength;
267 posHit[2] = pos[2] + mom[2] / pTot * absLength;
270 Int_t q = ((Int_t) (energyeV / kWion));
272 // Add the hit to the array. TR photon hits are marked
273 // by negative charge
274 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber(),det,posHit,-q,kTRUE);
282 //_____________________________________________________________________________
283 void AliTRDv1::Init()
286 // Initialise Transition Radiation Detector after geometry has been built.
291 if(fDebug) printf("%s: Slow simulator\n",ClassName());
294 printf(" Only plane %d is sensitive\n",fSensPlane);
295 if (fSensChamber >= 0)
296 printf(" Only chamber %d is sensitive\n",fSensChamber);
297 if (fSensSector >= 0) {
298 Int_t sens1 = fSensSector;
299 Int_t sens2 = fSensSector + fSensSectorRange;
300 sens2 -= ((Int_t) (sens2 / AliTRDgeometry::Nsect()))
301 * AliTRDgeometry::Nsect();
302 printf(" Only sectors %d - %d are sensitive\n",sens1,sens2-1);
306 printf("%s: TR simulation on\n",ClassName());
308 printf("%s: TR simulation off\n",ClassName());
311 // First ionization potential (eV) for the gas mixture (90% Xe + 10% CO2)
312 const Float_t kPoti = 12.1;
313 // Maximum energy (50 keV);
314 const Float_t kEend = 50000.0;
315 // Ermilova distribution for the delta-ray spectrum
316 Float_t poti = TMath::Log(kPoti);
317 Float_t eEnd = TMath::Log(kEend);
319 // Ermilova distribution for the delta-ray spectrum
320 fDeltaE = new TF1("deltae" ,Ermilova ,poti,eEnd,0);
322 // Geant3 distribution for the delta-ray spectrum
323 fDeltaG = new TF1("deltaeg",IntSpecGeant,poti,eEnd,0);
326 printf("%s: ",ClassName());
327 for (Int_t i = 0; i < 80; i++) printf("*");
333 //_____________________________________________________________________________
334 AliTRDsim *AliTRDv1::CreateTR()
337 // Enables the simulation of TR
340 fTR = new AliTRDsim();
345 //_____________________________________________________________________________
346 void AliTRDv1::SetSensPlane(Int_t iplane)
349 // Defines the hit-sensitive plane (0-5)
352 if ((iplane < 0) || (iplane > 5)) {
353 printf("Wrong input value: %d\n",iplane);
354 printf("Use standard setting\n");
365 //_____________________________________________________________________________
366 void AliTRDv1::SetSensChamber(Int_t ichamber)
369 // Defines the hit-sensitive chamber (0-4)
372 if ((ichamber < 0) || (ichamber > 4)) {
373 printf("Wrong input value: %d\n",ichamber);
374 printf("Use standard setting\n");
381 fSensChamber = ichamber;
385 //_____________________________________________________________________________
386 void AliTRDv1::SetSensSector(Int_t isector)
389 // Defines the hit-sensitive sector (0-17)
392 SetSensSector(isector,1);
396 //_____________________________________________________________________________
397 void AliTRDv1::SetSensSector(Int_t isector, Int_t nsector)
400 // Defines a range of hit-sensitive sectors. The range is defined by
401 // <isector> (0-17) as the starting point and <nsector> as the number
402 // of sectors to be included.
405 if ((isector < 0) || (isector > 17)) {
406 printf("Wrong input value <isector>: %d\n",isector);
407 printf("Use standard setting\n");
409 fSensSectorRange = 0;
414 if ((nsector < 1) || (nsector > 18)) {
415 printf("Wrong input value <nsector>: %d\n",nsector);
416 printf("Use standard setting\n");
418 fSensSectorRange = 0;
424 fSensSector = isector;
425 fSensSectorRange = nsector;
429 //_____________________________________________________________________________
430 void AliTRDv1::StepManager()
433 // Slow simulator. Every charged track produces electron cluster as hits
434 // along its path across the drift volume.
437 switch (fTypeOfStepManager) {
438 case 0 : StepManagerErmilova(); break; // 0 is Ermilova
439 case 1 : StepManagerGeant(); break; // 1 is Geant
440 case 2 : StepManagerFixedStep(); break; // 2 is fixed step
441 default : printf("<AliTRDv1::StepManager>: Not a valid Step Manager.\n");
446 //_____________________________________________________________________________
447 void AliTRDv1::SelectStepManager(Int_t t)
450 // Selects a step manager type:
453 // 2 - Fixed step size
457 printf("<AliTRDv1::SelectStepManager>: Sorry, Geant parametrization step"
458 "manager is not implemented yet. Please ask K.Oyama for detail.\n");
461 fTypeOfStepManager = t;
462 printf("<AliTRDv1::SelectStepManager>: Step Manager type %d was selected.\n"
463 , fTypeOfStepManager);
467 //_____________________________________________________________________________
468 void AliTRDv1::StepManagerGeant()
471 // Slow simulator. Every charged track produces electron cluster as hits
472 // along its path across the drift volume. The step size is set acording
473 // to Bethe-Bloch. The energy distribution of the delta electrons follows
474 // a spectrum taken from Geant3.
477 printf("AliTRDv1::StepManagerGeant: Not implemented yet.\n");
481 //_____________________________________________________________________________
482 void AliTRDv1::StepManagerErmilova()
485 // Slow simulator. Every charged track produces electron cluster as hits
486 // along its path across the drift volume. The step size is set acording
487 // to Bethe-Bloch. The energy distribution of the delta electrons follows
488 // a spectrum taken from Ermilova et al.
505 Double_t betaGamma, pp;
508 Bool_t drRegion = kFALSE;
509 Bool_t amRegion = kFALSE;
512 TString cIdSensDr = "J";
513 TString cIdSensAm = "K";
514 Char_t cIdChamber[3];
517 TLorentzVector pos, mom;
519 const Int_t kNplan = AliTRDgeometry::Nplan();
520 const Int_t kNcham = AliTRDgeometry::Ncham();
521 const Int_t kNdetsec = kNplan * kNcham;
523 const Double_t kBig = 1.0E+12; // Infinitely big
524 const Float_t kWion = 22.04; // Ionization energy
525 const Float_t kPTotMaxEl = 0.002; // Maximum momentum for e+ e- g
527 // Minimum energy for the step size adjustment
528 const Float_t kEkinMinStep = 1.0e-5;
530 // Plateau value of the energy-loss for electron in xenon
531 // taken from: Allison + Comb, Ann. Rev. Nucl. Sci. (1980), 30, 253
532 //const Double_t kPlateau = 1.70;
533 // the averaged value (26/3/99)
534 const Float_t kPlateau = 1.55;
536 const Float_t kPrim = 48.0; // dN1/dx|min for the gas mixture (90% Xe + 10% CO2)
537 // First ionization potential (eV) for the gas mixture (90% Xe + 10% CO2)
538 const Float_t kPoti = 12.1;
540 const Int_t kPdgElectron = 11; // PDG code electron
542 // Set the maximum step size to a very large number for all
543 // neutral particles and those outside the driftvolume
544 gMC->SetMaxStep(kBig);
546 // Use only charged tracks
547 if (( gMC->TrackCharge() ) &&
548 (!gMC->IsTrackStop() ) &&
549 (!gMC->IsTrackDisappeared())) {
551 // Inside a sensitive volume?
554 cIdCurrent = gMC->CurrentVolName();
555 if (cIdSensDr == cIdCurrent[1]) {
558 if (cIdSensAm == cIdCurrent[1]) {
561 if (drRegion || amRegion) {
563 // The hit coordinates and charge
564 gMC->TrackPosition(pos);
569 // The sector number (0 - 17)
570 // The numbering goes clockwise and starts at y = 0
571 Float_t phi = kRaddeg*TMath::ATan2(pos[0],pos[1]);
576 sec = ((Int_t) (phi / 20));
578 // The plane and chamber number
579 cIdChamber[0] = cIdCurrent[2];
580 cIdChamber[1] = cIdCurrent[3];
581 Int_t idChamber = (atoi(cIdChamber) % kNdetsec);
582 cha = kNcham - ((Int_t) idChamber / kNplan) - 1;
583 pla = ((Int_t) idChamber % kNplan);
585 // Check on selected volumes
586 Int_t addthishit = 1;
588 if ((fSensPlane >= 0) && (pla != fSensPlane )) addthishit = 0;
589 if ((fSensChamber >= 0) && (cha != fSensChamber)) addthishit = 0;
590 if (fSensSector >= 0) {
591 Int_t sens1 = fSensSector;
592 Int_t sens2 = fSensSector + fSensSectorRange;
593 sens2 -= ((Int_t) (sens2 / AliTRDgeometry::Nsect()))
594 * AliTRDgeometry::Nsect();
596 if ((sec < sens1) || (sec >= sens2)) addthishit = 0;
599 if ((sec < sens1) && (sec >= sens2)) addthishit = 0;
607 // The detector number
608 det = fGeometry->GetDetector(pla,cha,sec);
610 // Special hits only in the drift region
613 // Create a track reference at the entrance and
614 // exit of each chamber that contain the
615 // momentum components of the particle
616 if (gMC->IsTrackEntering() || gMC->IsTrackExiting()) {
617 gMC->TrackMomentum(mom);
618 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
621 // Create the hits from TR photons
622 if (fTR) CreateTRhit(det);
626 // Calculate the energy of the delta-electrons
627 eDelta = TMath::Exp(fDeltaE->GetRandom()) - kPoti;
628 eDelta = TMath::Max(eDelta,0.0);
630 // The number of secondary electrons created
631 qTot = ((Int_t) (eDelta / kWion) + 1);
633 // Create a new dEdx hit
635 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
636 ,det,hits,qTot,kTRUE);
639 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
640 ,det,hits,qTot,kFALSE);
643 // Calculate the maximum step size for the next tracking step
644 // Produce only one hit if Ekin is below cutoff
645 aMass = gMC->TrackMass();
646 if ((gMC->Etot() - aMass) > kEkinMinStep) {
648 // The energy loss according to Bethe Bloch
649 iPdg = TMath::Abs(gMC->TrackPid());
650 if ( (iPdg != kPdgElectron) ||
651 ((iPdg == kPdgElectron) && (pTot < kPTotMaxEl))) {
652 gMC->TrackMomentum(mom);
654 betaGamma = pTot / aMass;
655 pp = kPrim * BetheBloch(betaGamma);
656 // Take charge > 1 into account
657 charge = gMC->TrackCharge();
658 if (TMath::Abs(charge) > 1) pp = pp * charge*charge;
660 // Electrons above 20 Mev/c are at the plateau
662 pp = kPrim * kPlateau;
667 gMC->GetRandom()->RndmArray(1, random);
668 while ((random[0] == 1.) || (random[0] == 0.));
669 stepSize = - TMath::Log(random[0]) / pp;
670 gMC->SetMaxStep(stepSize);
683 //_____________________________________________________________________________
684 void AliTRDv1::StepManagerFixedStep()
687 // Slow simulator. Every charged track produces electron cluster as hits
688 // along its path across the drift volume. The step size is fixed in
689 // this version of the step manager.
701 Bool_t drRegion = kFALSE;
702 Bool_t amRegion = kFALSE;
705 TString cIdSensDr = "J";
706 TString cIdSensAm = "K";
707 Char_t cIdChamber[3];
710 TLorentzVector pos, mom;
712 const Int_t kNplan = AliTRDgeometry::Nplan();
713 const Int_t kNcham = AliTRDgeometry::Ncham();
714 const Int_t kNdetsec = kNplan * kNcham;
716 const Double_t kBig = 1.0E+12;
718 const Float_t kWion = 22.04; // Ionization energy
719 const Float_t kEkinMinStep = 1.0e-5; // Minimum energy for the step size adjustment
721 // Set the maximum step size to a very large number for all
722 // neutral particles and those outside the driftvolume
723 gMC->SetMaxStep(kBig);
725 // If not charged track or already stopped or disappeared, just return.
726 if ((!gMC->TrackCharge()) ||
727 gMC->IsTrackStop() ||
728 gMC->IsTrackDisappeared()) return;
730 // Inside a sensitive volume?
731 cIdCurrent = gMC->CurrentVolName();
733 if (cIdSensDr == cIdCurrent[1]) drRegion = kTRUE;
734 if (cIdSensAm == cIdCurrent[1]) amRegion = kTRUE;
736 if ((!drRegion) && (!amRegion)) return;
738 // The hit coordinates and charge
739 gMC->TrackPosition(pos);
744 // The sector number (0 - 17)
745 // The numbering goes clockwise and starts at y = 0
746 Float_t phi = kRaddeg*TMath::ATan2(pos[0],pos[1]);
747 if (phi < 90.) phi += 270.;
749 sec = ((Int_t) (phi / 20.));
751 // The plane and chamber number
752 cIdChamber[0] = cIdCurrent[2];
753 cIdChamber[1] = cIdCurrent[3];
754 Int_t idChamber = (atoi(cIdChamber) % kNdetsec);
755 cha = kNcham - ((Int_t) idChamber / kNplan) - 1;
756 pla = ((Int_t) idChamber % kNplan);
758 // Check on selected volumes
759 Int_t addthishit = 1;
761 if ((fSensPlane >= 0) && (pla != fSensPlane )) addthishit = 0;
762 if ((fSensChamber >= 0) && (cha != fSensChamber)) addthishit = 0;
763 if (fSensSector >= 0) {
764 Int_t sens1 = fSensSector;
765 Int_t sens2 = fSensSector + fSensSectorRange;
766 sens2 -= ((Int_t) (sens2 / AliTRDgeometry::Nsect())) * AliTRDgeometry::Nsect();
768 if ((sec < sens1) || (sec >= sens2)) addthishit = 0;
771 if ((sec < sens1) && (sec >= sens2)) addthishit = 0;
776 if (!addthishit) return;
778 det = fGeometry->GetDetector(pla,cha,sec); // The detector number
780 Int_t trkStat = 0; // 0: InFlight 1:Entering 2:Exiting
782 // Special hits only in the drift region
785 // Create a track reference at the entrance and exit of each
786 // chamber that contain the momentum components of the particle
788 if (gMC->IsTrackEntering()) {
789 gMC->TrackMomentum(mom);
790 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
793 if (gMC->IsTrackExiting()) {
794 gMC->TrackMomentum(mom);
795 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
799 // Create the hits from TR photons
800 if (fTR) CreateTRhit(det);
804 // Calculate the charge according to GEANT Edep
805 // Create a new dEdx hit
806 eDep = TMath::Max(gMC->Edep(),0.0) * 1.0e+09;
807 qTot = (Int_t) (eDep / kWion);
808 AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber(),det,hits,qTot,drRegion);
810 // Set Maximum Step Size
811 // Produce only one hit if Ekin is below cutoff
812 if ((gMC->Etot() - gMC->TrackMass()) < kEkinMinStep) return;
813 gMC->SetMaxStep(fStepSize);
817 //_____________________________________________________________________________
818 Double_t AliTRDv1::BetheBloch(Double_t bg)
821 // Parametrization of the Bethe-Bloch-curve
822 // The parametrization is the same as for the TPC and is taken from Lehrhaus.
825 // This parameters have been adjusted to averaged values from GEANT
826 const Double_t kP1 = 7.17960e-02;
827 const Double_t kP2 = 8.54196;
828 const Double_t kP3 = 1.38065e-06;
829 const Double_t kP4 = 5.30972;
830 const Double_t kP5 = 2.83798;
832 // This parameters have been adjusted to Xe-data found in:
833 // Allison & Cobb, Ann. Rev. Nucl. Sci. (1980), 30, 253
834 //const Double_t kP1 = 0.76176E-1;
835 //const Double_t kP2 = 10.632;
836 //const Double_t kP3 = 3.17983E-6;
837 //const Double_t kP4 = 1.8631;
838 //const Double_t kP5 = 1.9479;
840 // Lower cutoff of the Bethe-Bloch-curve to limit step sizes
841 const Double_t kBgMin = 0.8;
842 const Double_t kBBMax = 6.83298;
843 //const Double_t kBgMin = 0.6;
844 //const Double_t kBBMax = 17.2809;
845 //const Double_t kBgMin = 0.4;
846 //const Double_t kBBMax = 82.0;
849 Double_t yy = bg / TMath::Sqrt(1. + bg*bg);
850 Double_t aa = TMath::Power(yy,kP4);
851 Double_t bb = TMath::Power((1./bg),kP5);
852 bb = TMath::Log(kP3 + bb);
853 return ((kP2 - aa - bb)*kP1 / aa);
861 //_____________________________________________________________________________
862 Double_t BetheBlochGeant(Double_t bg)
865 // Return dN/dx (number of primary collisions per centimeter)
866 // for given beta*gamma factor.
868 // Implemented by K.Oyama according to GEANT 3 parametrization shown in
869 // A.Andronic's webpage: http://www-alice.gsi.de/trd/papers/dedx/dedx.html
870 // This must be used as a set with IntSpecGeant.
873 Double_t arr_g[20] = {
874 1.100000, 1.200000, 1.300000, 1.500000,
875 1.800000, 2.000000, 2.500000, 3.000000,
876 4.000000, 7.000000, 10.000000, 20.000000,
877 40.000000, 70.000000, 100.000000, 300.000000,
878 600.000000, 1000.000000, 3000.000000, 10000.000000 };
880 Double_t arr_nc[20] = {
881 75.009056, 45.508083, 35.299252, 27.116327,
882 22.734999, 21.411915, 19.934095, 19.449375,
883 19.344431, 20.185553, 21.027925, 22.912676,
884 24.933352, 26.504053, 27.387468, 29.566597,
885 30.353779, 30.787134, 31.129285, 31.157350 };
887 // betagamma to gamma
888 Double_t g = TMath::Sqrt( 1. + bg*bg );
890 // Find the index just before the point we need.
892 for( i = 0 ; i < 18 ; i++ )
893 if( arr_g[i] < g && arr_g[i+1] > g )
896 // Simple interpolation.
897 Double_t pp = ((arr_nc[i+1] - arr_nc[i]) /
898 (arr_g[i+1]-arr_g[i])) * (g-arr_g[i]) + arr_nc[i];
904 //_____________________________________________________________________________
905 Double_t Ermilova(Double_t *x, Double_t *)
908 // Calculates the delta-ray energy distribution according to Ermilova.
909 // Logarithmic scale !
918 const Int_t kNv = 31;
920 Float_t vxe[kNv] = { 2.3026, 2.9957, 3.4012, 3.6889, 3.9120
921 , 4.0943, 4.2485, 4.3820, 4.4998, 4.6052
922 , 4.7005, 5.0752, 5.2983, 5.7038, 5.9915
923 , 6.2146, 6.5221, 6.9078, 7.3132, 7.6009
924 , 8.0064, 8.5172, 8.6995, 8.9872, 9.2103
925 , 9.4727, 9.9035,10.3735,10.5966,10.8198
928 Float_t vye[kNv] = { 80.0 , 31.0 , 23.3 , 21.1 , 21.0
929 , 20.9 , 20.8 , 20.0 , 16.0 , 11.0
930 , 8.0 , 6.0 , 5.2 , 4.6 , 4.0
931 , 3.5 , 3.0 , 1.4 , 0.67 , 0.44
932 , 0.3 , 0.18 , 0.12 , 0.08 , 0.056
933 , 0.04 , 0.023, 0.015, 0.011, 0.01
942 dpos = energy - vxe[pos2++];
946 if (pos2 > kNv) pos2 = kNv - 1;
949 // Differentiate between the sampling points
950 dnde = (vye[pos1] - vye[pos2]) / (vxe[pos2] - vxe[pos1]);
956 //_____________________________________________________________________________
957 Double_t IntSpecGeant(Double_t *x, Double_t *)
960 // Integrated spectrum from Geant3
963 const Int_t n_pts = 83;
964 Double_t arr_e[n_pts] = {
965 2.421257, 2.483278, 2.534301, 2.592230,
966 2.672067, 2.813299, 3.015059, 3.216819,
967 3.418579, 3.620338, 3.868209, 3.920198,
968 3.978284, 4.063923, 4.186264, 4.308605,
969 4.430946, 4.553288, 4.724261, 4.837736,
970 4.999842, 5.161949, 5.324056, 5.486163,
971 5.679688, 5.752998, 5.857728, 5.962457,
972 6.067185, 6.171914, 6.315653, 6.393674,
973 6.471694, 6.539689, 6.597658, 6.655627,
974 6.710957, 6.763648, 6.816338, 6.876198,
975 6.943227, 7.010257, 7.106285, 7.252151,
976 7.460531, 7.668911, 7.877290, 8.085670,
977 8.302979, 8.353585, 8.413120, 8.483500,
978 8.541030, 8.592857, 8.668865, 8.820485,
979 9.037086, 9.253686, 9.470286, 9.686887,
980 9.930838, 9.994655, 10.085822, 10.176990,
981 10.268158, 10.359325, 10.503614, 10.627565,
982 10.804637, 10.981709, 11.158781, 11.335854,
983 11.593397, 11.781165, 12.049404, 12.317644,
984 12.585884, 12.854123, 14.278421, 16.975889,
985 20.829416, 24.682943, 28.536469
987 Double_t arr_dndx[n_pts] = {
988 19.344431, 18.664679, 18.136106, 17.567745,
989 16.836426, 15.677382, 14.281277, 13.140237,
990 12.207677, 11.445510, 10.697049, 10.562296,
991 10.414673, 10.182341, 9.775256, 9.172330,
992 8.240271, 6.898587, 4.808303, 3.889751,
993 3.345288, 3.093431, 2.897347, 2.692470,
994 2.436222, 2.340029, 2.208579, 2.086489,
995 1.975535, 1.876519, 1.759626, 1.705024,
996 1.656374, 1.502638, 1.330566, 1.200697,
997 1.101168, 1.019323, 0.943867, 0.851951,
998 0.755229, 0.671576, 0.570675, 0.449672,
999 0.326722, 0.244225, 0.188225, 0.149608,
1000 0.121529, 0.116289, 0.110636, 0.103490,
1001 0.096147, 0.089191, 0.079780, 0.063927,
1002 0.047642, 0.036341, 0.028250, 0.022285,
1003 0.017291, 0.016211, 0.014802, 0.013533,
1004 0.012388, 0.011352, 0.009803, 0.008537,
1005 0.007039, 0.005829, 0.004843, 0.004034,
1006 0.003101, 0.002564, 0.001956, 0.001494,
1007 0.001142, 0.000873, 0.000210, 0.000014,
1008 0.000000, 0.000000, 0.000000
1012 Double_t energy = x[0];
1015 for( i = 0 ; i < n_pts ; i++ )
1016 if( energy < arr_e[i] ) break;
1019 printf("Error in AliTRDv1::IntSpecGeant: "
1020 "given energy value is too small or zero.\n");
1023 dnde = (arr_dndx[i-1] - arr_dndx[i]) / (arr_e[i] - arr_e[i-1]);