CbmRoot
Loading...
Searching...
No Matches
CbmTrdRadiator.cxx
Go to the documentation of this file.
1/* Copyright (C) 2004-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Matus Kalisky [committer], Cyrano Bergmann, Adrian Meyer-Ahrens, David Emschermann, Florian Uhlig */
4
5// ------------------------------------------------------------------------
6// ----- CbmTrdRadiator source file -----
7// ----- Created 10/11/04 by M.Kalisky -----
8// ------------------------------------------------------------------------
9#include "CbmTrdRadiator.h"
10
11#include "CbmTrdGas.h" // for CbmTrdGas
12#include "CbmTrdPoint.h" // for CbmTrdPoint
13
14#include <Logger.h> // for Logger, LOG
15
16#include <TDirectory.h> // for TDirectory
17#include <TFile.h> // for TFile, gFile
18#include <TGeoManager.h> // for TGeoManager, gGeoManager
19#include <TH1.h> // for TH1D
20#include <TMath.h> // for Exp, Sqrt, Cos, Pi
21#include <TMathBase.h> // for Abs
22#include <TObjString.h> // for TObjString
23#include <TRandom.h> // for TRandom
24#include <TRandom3.h> // for gRandom
25#include <TVector3.h> // for TVector3
26
27#include <iomanip> // for setprecision, __iom_t5
28
29#include <stdio.h> // for printf, sprintf
30#include <stdlib.h> // for exit
31
32using std::setprecision;
33
34// ----- Default constructor ------------------------------------------------
35CbmTrdRadiator::CbmTrdRadiator(Bool_t SimpleTR, Int_t Nfoils, Float_t FoilThick, Float_t GapThick, TString material,
36 TString window) // If "Kapton" is set, 0.05 mu aluminum will be added
37 : fWindowFoil(window)
38 , fRadType("")
39 , fDetType(-1)
40 , fFirstPass(kTRUE)
41 , fSimpleTR(SimpleTR)
42 , fNFoils(Nfoils)
43 , fFoilThick(FoilThick)
44 , fGapThick(GapThick)
45 , fFoilMaterial(material)
46 , fGasThick(-1)
47 , fFoilDens(-1.)
48 , fGapDens(-1.)
49 , fFoilOmega(-1.)
50 , fGapOmega(-1.)
51 , fnPhotonCorr(0.65)
52 , fFoilThickCorr(1.)
53 , fGapThickCorr(1.)
54 , fGasThickCorr(1.)
55 , fnTRprod(-1)
56 , fWinDens(-1.)
57 , fWinThick(-1.)
58 , WINDOW()
59 , fCom1(-1.)
60 , fCom2(-1.)
61 , fSpBinWidth((Float_t) fSpRange / (Float_t) fSpNBins)
62 , fSigma(nullptr)
63 , fSigmaWin(nullptr)
64 , fSigmaDet(nullptr)
65 , fSpectrum(nullptr)
66 , fWinSpectrum(nullptr)
67 , fDetSpectrumA(nullptr)
68 , fDetSpectrum(nullptr)
69 , fTrackMomentum(nullptr)
70 , fFinal()
71 , fnTRabs()
72 , fnTRab(-1.)
73 , fELoss(-1.)
74 , fMom(-1., -1., -1.)
75{
76 for (Int_t i = 0; i < fNMom; i++) {
77 fFinal[i] = nullptr;
78 }
79}
80//-----------------------------------------------------------------------------
81
82// ----- Constructor using predefined radiator prototype------------------------------------
83CbmTrdRadiator::CbmTrdRadiator(Bool_t SimpleTR, TString prototype,
84 TString window) // If "Kapton" is set, 0.05 mu aluminum will be added
85 : fWindowFoil(window)
86 , fRadType(prototype)
87 , fDetType(-1)
88 , fFirstPass(kTRUE)
89 , fSimpleTR(SimpleTR)
90 , fNFoils(337)
91 , fFoilThick(0.0012)
92 , fGapThick(0.09)
93 , fFoilMaterial("")
94 , fGasThick(-1)
95 , fFoilDens(-1.)
96 , fGapDens(-1.)
97 , fFoilOmega(-1.)
98 , fGapOmega(-1.)
99 , fnPhotonCorr(0.65)
100 , fFoilThickCorr(1.)
101 , fGapThickCorr(1.)
102 , fGasThickCorr(1.)
103 , fnTRprod(-1)
104 , fWinDens(-1.)
105 , fWinThick(-1.)
106 , WINDOW()
107 , fCom1(-1.)
108 , fCom2(-1.)
109 , fSpBinWidth((Float_t) fSpRange / (Float_t) fSpNBins)
110 , fSigma(nullptr)
111 , fSigmaWin(nullptr)
112 , fSigmaDet(nullptr)
113 , fSpectrum(nullptr)
114 , fWinSpectrum(nullptr)
115 , fDetSpectrumA(nullptr)
116 , fDetSpectrum(nullptr)
117 , fTrackMomentum(nullptr)
118 , fFinal()
119 , fnTRabs()
120 , fnTRab(-1.)
121 , fELoss(-1.)
122 , fMom(-1., -1., -1.)
123{
124 for (Int_t i = 0; i < fNMom; i++) {
125 fFinal[i] = nullptr;
126 }
127}
128//-----------------------------------------------------------------------------
129
130// ----- Destructor ----------------------------------------------------
132{
133 // FairRootManager *fManager = FairRootManager::Instance();
134 // fManager->Write();
135 if (fSpectrum) {
136 LOG(info) << " -I DELETING fSpectrum ";
137 delete fSpectrum;
138 }
139 if (fWinSpectrum) delete fWinSpectrum;
140 if (fDetSpectrum) delete fDetSpectrum;
141 if (fDetSpectrumA) delete fDetSpectrumA;
142
143 for (Int_t i = 0; i < fNMom; i++) {
144 if (fFinal[i]) delete fFinal[i];
145 }
146}
147
148// ----- Create Histogramms --------------------------------------------------
150{
151
152 // Create the needed histograms
153
154 fSpBinWidth = (Float_t) fSpRange / (Float_t) fSpNBins;
155
156 Float_t SpLower = 1.0 - 0.5 * fSpBinWidth;
157 Float_t SpUpper = SpLower + (Float_t) fSpRange;
158
159 size_t buf_size = 50;
160 Char_t name[buf_size];
161
162 if (fSpectrum) delete fSpectrum;
163 fSpectrum = new TH1D("fSpectrum", "TR spectrum", fSpNBins, SpLower, SpUpper);
164
165 if (fWinSpectrum) delete fWinSpectrum;
166 fWinSpectrum = new TH1D("fWinSpectrum", "TR spectrum in Mylar", fSpNBins, SpLower, SpUpper);
167
168 if (fDetSpectrum) delete fDetSpectrum;
169 fDetSpectrum = new TH1D("fDetSpectrum", "TR spectrum escaped from detector", fSpNBins, SpLower, SpUpper);
170
171 if (fDetSpectrumA) delete fDetSpectrumA;
172 fDetSpectrumA = new TH1D("fDetSpectrumA", "TR spectrum absorbed in detector", fSpNBins, SpLower, SpUpper);
173
174 for (Int_t i = 0; i < fNMom; i++) {
175 snprintf(name, buf_size - 1, "fFinal%d", i + 1);
176 //LOG(info) <<"name : "<<name;
177 if (fFinal[i]) delete fFinal[i];
178 fFinal[i] = new TH1D(name, name, fSpNBins, SpLower, SpUpper);
179 }
180}
181
182
183// ----- Init function ----------------------------------------------------
185{
186 LOG(info) << "================CbmTrdRadiator===============";
188
189 //Check if a radiator type has been set
190 if (fRadType == "") {
191 //Set fnPhotonCorr also if no prototype has been specified
192 fnPhotonCorr = 0.65;
193 //Check specified radiator types
194 }
195 else if (fRadType == "tdr18") { //Default TDR18 radiator 30cm Box + 1.5 cm in carbon grid
196 fFoilMaterial = "pefoam20";
197 fNFoils = 337;
198 fGapThick = 900 * 0.0001;
199 fFoilThick = 12 * 0.0001;
200 fnPhotonCorr = 0.65;
201 }
202 else if (fRadType == "B++" || fRadType == "K++") {
203 fFoilMaterial = "pokalon";
204 fNFoils = 350;
205 fGapThick = 0.07;
206 fFoilThick = 0.0024;
207 fnPhotonCorr = 0.65;
208 }
209 else if (fRadType == "G30") {
210 fFoilMaterial = "pefiber";
211 fNFoils = 1791;
212 fGapThick = 50 * 0.0001;
213 fFoilThick = 17 * 0.0001;
214 fnPhotonCorr = 0.65;
215 }
216 else { // If radiator typ is neither empty nor one of the above (because of typo or else) set defaults
217
218 LOG(warn) << "CbmTrdRadiator::Init : *********** Radiator prototype not known ***********";
219 LOG(warn) << "CbmTrdRadiator::Init : switch to default parameters ";
220 fFoilMaterial = "pefoam20";
221 fNFoils = 337;
222 fGapThick = 900 * 0.0001;
223 fFoilThick = 12 * 0.0001;
224 fnPhotonCorr = 0.65;
225 }
226
227
228 //Material has been specified now, either in the constructor or set by radiator type above. Now, go through materials and set properties accordingly
229
230
231 // material dependent parameters for the gas between the foils of the radiator
232 //Properties of the air gaps between foils
233 fGapDens = 0.001205; // [g/cm3]
234 fGapOmega = 0.7; //plasma frequency ( from Anton )
235 //material = fFoilMaterial;
236 if (fFoilMaterial == "pefoam20") {
237 // (polyethylen foam foil)
238 fFoilDens = 0.90; // [g/cm3 ]
239 fFoilOmega = 20.64; //plasma frequency ( from Cyrano )
240 }
241 else if (fFoilMaterial == "polyethylen") {
242 // (polyethylen)
243 fFoilDens = 0.92; // [g/cm3 ]
244 fFoilOmega = 20.9; //plasma frequency ( from Anton )
245 }
246 else if (fFoilMaterial == "pefiber") {
247 // (polyethylen)
248 fFoilDens = 0.90; // [g/cm3 ]
249 fFoilOmega = 20.64; //plasma frequency ( from Cyrano )
250 }
251 else if (fFoilMaterial == "mylar") {
252 // (Mylar)
253 fFoilDens = 1.393; // [g/cm3 ]
254 fFoilOmega = 24.53; //plasma frequency ( from Cyrano )
255 }
256 else if (fFoilMaterial == "pokalon") {
257 // (PokalonN470)
258 fFoilDens = 1.150; // [g/cm3 ]
259 fFoilOmega = 22.43; //plasma frequency ( from Cyrano )
260 }
261 else { // If material is empty or one of the above (because of typo or else) set default
262 LOG(warn) << "CbmTrdRadiator::Init : *********** Radiator material not known ***********";
263 LOG(warn) << "CbmTrdRadiator::Init : switch to default material ";
264 // (polyethylen foam foil)
265 fFoilMaterial = "pefoam20";
266 fFoilDens = 0.90; // [g/cm3 ]
267 fFoilOmega = 20.64; //plasma frequency ( from Cyrano )
268 }
269
270 // foil between radiator and gas chamber
271 if (fWindowFoil == "Kapton") { // 0.05 mu Aluminum is added in SigmaWin() for Kapton
272 fWinDens = 1.42; //[g/cm3] ?? define values ?? default mylar
273 fWinThick = 0.0025; // [cm] ?? define values ?? default mylar
274 }
275 else if (fWindowFoil != "Mylar") {
276 if (!WINDOW.Init(fWindowFoil)) fWindowFoil = "Mylar";
277 }
278 if (fWindowFoil == "Mylar") {
279 fWinDens = 1.39; //[g/cm3]
280 fWinThick = 0.0100; //[cm]
281 }
282 if (!WINDOW.fN) {
283 LOG(info) << "CbmTrdRadiator::Init : Window type : " << fWindowFoil;
284 LOG(info) << "CbmTrdRadiator::Init : Window density : " << fWinDens << " g/cm^3";
285 LOG(info) << "CbmTrdRadiator::Init : Window thickness : " << fWinThick << " cm";
286 }
287
288
289 LOG(info) << "CbmTrdRadiator::Init : Prototype : " << fRadType;
290 LOG(info) << "CbmTrdRadiator::Init : Scaling factor : " << fnPhotonCorr;
291 LOG(info) << "CbmTrdRadiator::Init : Foil material : " << fFoilMaterial;
292 LOG(info) << "CbmTrdRadiator::Init : Nr. of foils : " << fNFoils;
293 LOG(info) << "CbmTrdRadiator::Init : Foil thickness : " << setprecision(4) << fFoilThick << " cm";
294 LOG(info) << "CbmTrdRadiator::Init : Gap thickness : " << fGapThick << " cm";
295 LOG(info) << "CbmTrdRadiator::Init : Simple TR production: " << setprecision(2) << fSimpleTR;
296 LOG(info) << "CbmTrdRadiator::Init : Foil plasm. frequ. : " << fFoilOmega << " keV";
297 LOG(info) << "CbmTrdRadiator::Init : Gap plasm. frequ. : " << fGapOmega << " keV";
298
299
300 // Get all the gas properties from CbmTrdGas
301 CbmTrdGas* fTrdGas = CbmTrdGas::Instance();
302 if (fTrdGas == 0) {
303 fTrdGas = new CbmTrdGas();
304 fTrdGas->Init();
305 }
306
307 fCom2 = fTrdGas->GetNobleGas();
308 fCom1 = fTrdGas->GetCO2();
309 fDetType = fTrdGas->GetDetType();
310 fGasThick = fTrdGas->GetGasThick();
311
312 LOG(info) << "CbmTrdRadiator::Init : Detector noble gas : " << fTrdGas->GetNobleGas();
313 LOG(info) << "CbmTrdRadiator::Init : Detector quenching gas: " << fTrdGas->GetCO2();
314 LOG(info) << "CbmTrdRadiator::Init : Detector type : " << fTrdGas->GetDetType();
315 LOG(info) << "CbmTrdRadiator::Init : Detector gas thick. : " << fTrdGas->GetGasThick() << " cm";
316
317 //LOG(info) << "************* End of Trd Radiator Init **************";
318 // If simplified version is used one didn't calculate the TR
319 // for each CbmTrdPoint in full glory, but create at startup
320 // some histograms for several momenta which are later used to
321 // get the TR much faster.
322 if (fSimpleTR == kTRUE) {
323
325
326 TFile* oldFile = gFile;
327 TDirectory* oldDir = gDirectory;
328
329 TFile* f1 = new TFile("TRhistos.root", "recreate");
330
331 for (Int_t i = 0; i < fNMom; i++) {
332 fFinal[i]->Write();
333 }
334 f1->Close();
335 f1->Delete();
336
337 gFile = oldFile;
338 gDirectory = oldDir;
339 }
340}
341
342//----------------------------------------------------------------------------
344{
345 memset(fThick, 0, NCOMPONENTS * sizeof(Float_t));
346 memset(fDens, 0, NCOMPONENTS * sizeof(Float_t));
347 memset(GetMu, 0, NCOMPONENTS * sizeof(GetMuPtr));
348 Init(def);
349}
350
351//----------------------------------------------------------------------------
353{
354 TObjArray* mats = def.Tokenize(";");
355 for (fN = 0; fN < mats->GetEntriesFast(); fN++) {
356 TObjString* mat = (TObjString*) (*mats)[fN];
357 TString mname = mat->String();
358 if (mname.CompareTo("Al") == 0) {
359 fMat[fN] = "Al";
360 fDens[fN] = 2.7;
361 GetMu[fN] = CbmTrdRadiator::GetMuAl;
362 }
363 else if (mname.CompareTo("C") == 0) {
364 fMat[fN] = "C";
365 fDens[fN] = 2.267;
366 GetMu[fN] = CbmTrdRadiator::GetMuC;
367 }
368 else if (mname.CompareTo("HC") == 0) {
369 fMat[fN] = "HC";
370 fDens[fN] = 4.8e-2; // 48 Kg/m^3
371 GetMu[fN] = CbmTrdRadiator::GetMuAir;
372 }
373 else if (mname.CompareTo("Po") == 0) {
374 fMat[fN] = "Po";
375 fDens[fN] = 0.92;
376 GetMu[fN] = CbmTrdRadiator::GetMuPo;
377 }
378 else if (mname.CompareTo("Pok") == 0) {
379 fMat[fN] = "Pok";
380 fDens[fN] = 1.150;
381 GetMu[fN] = CbmTrdRadiator::GetMuPok;
382 }
383 else if (mname.CompareTo("Ka") == 0) {
384 fMat[fN] = "Ka";
385 fDens[fN] = 1.39;
386 GetMu[fN] = CbmTrdRadiator::GetMuKa;
387 }
388 else if (mname.CompareTo("Air") == 0) {
389 fMat[fN] = "Air";
390 fDens[fN] = 1.205e-3;
391 GetMu[fN] = CbmTrdRadiator::GetMuAir;
392 }
393 else if (mname.CompareTo("Xe") == 0) {
394 fMat[fN] = "Xe";
395 fDens[fN] = 5.9e-3;
396 GetMu[fN] = CbmTrdRadiator::GetMuXe;
397 }
398 else if (mname.CompareTo("CO2") == 0) {
399 fMat[fN] = "CO2";
400 fDens[fN] = 1.9767e-3;
401 GetMu[fN] = CbmTrdRadiator::GetMuCO2;
402 }
403 else if (mname.CompareTo("My") == 0) {
404 fMat[fN] = "My";
405 fDens[fN] = 1.393;
406 GetMu[fN] = CbmTrdRadiator::GetMuMy;
407 }
408 else {
409 LOG(warn) << "CbmTrdEntranceWindow::Init : material " << mname.Data() << " not in the DB. Can't create "
410 << def.Data() << " entrance window structure. Default to Mylar.";
411 fN = 0;
412 return kFALSE;
413 }
414 LOG(info) << "CbmTrdEntranceWindow::Init : C" << fN << " type : " << fMat[fN];
415 LOG(info) << "CbmTrdEntranceWindow::Init : density : " << fDens[fN] << " g/cm^3";
416 LOG(info) << "CbmTrdEntranceWindow::Init : thickness : " << fThick[fN] << " cm";
417 }
418 mats->Delete();
419 delete mats;
420 return kTRUE;
421}
422
423//----------------------------------------------------------------------------
424void CbmTrdRadiator::SetEWwidths(Int_t n, Float_t* w)
425{
426 if (n > NCOMPONENTS) {
427 LOG(warn) << "CbmTrdEntranceWindow : can support only up to " << NCOMPONENTS
428 << " plane-parallel elements. Please check your simulations";
429 n = NCOMPONENTS;
430 }
431 memcpy(WINDOW.fThick, w, n * sizeof(Float_t));
432}
433
434//---- Lattice Hit------------------------------------------------------------
436{
437 //printf("---------------------------------------------------\n");
438 Double_t point_in[3];
439 Double_t point_out[3];
440 if (nullptr != point) {
441 point_in[0] = point->GetXIn();
442 point_in[1] = point->GetYIn();
443 point_in[2] = point->GetZIn();
444
445 point_out[0] = point->GetXOut();
446 point_out[1] = point->GetYOut();
447 point_out[2] = point->GetZOut();
448 Double_t back_direction[3] = {(point_in[0] - point_out[0]), (point_in[1] - point_out[1]),
449 (point_in[2] - point_out[2])};
450 if (back_direction[2] > 0) {
451 LOG(debug2) << "CbmTrdRadiator::LatticeHit: MC-track points towards target!";
452 //for(Int_t i = 0; i < 3; i++)
453 //printf("%i: in:%8.2f out:%8.2f direction:%8.2f\n",i,point_in[i],point_out[i],back_direction[i]);
454 return false;
455 }
456 Double_t trackLength = TMath::Sqrt(back_direction[0] * back_direction[0] + back_direction[1] * back_direction[1]
457 + back_direction[2] * back_direction[2]);
458
459 trackLength *= 10.; // cm -> mm to get a step width of 1mm
460 //printf("track length:%7.2fmm\n",trackLength);
461 gGeoManager->FindNode((point_out[0] + point_in[0]) / 2, (point_out[1] + point_in[1]) / 2,
462 (point_out[2] + point_in[2]) / 2);
463
464 Double_t pos[3] = {point_in[0], point_in[1], point_in[2]}; // start at entrance point
465
466 for (Int_t i = 0; i < 3; i++) {
467 back_direction[i] /= trackLength;
468 //printf("%i: in:%8.2f out:%8.2f start:%8.2f direction:%8.2f\n",i,point_in[i],point_out[i],pos[i],back_direction[i]);
469 }
470 if (TString(gGeoManager->GetPath()).Contains("gas")) {
471 Int_t stepCount = 0;
472 while (
473 /*(!TString(gGeoManager->GetPath()).Contains("lattice") || !TString(gGeoManager->GetPath()).Contains("radiator")) &&*/
474 pos[2] >= point_in[2] - 5 && stepCount < 50) {
475 stepCount++;
476 //printf("step%i\n",stepCount);
477 for (Int_t i = 0; i < 3; i++) {
478 pos[i] += back_direction[i];
479 //printf("%8.2f ",pos[i]);
480 }
481 //printf(" %s\n",TString(gGeoManager->GetPath()).Data());
482 gGeoManager->FindNode(pos[0], pos[1], pos[2]);
483 if (TString(gGeoManager->GetPath()).Contains("radiator")) {
484 //printf ("%s false\n",TString(gGeoManager->GetPath()).Data());
485 return false;
486 }
487 else if (TString(gGeoManager->GetPath()).Contains("lattice")) {
488 //printf ("%s true <----------------------------------------\n",TString(gGeoManager->GetPath()).Data());
489 return true;
490 }
491 else if (TString(gGeoManager->GetPath()).Contains("frame")) {
492 //printf ("%s true <----------------------------------------\n",TString(gGeoManager->GetPath()).Data());
493 return true;
494 }
495 else {
496 //printf ("%s\n",TString(gGeoManager->GetPath()).Data());
497 }
498 }
499 }
500 else {
501 LOG(error) << "CbmTrdRadiator::LatticeHit: MC-track not in TRD! Node:" << TString(gGeoManager->GetPath()).Data()
502 << " gGeoManager->MasterToLocal() failed!";
503 return false;
504 }
505 }
506 else {
507 LOG(error) << "CbmTrdRadiator::LatticeHit: CbmTrdPoint == nullptr!";
508 return false;
509 }
510 return kTRUE;
511}
512//----------------------------------------------------------------------------
513// ---- Spectra Production ---------------------------------------------------
515{
516
517 fTrackMomentum = new Double_t[fNMom];
518
519 Double_t trackMomentum[fNMom] = {0.1, 0.25, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};
520
521 for (Int_t imom = 0; imom < fNMom; imom++) {
522 fTrackMomentum[imom] = trackMomentum[imom];
523 }
524
525 for (Int_t i = 0; i < fNMom; i++) {
526
527 fMom.SetXYZ(0.0, 0.0, fTrackMomentum[i]);
528
529 ProcessTR();
530 fnTRabs[i] = fnTRab;
531
532 // copy the content of the current fDetSpectrumA into appropriate
533 // fFinal
534
535 Float_t tmp = 0;
536 for (Int_t j = 0; j < fSpNBins; j++) {
537 tmp = fDetSpectrumA->GetBinContent(j + 1);
538 fFinal[i]->SetBinContent(j + 1, tmp);
539 }
540 fFinal[i]->SetTitle(Form("%s-momentum%.2f", fFinal[i]->GetTitle(), fTrackMomentum[i]));
541 }
542}
543
544//----------------------------------------------------------------------------
545
546// ---- GetTR ---------------------------------------------------------------
547Float_t CbmTrdRadiator::GetTR(TVector3 Mom)
548{
549
550 /*
551 * Simplified simulation of the TR
552 */
553
554 if (fSimpleTR == kTRUE) {
555
556 Float_t m = Mom.Mag();
557
558 // Find correct spectra
559 Int_t i = 0;
560 while (m > fTrackMomentum[i]) {
561 i++;
562 if (i == fNMom) {
563 i--;
564 break;
565 }
566 }
567
568 ELoss(i);
569 }
570
571 /*
572 * Full simulation of the TR production
573 */
574 else {
575
576 fMom = Mom;
577 ProcessTR();
578 }
579
580 return fELoss;
581}
582
583//----------------------------------------------------------------------------
584
585//----- main TR processing function ------------------------------
587{
588
589 // Compute the angle normalization factor -
590 // for different angles the detector thicknesses are different
591
592 Float_t fNormPhi = fMom.Mag() / fMom.Pz();
593
594 // Correct the thickness according to this factor
595
596 fFoilThickCorr = TMath::Abs(fFoilThick * fNormPhi);
597 fGapThickCorr = TMath::Abs(fGapThick * fNormPhi);
598 fGasThickCorr = TMath::Abs(fGasThick * fNormPhi);
599
600 fFirstPass = true;
601 // compute the TR spectra in the radiator
602 TRspectrum();
603 // compute the TR spectra in the mylar foil
605 // compute the TR spectra in the detector
607 // Loop over photons and compute the E losses
608 ELoss(-1);
609
610
611 if (fDetType == 1) { // if detector is MB type = dual-sided MWPC
612 fFirstPass = false;
613 Float_t energiefirst = fELoss;
614 Float_t fTRAbsfirst = fnTRab;
615
616 // compute the TR spectra in the mylar foil between the two gas layers
618 // compute the TR spectra in the second halve of the detector
620 // Loop over photons and compute the E losses
621 ELoss(-1);
622 fELoss += energiefirst;
623 fnTRab += fTRAbsfirst;
624 }
625}
626//----------------------------------------------------------------------------
627
628// ---- Compute the energy losses --------------------------------------------
629Int_t CbmTrdRadiator::ELoss(Int_t index)
630{
631
632 // calculate the energy loss of the TR photons in the
633 // detector gas. fNTRab is the number of TR photons
634 // absorbed in the gas. Since this number is low the
635 // actual number comes from a poisson distribution.
636
637 Int_t nPhoton;
638 Int_t maxPhoton = 50;
639 Double32_t eLoss = 0;
640 Float_t eTR = 0;
641
642 if (-1 == index) {
643 if (0 == fDetSpectrumA) {
644 LOG(error) << " -Err :: No input spectra ";
645 fELoss = -1;
646 return 1;
647 }
648 nPhoton = gRandom->Poisson(fnTRab * fnPhotonCorr);
649 if (nPhoton > maxPhoton) nPhoton = maxPhoton;
650 for (Int_t i = 0; i < nPhoton; i++) {
651 // energy of the photon
652 eTR = fDetSpectrumA->GetRandom();
653 eLoss += eTR;
654 }
655 }
656 else {
657 if (0 == fFinal[index]) {
658 LOG(error) << " -Err :: No input spectra ";
659 fELoss = -1;
660 return 1;
661 }
662 nPhoton = gRandom->Poisson(fnTRabs[index] * fnPhotonCorr);
663 if (nPhoton > maxPhoton) nPhoton = maxPhoton;
664 for (Int_t i = 0; i < nPhoton; i++) {
665 // energy of the photon
666 eTR = fFinal[index]->GetRandom();
667 eLoss += eTR;
668 }
669 }
670
671 // keV->GeV & set the result
672 fELoss = eLoss / 1000000.0;
673
674 return 0;
675}
676
677//----------------------------------------------------------------------------
678
679//----- TR spectrum ---------------------------------------------------
681{
682
683 // calculate the number of TR photons in the radiator which are not
684 // absorbed in the radiator.
685 // Formulas are tacken from M. Castellano et al.
686 // Computer Physics Communications 61 (1990)
687
688
689 // Where does this values come from, put them in the header file
690 const Float_t kAlpha = 0.0072973; // 1/137
691 const Int_t kSumMax = 30;
692
693 // calculate the gamma of the particle
694 Float_t gamma = GammaF();
695
696 fSpectrum->Reset();
697 fDetSpectrum->Reset();
698 fDetSpectrumA->Reset();
699
700 Float_t kappa = fGapThickCorr / fFoilThickCorr;
701
702 SetSigma(1);
703
704 //Float_t stemp = 0;
705
706 // Loop over energy
707 // stemp is the total energy of all created photons
708 for (Int_t iBin = 0; iBin < fSpNBins; iBin++) {
709
710 // keV -> eV
711 Float_t energyeV = (fSpBinWidth * iBin + 1.0) * 1e3;
712
713 Float_t csFoil = fFoilOmega / energyeV;
714 Float_t csGap = fGapOmega / energyeV;
715
716 Float_t rho1 = energyeV * fFoilThickCorr * 1e4 * 2.5 * (1.0 / (gamma * gamma) + csFoil * csFoil);
717 Float_t rho2 = energyeV * fFoilThickCorr * 1e4 * 2.5 * (1.0 / (gamma * gamma) + csGap * csGap);
718
719 // Calculate the sum over the production angle tetan
720 Float_t sum = 0;
721 for (Int_t iSum = 0; iSum < kSumMax; iSum++) {
722 Float_t tetan = (TMath::Pi() * 2.0 * (iSum + 1) - (rho1 + kappa * rho2)) / (kappa + 1.0);
723 if (tetan < 0.0) { tetan = 0.0; }
724 Float_t aux = 1.0 / (rho1 + tetan) - 1.0 / (rho2 + tetan);
725 sum += tetan * (aux * aux) * (1.0 - TMath::Cos(rho1 + tetan));
726 }
727 Float_t conv = 1.0 - TMath::Exp(-fNFoils * fSigma[iBin]);
728
729 // eV -> keV
730 Float_t energykeV = energyeV * 0.001;
731
732 // dN / domega
733 Float_t wn = kAlpha * 4.0 / (fSigma[iBin] * (kappa + 1.0)) * conv * sum / energykeV;
734 /*
735 wn = 4.0 * kAlpha
736 / (energykeV * (kappa + 1.0))
737 * (1.0 - TMath::Exp(Double_t(-fNFoils) * fSigma[iBin])) / (1.0 - TMath::Exp(-fSigma[iBin]))
738 * sum;
739 */
740 // save the result
741 fSpectrum->SetBinContent(iBin + 1, wn);
742 // compute the integral
743 //stemp += wn;
744 }
745
746 // <nTR> (binsize corr.)
747 //Float_t nTR0 = stemp * fSpBinWidth;
748 //LOG(info) << " No. of photons after radiator" << nTR0;
749
750 // compute the spectra behind the mylar foil (absorption)
751 // WinTRspectrum();
752
753 return 1;
754}
755
756//------------------------------------------------------------------
757
758//----- WinTRspectrum -----------------------------------------------
760{
761 //
762 // Computes the spectrum after absorption in Mylar foil
763 //
764
765 fWinSpectrum->Reset();
766
767 SetSigma(2);
768
769 //Float_t stemp = 0;
770 for (Int_t iBin = 0; iBin < fSpNBins; iBin++) {
771
772 Float_t sp = 0;
773 if (fFirstPass == true) { sp = fSpectrum->GetBinContent(iBin + 1); }
774 else {
775 sp = fDetSpectrum->GetBinContent(iBin + 1);
776 }
777 // compute the absorption coefficient
778 Float_t conv = TMath::Exp(-fSigmaWin[iBin]);
779 Float_t wn = sp * conv;
780
781 fWinSpectrum->SetBinContent(iBin + 1, wn);
782
783 //stemp += wn;
784 }
785
786 //fnTRprod = stemp * fSpBinWidth;
787 //LOG(info) << "No. of photons after My = "<< fnTRprod;
788
789 // compute the spectrum absorbed in the D & escaped from the D
790 // DetTRspectrum();
791 return 1;
792}
793//----------------------------------------------------------------------------
794
795//----- DetTRspectrum ------------------------------------------------
797{
798 //
799 // Computes the spectrum absorbed and passed in the gas mixture
800 //
801
802 SetSigma(3);
803 //Float_t stemp = 0;
804 Float_t stemp2 = 0;
805 for (Int_t iBin = 0; iBin < fSpNBins; iBin++) {
806
807 //passed spectrum
808 Float_t sp = 0;
809 sp = fWinSpectrum->GetBinContent(iBin + 1);
810 Float_t conv = TMath::Exp(-fSigmaDet[iBin]);
811 Float_t wn = sp * conv;
812
813 fDetSpectrum->SetBinContent(iBin + 1, wn);
814 //stemp += wn;
815
816 // absorbed spectrum
817 Float_t conv2 = 1 - TMath::Exp(-fSigmaDet[iBin]);
818 Float_t wn2 = sp * conv2;
819
820 fDetSpectrumA->SetBinContent(iBin + 1, wn2);
821 stemp2 += wn2;
822 }
823
824 //Float_t nTR1 = stemp * fSpBinWidth;
825 Float_t nTR2 = stemp2 * fSpBinWidth;
826
827 // Save the number of photons absorbed
828 fnTRab = nTR2;
829
830 //LOG(info) << " No. of photons escaped: " << nTR1;
831 //LOG(info) << " No. of photnos absorbed in the gas: " <<nTR2;
832
833 return 1;
834}
835//----------------------------------------------------------------------------
836
837//----- Gamma factor--------------------------------------------------
839{
840
841 // put this in the header ?
842 Float_t massE = 5.1099907e-4; // GeV/c2
843
844 Float_t p2 = fMom.Mag2();
845 Float_t result = TMath::Sqrt(p2 + massE * massE) / massE;
846
847 return result;
848}
849//----------------------------------------------------------------------------
850
851//----- SetSigma---------------------------------------------------------
852void CbmTrdRadiator::SetSigma(Int_t SigmaT)
853{
854 //
855 // Sets the absorbtion crosssection for the energies of the TR spectrum
856 //
857
858
859 if (SigmaT == 1) {
860 if (fSigma) delete[] fSigma;
861 fSigma = new Float_t[fSpNBins];
862 for (Int_t iBin = 0; iBin < fSpNBins; iBin++) {
863 Float_t energykeV = iBin * fSpBinWidth + 1.0;
864 fSigma[iBin] = Sigma(energykeV);
865 }
866 }
867
868 if (SigmaT == 2) {
869 if (fSigmaWin) delete[] fSigmaWin;
870 fSigmaWin = new Float_t[fSpNBins];
871 for (Int_t iBin = 0; iBin < fSpNBins; iBin++) {
872 Float_t energykeV = iBin * fSpBinWidth + 1.0;
873 fSigmaWin[iBin] = SigmaWin(energykeV);
874 }
875 }
876
877 if (SigmaT == 3) {
878 if (fSigmaDet) delete[] fSigmaDet;
879 fSigmaDet = new Float_t[fSpNBins];
880 for (Int_t iBin = 0; iBin < fSpNBins; iBin++) {
881 Float_t energykeV = iBin * fSpBinWidth + 1.0;
882 fSigmaDet[iBin] = SigmaDet(energykeV);
883 }
884 }
885}
886//----------------------------------------------------------------------------
887
888//----- Sigma-------------------------------------------------------------
889Float_t CbmTrdRadiator::Sigma(Float_t energykeV)
890{
891 //
892 // Calculates the absorbtion crosssection for a one-foil-one-gap-radiator
893 //
894
895 // keV -> MeV
896 Float_t energyMeV = energykeV * 0.001;
897 Float_t foil = 0.0;
898
899 if (fFoilMaterial == "polyethylen") foil = GetMuPo(energyMeV) * fFoilDens * fFoilThickCorr;
900 else if (fFoilMaterial == "pefoam20")
901 foil = GetMuPo(energyMeV) * fFoilDens * fFoilThickCorr;
902 else if (fFoilMaterial == "pefiber")
903 foil = GetMuPo(energyMeV) * fFoilDens * fFoilThickCorr;
904 else if (fFoilMaterial == "mylar")
905 foil = GetMuMy(energyMeV) * fFoilDens * fFoilThickCorr;
906 else if (fFoilMaterial == "pokalon")
907 foil = GetMuPok(energyMeV) * fFoilDens * fFoilThickCorr;
908 else
909 LOG(error) << "ERROR:: unknown radiator material";
910
911
912 if (energyMeV >= 0.001) {
913 Float_t result = (foil + (GetMuAir(energyMeV) * fGapDens * fGapThickCorr));
914 return result;
915 }
916 else {
917 return 1e6;
918 }
919}
920//----------------------------------------------------------------------------
921
922//----- SigmaWin -------------------------------------------------------
923Float_t CbmTrdRadiator::SigmaWin(Float_t energykeV)
924{
925 //
926 // Calculates the absorbtion crosssection for a one-foil
927 //
928
929 // keV -> MeV
930 Float_t energyMeV = energykeV * 0.001;
931 if (energyMeV >= 0.001) {
932 if (fWindowFoil == "Kapton") // aluminized kapton
933 return GetMuKa(energyMeV) * fWinDens * fWinThick + GetMuAl(energyMeV) * 2.70 /*[g/cm^3]*/ * 5E-6 /*[cm]*/;
934 else if (fWindowFoil == "Mylar") // mylar foil
935 return GetMuMy(energyMeV) * fWinDens * fWinThick;
936 else { // general sandwich structure
937 Float_t sigma(0.);
938 for (Int_t iwin(0); iwin < WINDOW.fN; iwin++)
939 sigma += WINDOW.GetMu[iwin](energyMeV) * WINDOW.fDens[iwin] * WINDOW.fThick[iwin];
940 return sigma;
941 }
942 }
943 else
944 return 1e6;
945}
946//----------------------------------------------------------------------------
947
948//----- SigmaDet --------------------------------------------------------
949Float_t CbmTrdRadiator::SigmaDet(Float_t energykeV)
950{
951 //
952 //Calculates the absorbtion crosssection for a choosed gas
953 //
954
955 // keV -> MeV
956 Float_t energyMeV = energykeV * 0.001;
957
958 if (energyMeV >= 0.001) {
959 // densities for CO2 and Xe changed. think density for CO2 is just
960 // a typo. where the difference for Xe comes from i don't know
961 // Values are from http://pdg.lbl.gov/AtomicNuclearProperties/
962 // return(GetMuCO2(energyMeV) * 0.001806 * fGasThick * fCom1 +
963 // GetMuXe(energyMeV) * 0.00589 * fGasThick * fCom2);
964 return (GetMuCO2(energyMeV) * 0.00184 * fGasThick * fCom1 + GetMuXe(energyMeV) * 0.00549 * fGasThick * fCom2);
965 }
966 else {
967 return 1e6;
968 }
969}
970//----------------------------------------------------------------------------
971
972//----- GetMuPok --------------------------------------------------------
973Float_t CbmTrdRadiator::GetMuPok(Float_t energyMeV)
974{
975 //
976 // Returns the photon absorbtion cross section for pokalon N470
977 //
978 return Interpolate(energyMeV, fEn_pok, fMu_pok, fKN_pok);
979}
980//----------------------------------------------------------------------------
981//----- GetMuKa --------------------------------------------------------
982Float_t CbmTrdRadiator::GetMuKa(Float_t energyMeV)
983{
984 //
985 // Returns the photon absorbtion cross section for kapton
986 //
987 return Interpolate(energyMeV, fEn_ka, fMu_ka, fKN_ka);
988}
989//----------------------------------------------------------------------------
990
991//----- GetMuAl --------------------------------------------------------
992Float_t CbmTrdRadiator::GetMuAl(Float_t energyMeV)
993{
994 //
995 // Returns the photon absorbtion cross section for Al
996 //
997 return Interpolate(energyMeV, fEn_al, fMu_al, fKN_al);
998}
999//----------------------------------------------------------------------------
1000
1001//----- GetMuC --------------------------------------------------------
1002Float_t CbmTrdRadiator::GetMuC(Float_t energyMeV)
1003{
1004 //
1005 // Returns the photon absorbtion cross section for Carbon
1006 //
1007 return Interpolate(energyMeV, fEn_c, fMu_c, fKN_c);
1008}
1009//----------------------------------------------------------------------------
1010
1011//----- GetMuPo --------------------------------------------------------
1012Float_t CbmTrdRadiator::GetMuPo(Float_t energyMeV)
1013{
1014 //
1015 // Returns the photon absorbtion cross section for polypropylene
1016 //
1017 return Interpolate(energyMeV, fEn_po, fMu_po, fKN_po);
1018}
1019//----------------------------------------------------------------------------
1020
1021//----- GetMuAir --------------------------------------------------------
1022Float_t CbmTrdRadiator::GetMuAir(Float_t energyMeV)
1023{
1024 //
1025 // Returns the photon absorbtion cross section for Air
1026 //
1027 return Interpolate(energyMeV, fEn_air, fMu_air, fKN_air);
1028}
1029//----------------------------------------------------------------------------
1030
1031//----- GetMuXe --------------------------------------------------------
1032Float_t CbmTrdRadiator::GetMuXe(Float_t energyMeV)
1033{
1034 //
1035 // Returns the photon absorbtion cross section for xenon
1036 //
1037 return Interpolate(energyMeV, fEn_xe, fMu_xe, fKN_xe);
1038}
1039//----------------------------------------------------------------------------
1040
1041//----- GetMuCO2 ------------------------------------------------------
1042Float_t CbmTrdRadiator::GetMuCO2(Float_t energyMeV)
1043{
1044 //
1045 // Returns the photon absorbtion cross section for CO2
1046 //
1047 return Interpolate(energyMeV, fEn_co2, fMu_co2, fKN_co2);
1048}
1049//----------------------------------------------------------------------------
1050
1051//----- GetMuMy -------------------------------------------------------
1052Float_t CbmTrdRadiator::GetMuMy(Float_t energyMeV)
1053{
1054 //
1055 // Returns the photon absorbtion cross section for mylar
1056 //
1057 return Interpolate(energyMeV, fEn_my, fMu_my, fKN_my);
1058}
1059//----------------------------------------------------------------------------
1060
1061//----- Interpolate ------------------------------------------------------
1062Float_t CbmTrdRadiator::Interpolate(Float_t energyMeV, const Float_t* en, const Float_t* mu, Int_t n)
1063{
1064 //
1065 // Interpolates the photon absorbtion cross section
1066 // for a given energy <energyMeV>.
1067 //
1068
1069 Float_t de = 0;
1070 Int_t index = 0;
1071 Int_t istat = Locate(en, n, energyMeV, index, de);
1072 if (istat == 0) {
1073 // Float_t result = (mu[index] - de * (mu[index] - mu[index+1])
1074 // / (en[index+1] - en[index] ));
1075 // return result;
1076 Float_t result =
1077 (TMath::Log(mu[index]) - de * (TMath::Log(mu[index]) - TMath::Log(mu[index + 1])) / (en[index + 1] - en[index]));
1078 return TMath::Exp(result);
1079 }
1080 else {
1081 return 0.0;
1082 }
1083}
1084//----------------------------------------------------------------------------
1085
1086//----- Locate ------------------------------------------------------------
1087Int_t CbmTrdRadiator::Locate(const Float_t* xv, Int_t n, Float_t xval, Int_t& kl, Float_t& dx)
1088{
1089 //
1090 // Locates a point (xval) in a 1-dim grid (xv(n))
1091 //
1092
1093 if (xval >= xv[n - 1]) return 1;
1094 if (xval < xv[0]) return -1;
1095
1096 Int_t km;
1097 Int_t kh = n - 1;
1098
1099 kl = 0;
1100 while (kh - kl > 1) {
1101 if (xval < xv[km = (kl + kh) / 2]) kh = km;
1102 else
1103 kl = km;
1104 }
1105 if (xval < xv[kl] || xval > xv[kl + 1] || kl >= n - 1) {
1106 printf("Locate failed xv[%d] %f xval %f xv[%d] %f!!!\n", kl, xv[kl], xval, kl + 1, xv[kl + 1]);
1107 exit(1);
1108 }
1109
1110 dx = xval - xv[kl];
1111 if (xval == 0.001) LOG(info) << "Locat = 0";
1112 return 0;
1113}
1114//----------------------------------------------------------------------------
1115// Photon absorption cross sections
1116
1117// Pokalon N470
1118constexpr Float_t CbmTrdRadiator::fEn_pok[46];
1119constexpr Float_t CbmTrdRadiator::fMu_pok[46];
1120
1121// Kapton
1122constexpr Float_t CbmTrdRadiator::fEn_ka[46];
1123constexpr Float_t CbmTrdRadiator::fMu_ka[46];
1124
1125// Aluminum
1126constexpr Float_t CbmTrdRadiator::fEn_al[48];
1127constexpr Float_t CbmTrdRadiator::fMu_al[48];
1128
1129// Polypropylene/Polyethylene
1130constexpr Float_t CbmTrdRadiator::fEn_po[36];
1131constexpr Float_t CbmTrdRadiator::fMu_po[36];
1132
1133// Carbon
1134constexpr Float_t CbmTrdRadiator::fEn_c[46];
1135constexpr Float_t CbmTrdRadiator::fMu_c[46];
1136
1137// Air
1138constexpr Float_t CbmTrdRadiator::fEn_air[38];
1139constexpr Float_t CbmTrdRadiator::fMu_air[38];
1140
1141// Xenon
1142constexpr Float_t CbmTrdRadiator::fEn_xe[48];
1143constexpr Float_t CbmTrdRadiator::fMu_xe[48];
1144
1145// CO2
1146constexpr Float_t CbmTrdRadiator::fEn_co2[36];
1147constexpr Float_t CbmTrdRadiator::fMu_co2[36];
1148
1149// Mylar
1150constexpr Float_t CbmTrdRadiator::fEn_my[36];
1151constexpr Float_t CbmTrdRadiator::fMu_my[36];
1152
1153
ClassImp(CbmConverterManager)
Container for gas properties of TRD.
Float_t(* GetMuPtr)(Float_t)
#define NCOMPONENTS
Double_t GetNobleGas() const
Definition CbmTrdGas.h:28
Double_t GetGasThick() const
Definition CbmTrdGas.h:27
Int_t GetDetType() const
Definition CbmTrdGas.h:26
void Init()
Definition CbmTrdGas.cxx:43
static CbmTrdGas * Instance()
Definition CbmTrdGas.h:33
Double_t GetCO2() const
Definition CbmTrdGas.h:29
double GetYOut() const
Definition CbmTrdPoint.h:69
double GetXIn() const
Definition CbmTrdPoint.h:65
double GetZIn() const
Definition CbmTrdPoint.h:67
double GetXOut() const
Definition CbmTrdPoint.h:68
double GetYIn() const
Definition CbmTrdPoint.h:66
double GetZOut() const
Definition CbmTrdPoint.h:70
static constexpr Float_t fMu_c[46]
static const Int_t fKN_xe
static constexpr Float_t fMu_ka[46]
static constexpr Float_t fEn_co2[36]
static Int_t Locate(const Float_t *xv, Int_t n, Float_t xval, Int_t &kl, Float_t &dx)
Bool_t LatticeHit(const CbmTrdPoint *point)
Float_t SigmaDet(Float_t energykeV)
static const Int_t fNMom
TR passed through Detector.
static Float_t GetMuKa(Float_t energyMeV)
CbmTrdRadiator(Bool_t SimpleTR=true, Int_t Nfoils=337, Float_t FoilThick=0.0012, Float_t GapThick=0.09, TString material="pefoam20", TString window="Kapton")
Float_t Sigma(Float_t energykeV)
static constexpr Float_t fEn_c[46]
static Float_t GetMuC(Float_t energyMeV)
static Float_t GetMuPo(Float_t energyMeV)
void SetSigma(Int_t SigmaT)
static constexpr Float_t fEn_my[36]
Float_t fnTRabs[fNMom]
Absorption spectra for different momenta.
Float_t * fSigmaDet
[fSpNBins] Array of sigma values for the entrance window of detector
static const Int_t fKN_pok
static Float_t GetMuXe(Float_t energyMeV)
static const Int_t fKN_co2
static Float_t GetMuAir(Float_t energyMeV)
static constexpr Float_t fMu_my[36]
static constexpr Float_t fEn_pok[46]
CbmTrdEntranceWindow WINDOW
Float_t * fSigmaWin
[fSpNBins] Array of sigma values for the foil of the radiator
static const Int_t fKN_po
static constexpr Float_t fMu_al[48]
static constexpr Float_t fMu_pok[46]
static Float_t Interpolate(Float_t energyMeV, const Float_t *en, const Float_t *mu, Int_t n)
Float_t SigmaWin(Float_t energykeV)
static constexpr Float_t fMu_co2[36]
TH1D * fDetSpectrumA
TR spectra in gas-window foil.
TH1D * fDetSpectrum
TR absorbed in Detector.
static const Int_t fKN_ka
Float_t GetTR(TVector3 mom)
Double_t * fTrackMomentum
static constexpr Float_t fEn_ka[46]
static const Int_t fSpNBins
TH1D * fSpectrum
[fSpNBins] Array of sigma values for the active gas
Int_t ELoss(Int_t index)
TH1D * fWinSpectrum
TR photon energy spectrum.
static constexpr Float_t fMu_po[36]
static constexpr Float_t fMu_air[38]
void SetEWwidths(Int_t n, Float_t *w)
static const Int_t fSpRange
static Float_t GetMuAl(Float_t energyMeV)
static constexpr Float_t fEn_al[48]
static const Int_t fKN_c
static constexpr Float_t fEn_po[36]
static constexpr Float_t fMu_xe[48]
static const Int_t fKN_air
static Float_t GetMuMy(Float_t energyMeV)
virtual ~CbmTrdRadiator()
static constexpr Float_t fEn_xe[48]
static Float_t GetMuCO2(Float_t energyMeV)
static Float_t GetMuPok(Float_t energyMeV)
static const Int_t fKN_al
static constexpr Float_t fEn_air[38]
static const Int_t fKN_my
TH1D * fFinal[fNMom]
[fNMom] Track momenta for which spectra