CbmRoot
CbmTrdParModGas.cxx
Go to the documentation of this file.
1 #include "CbmTrdParModGas.h"
2 
3 #include <FairLogger.h> // for Logger, LOG
4 
5 #include <TAxis.h> // for TAxis
6 #include <TGenericClassInfo.h> // for TGenericClassInfo
7 #include <TH2.h> // for TH2F
8 #include <TMath.h> // for Exp
9 #include <TMathBase.h> // for Abs
10 #include <TObjArray.h> // for TObjArray
11 #include <TObjString.h> // for TObjString
12 
13 #include <stdio.h> // for printf
14 
15 #define VERBOSE 0
16 
17 // binding energy in keV for 'K' 'L' and 'M' shells of Ar and Xe
19  {34.5, 5.1, 1.1}, // Xe
20  {3.2, 0.25, 0.1} // Ar
21 };
22 // binding energy in keV for 'K' 'L' and 'M' shells of Ar and Xe
23 Float_t CbmTrdParModGas::fgkBR[2][NSHELLS - 1] = {
24  {0.11, 0.02}, // Xe
25  {0.11, 0.02} // Ar
26 };
27 // average energy to produce one electron-ion pair
28 Float_t CbmTrdParModGas::fgkWi[3] = {
29  23.1, // Xe
30  25.8, // Ar
31  33 // CO2
32 };
33 // Bucharest detector gas gain parametrization based on 55Fe measurements with ArCO2(80/20)
34 Float_t CbmTrdParModGas::fgkGGainUaPar[2] = {-10.1676, 8.3745};
35 Float_t CbmTrdParModGas::fgkE0 = 866.1047; // energy offset in ADC ch @ 0 keV
36 
37 //___________________________________________________________________
39  : CbmTrdParMod("CbmTrdParModGas", title)
40  , fConfig(0)
41  , fUa(0)
42  , fUd(0)
43  , fDw(0.3)
44  , fGasThick(0.6)
45  , fPercentCO2(0.2)
46  , fDriftMap(nullptr)
47  , fFileNamePID() {
48  TString s(title);
49  TString name;
50  // Int_t val;
51  TObjArray* so = s.Tokenize("/");
52  for (Int_t ie(0); ie < so->GetEntries(); ie += 2) {
53  name = ((TObjString*) (*so)[ie])->String();
54  if (name.EqualTo("Module"))
55  fModuleId = ((TObjString*) (*so)[ie + 1])->String().Atoi();
56  else if (name.EqualTo("Ua"))
57  fUa = ((TObjString*) (*so)[ie + 1])->String().Atoi();
58  else if (name.EqualTo("Ud"))
59  fUd = ((TObjString*) (*so)[ie + 1])->String().Atoi();
60  else if (name.EqualTo("Gas")) {
61  TString gas = ((TObjString*) (*so)[ie + 1])->String();
62  if (gas.EqualTo("Ar"))
63  SetNobleGasType(1);
64  else if (gas.EqualTo("Xe"))
65  SetNobleGasType(0);
66  else {
67  LOG(warn) << GetName() << ":: gas type \"" << gas
68  << "\" not defined. Default to Xe.";
69  SetNobleGasType(0);
70  }
71  }
72  }
73  so->Delete();
74  delete so;
75 
76  if (VERBOSE) printf("Module[%2d] U[%4d %3d]\n", fModuleId, fUa, fUd);
77 }
78 
79 //___________________________________________________________________
81  // if(fDriftMap) delete fDriftMap;
82 }
83 
84 //_______________________________________________________________________________________________
85 Float_t CbmTrdParModGas::EkevFC(Float_t ekev) const {
86  // Convert energy deposit to no of primary ionizations and apply gas gain.
87  // Currently gas gain is evalauted from 55Fe spectrum analysis on ArCO2(80/20)
88  Int_t gasId = GetNobleGasType() - 1;
89  Float_t wi = (1. - fPercentCO2) * fgkWi[gasId] + fPercentCO2 * fgkWi[2];
90 
91  //gas gain
92  // G = G[ev->ADC] * wi[ArCO2]/C[mV->ADC]/A[fC->mV]/e
93  // G[ev->ADC] : measured gain based on 55Fe spectrum (expo)
94  // wi[ArCO2] : average energy to produce a ele-ion pair in mixture (27.24 ev)
95  // C[mV->ADC] : FASP out [2V] to ADC range [4096 ch] (2)
96  // A[fC->mV] : FASP gain from CADENCE (6)
97  // e : 1.6e-4 [fC] electric charge
98  Double_t gain =
99  170.25 * TMath::Exp(fgkGGainUaPar[0] + fgkGGainUaPar[1] * fUa * 1.e-3)
100  / 12.;
101  // for Xe correct Ar gain measurements TODO
102  if (gasId == 0) gain *= 0.6;
103 
104  Float_t efC = gain * ekev * 0.16 / wi;
105  if (VERBOSE)
106  printf(
107  " ua[V]=%d gain[%5.2e] wi[eV]=%5.2f :: E[keV]=%6.3f E[fC]=%6.2f\n",
108  fUa,
109  gain,
110  wi,
111  ekev,
112  efC);
113  return efC;
114 
115  // Double_t eadc = fgkE0 + gain * ekev;
116  // //printf("E = %fkeV %fADC\n", ekev, eadc);
117  // // apply FASP gain -> should be done without intermediate ADC conversion TODO
118  // Double_t sFASP = eadc/2.; // FASP signal [mV]; FASP amplification 1
119  // // FASP gaincharacteristic -> should be defined elsewhere
120  // // data based on CADENCE simulations
121  // Double_t s0FASP = 10, gFASP = 6;
122  // return (sFASP-s0FASP)/gFASP;
123 }
124 
125 //_______________________________________________________________________________________________
126 Int_t CbmTrdParModGas::GetShellId(const Char_t shell) const {
130  switch (shell) {
131  case 'K': return 0;
132  case 'L': return 1;
133  case 'M': return 2;
134  default:
135  LOG(warn) << GetName() << "::GetShellId: Atomic shell : " << shell
136  << " not defined for gas "
137  << (GetNobleGasType() == 2 ? "Ar" : "Xe");
138  return -1;
139  }
140 }
141 
142 //_______________________________________________________________________________________________
143 Float_t CbmTrdParModGas::GetBindingEnergy(const Char_t shell,
144  Bool_t main) const {
145  Int_t gasId = GetNobleGasType() - 1;
146  Int_t shellId = GetShellId(shell);
147  if (shellId < 0) return 0;
148 
149  if (!main)
150  return fgkBindingEnergy[gasId][shellId];
151  else {
152  if (shellId < NSHELLS - 1)
153  return fgkBindingEnergy[gasId][shellId + 1];
154  else {
155  LOG(warn) << GetName()
156  << "::GetBindingEnergy: Request atomic shell : " << shellId + 1
157  << " not defined for gas " << (gasId ? "Ar" : "Xe");
158  return 0;
159  }
160  }
161  return 0;
162 }
163 
164 //_______________________________________________________________________________________________
165 Float_t CbmTrdParModGas::GetNonIonizingBR(const Char_t shell) const {
166  Int_t gasId = GetNobleGasType() - 1;
167  Int_t shellId = GetShellId(shell);
168  if (shellId < 0) return 0;
169 
170  return fgkBR[gasId][shellId];
171 }
172 
173 //_______________________________________________________________________________________________
174 Char_t CbmTrdParModGas::GetPEshell(Float_t Ex) const {
175  const Char_t shellName[NSHELLS] = {'K', 'L', 'M'};
176  Int_t gasId = GetNobleGasType() - 1;
177  for (Int_t ishell(0); ishell < NSHELLS; ishell++) {
178  if (Ex < fgkBindingEnergy[gasId][ishell]) continue;
179  return shellName[ishell];
180  }
181  LOG(debug) << GetName() << "::GetPEshell: Ex[keV] " << Ex
182  << " less than highes atomic shell binding energy : "
183  << fgkBindingEnergy[gasId][NSHELLS - 1] << " for gas "
184  << (gasId ? "Ar" : "Xe");
185  return 0;
186 }
187 
188 //_______________________________________________________________________________________________
189 Double_t CbmTrdParModGas::GetDriftTime(Double_t y0, Double_t z0) const {
190  const TAxis *ay(fDriftMap->GetXaxis()), *az(fDriftMap->GetYaxis());
191  Int_t by(ay->FindBin(y0)), bz(az->FindBin(z0));
192  Double_t tmin(fDriftMap->GetBinContent(by, bz));
193  if (VERBOSE) printf("GetDriftTime :: Start @ dt=%3d [ns]\n", Int_t(tmin));
194  return tmin;
195 }
196 
197 //_______________________________________________________________________________________________
198 void CbmTrdParModGas::Print(Option_t* /*opt*/) const {
199  printf("%s @ %4d ", GetName(), fModuleId);
200  printf("Type[%s] ", GetDetName());
201  printf("%s[%4.1f%%] Ua[V]=%d Ud[V]=%d ",
202  GetNobleGasName(),
203  1e2 * GetNobleGas(),
204  fUa,
205  fUd);
206  printf("Pid Type[%d] DB[%s]\n", GetPidType(), fFileNamePID.Data());
207 }
208 
209 //_______________________________________________________________________________________________
210 Double_t CbmTrdParModGas::ScanDriftTime(Double_t y0,
211  Double_t z0,
212  Double_t dzdy,
213  Double_t dy) const {
214  Double_t y1 = y0 + dy, z1 = z0 + dzdy * dy, dw(fDw), dwh(0.5 * dw);
215  // Double_t dhh(fGasThick);
216 
217  if (VERBOSE)
218  printf("ScanDriftTime :: Try : [%7.4f %7.4f] => [%7.4f %7.4f] dzdy[%5.2f] "
219  "dy[%5.2f]\n",
220  y0,
221  z0,
222  y1,
223  z1,
224  dzdy,
225  dy);
226  while (y1 < -dwh - 1e-3) {
227  y0 += dw;
228  y1 += dw;
229  }
230  while (y1 > dwh + 1.e-3) {
231  y0 -= dw;
232  y1 -= dw;
233  }
234  TH2F* h = fDriftMap;
235  y1 = y0;
236  z1 = z0;
237  const TAxis *ay(fDriftMap->GetXaxis()), *az(fDriftMap->GetYaxis());
238  Int_t by(ay->FindBin(y1)), bz(az->FindBin(z1)), nby(ay->GetNbins()),
239  nbz(az->GetNbins());
240  Float_t dyStep = ay->GetBinWidth(1), tmin(500), tmax(0), tc(0);
241  while (by > 0 && by <= nby && bz <= nbz) {
242  bz = az->FindBin(z1);
243  tc = h->GetBinContent(by, bz);
244  //if(VERBOSE) printf("ScanDriftTime :: Do : y0(%7.4f), z0(%7.4f), by(%3d), bz(%3d) td[ns]=%5.1f t0[ns]=%5.1f \n", y1, z1, by, bz, tc, tmin);
245 
246  if (tc > 0) {
247  if (tc < tmin) tmin = tc;
248  if (tc > tmax) tmax = tc;
249  }
250  z1 += TMath::Abs(dzdy) * dyStep;
251  if (dzdy > 0) {
252  y1 += dyStep;
253  by++;
254  } else {
255  y1 -= dyStep;
256  by--;
257  }
258  }
259  if (VERBOSE) printf("ScanDriftTime :: Start @ dt=%3d [ns]\n", Int_t(tmin));
260 
261  return tmin;
262 }
263 
264 //___________________________________________________________________
265 void CbmTrdParModGas::SetDriftMap(TH2F* hm, TDirectory* d) {
270  if (VERBOSE)
271  printf("CbmTrdParModGas::SetDriftMap : Module[%2d] U[%4d %3d]\n",
272  fModuleId,
273  fUa,
274  fUd);
275 
276  fDriftMap = (TH2F*) hm->Clone(Form("trdDM%02d", fModuleId));
277  fDriftMap->SetTitle(GetTitle());
278  fDriftMap->SetDirectory(d);
279 }
280 
CbmTrdParModGas.h
CbmTrdParModGas::fgkBindingEnergy
static Float_t fgkBindingEnergy[2][NSHELLS]
binding energy in keV for first atomic shells of Ar and Xe
Definition: CbmTrdParModGas.h:124
CbmTrdParModGas::GetBindingEnergy
Float_t GetBindingEnergy(const Char_t shell='K', Bool_t main=kTRUE) const
Get binding energy for the working gas.
Definition: CbmTrdParModGas.cxx:143
CbmTrdParModGas::fgkE0
static Float_t fgkE0
min energy [ADC ch] which can be measured
Definition: CbmTrdParModGas.h:132
CbmTrdParModGas::GetDriftTime
Double_t GetDriftTime(Double_t y0, Double_t z0) const
Definition: CbmTrdParModGas.cxx:189
VERBOSE
#define VERBOSE
Definition: CbmTrdParModGas.cxx:15
CbmTrdParModGas::fUa
UShort_t fUa
anode voltage
Definition: CbmTrdParModGas.h:114
CbmTrdParModGas::GetNobleGasType
Int_t GetNobleGasType() const
Definition: CbmTrdParModGas.h:51
CbmTrdParModGas::fgkGGainUaPar
static Float_t fgkGGainUaPar[2]
gas gaian parametrization on Ua for Ar on Buch detector
Definition: CbmTrdParModGas.h:131
CbmTrdParModGas::fFileNamePID
TString fFileNamePID
filename for PID database
Definition: CbmTrdParModGas.h:120
CbmTrdParModGas::GetNonIonizingBR
Float_t GetNonIonizingBR(const Char_t shell='K') const
Get branching ration for radiative process on the.
Definition: CbmTrdParModGas.cxx:165
CbmTrdParModGas::EkevFC
Float_t EkevFC(Float_t ekev) const
Convert Energy debposit in keV to pad-plane charge taking into account the gas gain.
Definition: CbmTrdParModGas.cxx:85
CbmTrdParModGas::GetPidType
Int_t GetPidType() const
Definition: CbmTrdParModGas.h:63
h
Data class with information on a STS local track.
CbmTrdParModGas::~CbmTrdParModGas
virtual ~CbmTrdParModGas()
Definition: CbmTrdParModGas.cxx:80
CbmTrdParModGas::GetShellId
Int_t GetShellId(const Char_t shell) const
Get atomic shell index.
Definition: CbmTrdParModGas.cxx:126
d
double d
Definition: P4_F64vec2.h:24
CbmTrdParModGas::fgkBR
static Float_t fgkBR[2][NSHELLS - 1]
branching ratio for non-ionizing decay of Ar and Xe
Definition: CbmTrdParModGas.h:127
CbmTrdParMod
Definition of generic parameters for one TRD module.
Definition: CbmTrdParMod.h:9
CbmTrdParModGas::GetNobleGas
Double_t GetNobleGas() const
Definition: CbmTrdParModGas.h:47
ClassImp
ClassImp(CbmConverterManager) InitStatus CbmConverterManager
Definition: CbmConverterManager.cxx:12
CbmTrdParModGas::fDriftMap
TH2F * fDriftMap
drift time map for one amplification cell
Definition: CbmTrdParModGas.h:119
CbmTrdParModGas::GetNobleGasName
const Char_t * GetNobleGasName() const
Definition: CbmTrdParModGas.h:48
CbmTrdParModGas::fPercentCO2
Double_t fPercentCO2
Percentage of CO2.
Definition: CbmTrdParModGas.h:118
CbmTrdParModGas::GetPEshell
Char_t GetPEshell(Float_t Ex) const
Get first atomic shell which can be excited by PE effect.
Definition: CbmTrdParModGas.cxx:174
CbmTrdParModGas::SetDriftMap
void SetDriftMap(TH2F *hm, TDirectory *d)
Load drift map for current settings from repository.
Definition: CbmTrdParModGas.cxx:265
NSHELLS
#define NSHELLS
Definition: CbmTrdParModGas.h:13
CbmTrdParModGas::fUd
UShort_t fUd
drift voltage
Definition: CbmTrdParModGas.h:115
CbmTrdParModGas::fDw
Double_t fDw
anode wire pitch
Definition: CbmTrdParModGas.h:116
CbmTrdParModGas::ScanDriftTime
Double_t ScanDriftTime(Double_t y0, Double_t z0, Double_t dzdy, Double_t dy) const
Get prompt signal for track segment in the y-z plane.
Definition: CbmTrdParModGas.cxx:210
CbmTrdParModGas::GetDetName
const Char_t * GetDetName() const
Definition: CbmTrdParModGas.h:29
CbmTrdParModGas::SetNobleGasType
void SetNobleGasType(Int_t ar=1)
Definition: CbmTrdParModGas.h:98
CbmTrdParModGas::CbmTrdParModGas
CbmTrdParModGas(const char *title="TRD gas properties definition")
Definition: CbmTrdParModGas.cxx:38
z1
Double_t z1[nSects1]
Definition: pipe_v16a_mvdsts100.h:6
CbmTrdParModGas::Print
virtual void Print(Option_t *opt="") const
Definition: CbmTrdParModGas.cxx:198
CbmTrdParMod::fModuleId
Int_t fModuleId
module id
Definition: CbmTrdParMod.h:20
CbmTrdParModGas
Definition of gas parameters for one TRD module.
Definition: CbmTrdParModGas.h:16
CbmTrdParModGas::fgkWi
static Float_t fgkWi[3]
average energy to produce one electron-ion pair for ar, xe and co2
Definition: CbmTrdParModGas.h:129