BOSS 7.0.9
BESIII Offline Software System
Loading...
Searching...
No Matches
HadronSaturation.cc
Go to the documentation of this file.
1#include "HadronSaturation.h"
2
3static HadronSaturation *HC_obj;
4
6 m_flag(0),
7 m_cosbins(18),
8 m_alpha(0.0266879),
9 m_gamma(0.00378704),
10 m_delta(0.0038601),
11 m_power(1.8957),
12 m_ratio(3.09834)
13{
14 m_dedx.clear();
15 m_dedxerror.clear();
16 m_betagamma.clear();
17 m_costheta.clear();
18 HC_obj = this;
19}
20
21HadronSaturation::HadronSaturation( double alpha, double gamma, double delta, double power, double ratio ) :
22 m_flag(0),
23 m_cosbins(18),
24 m_alpha(alpha),
25 m_gamma(gamma),
27 m_power(power),
28 m_ratio(ratio)
29{
30 m_dedx.clear();
31 m_dedxerror.clear();
32 m_betagamma.clear();
33 m_costheta.clear();
34}
35
36void
38 m_alpha = par[0];
39 m_gamma = par[1];
40 m_delta = par[2];
41 m_power = par[3];
42 m_ratio = par[4];
43}
44
45void
46HadronSaturation::setParameters( std::string infile ){
47 double hadpar[5];
48 std::ifstream parfile(infile.c_str());
49 if( !parfile.fail() ){
50 for( int i = 0; i < 5; ++i ){
51 parfile >> hadpar[i];
52 }
53 parfile.close();
54 setParameters(hadpar);
55 }
56 else
57 std::cout << "HadronSaturation: WARNING - parameter file " << infile << " does not exist, using defaults..." << std::endl;
58}
59
60void
61HadronSaturation::fillSample( TString infilename ) {
62
63 std::cout << "HadronSaturation: filling sample events..." << std::endl;
64
65 // clear the vectors to be filled
66 clear();
67
68 std::vector< TString > types;
69 types.push_back("pion");
70 types.push_back("kaon");
71 types.push_back("proton");
72 types.push_back("muon");
73 types.push_back("electron");
74
75 // fill the containers with a previously prepared sample
76 TFile* satFile = new TFile(infilename);
77
78 for( int i = 0; i < 4; ++i ){
79 TTree* satTree = (TTree*)satFile->Get(types[i]);
80
81 double satdedx, saterror, satbg, satcosth;
82 satTree->SetBranchAddress("dedx",&satdedx);
83 satTree->SetBranchAddress("error",&saterror);
84 satTree->SetBranchAddress("bg",&satbg);
85 satTree->SetBranchAddress("costh",&satcosth);
86
87 // fill the vectors
88 for( unsigned int i = 0; i < satTree->GetEntries(); ++i ){
89 satTree->GetEvent(i);
90
91 if( saterror == 0 ) continue;
92
93 m_dedx.push_back(satdedx);
94 m_dedxerror.push_back(saterror);
95 m_betagamma.push_back(satbg);
96 m_costheta.push_back(satcosth);
97 }
98 }
99
100 satFile->Close();
101}
102
103void
104HadronSaturation::printEvents( int firstevent = 0, int nevents = 10 ){
105
106 if( firstevent < 0 || (nevents+firstevent) > m_dedx.size() ){
107 std::cout << "HadronSaturation: trying to print events out of range (" << m_dedx.size() << ")" << std::endl;
108 exit(1);
109 }
110
111 std::cout << std::endl << std::endl;
112 for( int i = firstevent; i < nevents; ++i ){
113 std::cout << "Event " << i << ":\t bg = " << m_betagamma[i] << "\t cos(theta) = " << m_costheta[i] << "\t dE/dx mean = " << m_dedx[i] << "\t dE/dx error = " << m_dedxerror[i] << std::endl;
114 }
115 std::cout << std::endl;
116}
117
118double
119HadronSaturation::D2I( double cosTheta, double D, double alpha, double gamma, double delta, double power, double ratio ) const {
120
121 double absCosTheta = fabs(cosTheta);
122 double projection = pow(absCosTheta, power) + delta;
123 double chargeDensity = D / projection;
124 double numerator = 1 + alpha * chargeDensity;
125 double denominator = 1 + gamma * chargeDensity;
126
127 double I = D * ratio * numerator / denominator;
128
129 return I;
130}
131
132double
133HadronSaturation::I2D( double cosTheta, double I, double alpha, double gamma, double delta, double power, double ratio ) const {
134
135 double absCosTheta = fabs(cosTheta);
136 double projection = pow(absCosTheta, power) + delta;
137
138 double a = alpha/projection;
139 double b = 1 - gamma/projection * (I/ratio);
140 double c = -1.0 * I/ratio;
141
142 if( b == 0 && a == 0 ){
143 std::cout << "both a and b coefficiants for hadron correction are 0" << std::endl;
144 return I;
145 }
146
147 double D = (a != 0) ? (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a) : -c / b;
148 if( D < 0 ){
149 // std::cout << "D is less 0! will try another solution" << std::endl;
150 D = (a != 0) ? (-b - sqrt(b * b + 4.0 * a * c)) / (2.0 * a) : -c / b;
151 if( D < 0 ){
152 // std::cout << "D is still less 0! just return uncorrectecd value" << std::endl;
153 return I;
154 }
155 }
156
157 return D;
158}
159
160double
161HadronSaturation::myFunction( double alpha, double gamma, double delta, double power, double ratio ){
162
163 unsigned int nevt = m_dedx.size();
164 double chisq = 0, dedxsum = 0;
165 std::vector< double > vdedxavg;
166
167 // Compute the average value (across cos(theta)) for each bin of beta-gamma.
168 // NOTE: the correction is not constrained to a certain value (1), it
169 // changes as a function of beta gamma...
170 double dedxcor = 0;
171 for( unsigned int i = 0; i < nevt; i++ ){
172 if( m_flag == 0 )
173 dedxcor = D2I(m_costheta[i],I2D(m_costheta[i],1.0,alpha,gamma,delta,power,ratio)*m_dedx[i],alpha,gamma,delta,power,ratio);
174 else
175 dedxcor = D2I(m_costheta[i],m_dedx[i],alpha,gamma,delta,power,ratio);
176 dedxsum += dedxcor;
177
178 if( (i+1)%m_cosbins == 0 ){
179 vdedxavg.push_back(dedxsum/m_cosbins);
180 dedxsum = 0;
181 }
182 }
183
184 // Construct a chi^2 value for the difference between the average in a cosine bin
185 // to the actual values
186 for( unsigned int i = 0; i < nevt; i++ ){
187 if( m_flag == 0 )
188 dedxcor = D2I(m_costheta[i],I2D(m_costheta[i],1.0,alpha,gamma,delta,power,ratio)*m_dedx[i],alpha,gamma,delta,power,ratio);
189 else
190 dedxcor = D2I(m_costheta[i],m_dedx[i],alpha,gamma,delta,power,ratio);
191
192 int j = (int)i/m_cosbins;
193 chisq += pow((dedxcor-vdedxavg[j])/m_dedxerror[i],2);
194 }
195
196 return chisq;
197}
198
199void
200HadronSaturation::minuitFunction( int& nDim, double* gout, double& result, double* par, int flag ){
201 result = HC_obj->myFunction(par[0],par[1],par[2],par[3],par[4]);
202}
203
204void
206
207 std::cout << "Performing the hadron saturation fit..." << std::endl;
208
209 // Construct the fitter
210 TFitter* minimizer = new TFitter(5);
211 minimizer->SetFCN(HadronSaturation::minuitFunction);
212
213 TRandom* rand = new TRandom();
214
215 minimizer->SetParameter(0,"alpha",m_alpha,rand->Rndm()*0.001,0.0,0.5);
216 minimizer->SetParameter(1,"gamma",m_gamma,rand->Rndm()*0.001,-2,2);
217 minimizer->SetParameter(2,"delta",m_delta,rand->Rndm()*0.001,-2,2);
218 minimizer->SetParameter(3,"power",m_power,rand->Rndm()*0.01,-5,5);
219 minimizer->SetParameter(4,"ratio",m_ratio,rand->Rndm()*0.01,-100,100);
220
221 // Set minuit fitting strategy
222 double arg[10];
223 arg[0] = 2;
224 minimizer->ExecuteCommand("SET STR",arg,1);
225
226 // Suppress much of the output of MINUIT
227 arg[0] = -1;
228 minimizer->ExecuteCommand("SET PRINT",arg,1);
229
230 // Minimize with MIGRAD
231 arg[0] = 10000;
232
233 double fitpar[5], fiterr[5];
234 for( int i = 0; i < 20; ++i ){
235
236 minimizer->SetParameter(0,"alpha",m_alpha,rand->Rndm()*0.001,0.0,0.5);
237 minimizer->SetParameter(1,"gamma",m_gamma,rand->Rndm()*0.001,-2,2);
238 minimizer->SetParameter(2,"delta",m_delta,rand->Rndm()*0.001,-2,2);
239 minimizer->SetParameter(3,"power",m_power,rand->Rndm()*0.01,-5,5);
240 minimizer->SetParameter(4,"ratio",m_ratio,rand->Rndm()*0.01,-100,100);
241
242 int status = minimizer->ExecuteCommand("MIGRAD",arg,1);
243 status = minimizer->ExecuteCommand("MIGRAD",arg,1);
244 minimizer->PrintResults(1,0);
245 std::cout << "Fit status: " << status << std::endl;
246
247 int counter = 0;
248 while( status != 0 && counter < 10 ){
249 counter++;
250
251 minimizer->SetParameter(0,"alpha",m_alpha,rand->Rndm()*0.001,0.0,0.5);
252 minimizer->SetParameter(1,"gamma",m_gamma,rand->Rndm()*0.001,-2,2);
253 minimizer->SetParameter(2,"delta",m_delta,rand->Rndm()*0.001,-2,2);
254 minimizer->SetParameter(3,"power",m_power,rand->Rndm()*0.01,-5,5);
255 minimizer->SetParameter(4,"ratio",m_ratio,rand->Rndm()*0.01,-100,100);
256
257 status = minimizer->ExecuteCommand("MIGRAD",arg,1);
258 std::cout << "Fit status: " << status << std::endl;
259 }
260 if( status != 0 ){
261 std::cout << "HadronSaturation::ERROR - BAD FIT!" << std::endl;
262 return;
263 }
264 }
265
266 for( int par = 0; par < 5; ++par ){
267 fitpar[par] = minimizer->GetParameter(par);
268 fiterr[par] = minimizer->GetParError(par);
269 }
270
271 std::cout << "HadronSaturation: fit results" << std::endl;
272 std::cout << "\t alpha (" << m_alpha << "): " << fitpar[0] << " +- " << fiterr[0] << std::endl;
273 std::cout << "\t gamma (" << m_gamma << "): " << fitpar[1] << " +- " << fiterr[1] << std::endl;
274 std::cout << "\t delta (" << m_delta << "): " << fitpar[2] << " +- " << fiterr[2] << std::endl;
275 std::cout << "\t power (" << m_power << "): " << fitpar[3] << " +- " << fiterr[3] << std::endl;
276 std::cout << "\t ratio (" << m_ratio << "): " << fitpar[4] << " +- " << fiterr[4] << std::endl;
277
278 // function value, estimated distance to minimum, errdef
279 // variable parameters, number of parameters
280 double chi2, edm, errdef;
281 int nvpar, nparx;
282 minimizer->GetStats(chi2,edm,errdef,nvpar,nparx);
283 std::cout << "\t\t Fit chi^2: " << chi2 << std::endl;
284
285 std::ofstream parfile;
286 parfile.open("sat-pars.fit.txt");
287
288 parfile << fitpar[0] << std::endl;
289 parfile << fitpar[1] << std::endl;
290 parfile << fitpar[2] << std::endl;
291 parfile << fitpar[3] << std::endl;
292 parfile << fitpar[4] << std::endl;
293 parfile.close();
294
295 delete minimizer;
296}
297
298void
300
301 m_dedx.clear();
302 m_dedxerror.clear();
303 m_betagamma.clear();
304 m_costheta.clear();
305}
const double delta
Int_t nevt[10]
const DifComplex I
const double alpha
*********Class see also m_nmax DOUBLE PRECISION m_delta
Definition: KarFin.h:12
void printEvents(int firstevent, int nevents)
double myFunction(double alpha, double gamma, double delta, double power, double ratio)
double I2D(double cosTheta, double I, double alpha, double gamma, double delta, double power, double ratio) const
void fillSample(TString infilename)
double D2I(double cosTheta, double D, double alpha, double gamma, double delta, double power, double ratio) const
void setParameters(double par[])
static void minuitFunction(int &nDim, double *gout, double &result, double *para, int flg)
const double b
Definition: slope.cxx:9