9#include <cdc/calibration/CDCdEdx/HadronSaturation.h>
17 m_gamma(0.0019308200),
47 B2INFO(
"\n\t HadronSaturation: filling sample events...\n");
52 std::vector< TString > types;
53 types.push_back(
"pion");
54 types.push_back(
"kaon");
55 types.push_back(
"proton");
56 types.push_back(
"muon");
59 TFile* satFile =
new TFile(infilename);
61 for (
int i = 0; i < int(types.size()); ++i) {
63 TTree* satTree = (TTree*)satFile->Get(types[i]);
64 double satbg, satcosth, satdedx, satdedxerr;
65 satTree->SetBranchAddress(
"bg", &satbg);
66 satTree->SetBranchAddress(
"costh", &satcosth);
67 satTree->SetBranchAddress(
"dedx", &satdedx);
68 satTree->SetBranchAddress(
"dedxerr", &satdedxerr);
71 for (
unsigned int j = 0; j < satTree->GetEntries(); ++j) {
73 if (satdedxerr == 0)
continue;
87 if ((nevents + firstevent) >
int(
m_dedx.size())) nevents =
m_dedx.size();
89 if (firstevent < 0 || (nevents + firstevent) >
int(
m_dedx.size()))
90 B2FATAL(
"HadronSaturation: trying to print events out of range (" <<
m_dedx.size() <<
")");
92 for (
int i = firstevent; i < nevents; ++i)
93 B2INFO(
"\t Event " << i <<
":\t bg = " <<
m_betagamma[i] <<
"\t cos(theta) = " <<
m_costheta[i] <<
"\t dE/dx mean = " <<
99 double power,
double ratio)
101 unsigned int nevt =
m_dedx.size();
103 B2ERROR(
"HadronSaturation::myFunction called with no events!");
108 B2ERROR(
"HadronSaturation::myFunction invalid cosbins = " <<
m_cosbins);
114 std::vector<double> vdedxavg;
119 for (
unsigned int i = 0; i < nevt; i++) {
120 double dedxcor = hadsat.
D2I(
123 alpha, gamma, delta, power, ratio);
125 if (!std::isfinite(dedxcor)) {
126 B2WARNING(
"Non-finite dedxcor at event " << i);
139 if (vdedxavg.empty()) {
140 B2ERROR(
"HadronSaturation::myFunction failed to compute averages!");
145 for (
unsigned int i = 0; i < nevt; i++) {
146 double dedxcor = hadsat.
D2I(
149 alpha, gamma, delta, power, ratio);
151 if (!std::isfinite(dedxcor) ||
m_dedxerror[i] <= 0)
continue;
154 if (j >=
int(vdedxavg.size())) {
155 B2WARNING(
"Index " << j <<
" out of range for vdedxavg!");
159 chisq += pow((dedxcor - vdedxavg[j]) /
m_dedxerror[i], 2);
160 B2INFO(
"\t " << i <<
") " << dedxcor <<
"/" << vdedxavg[j] <<
", error was "
162 ": Final " << chisq);
171 result = HC_obj->
myFunction(par[0], par[1], par[2], par[3], par[4]);
179 B2ERROR(
"HadronSaturation::fitSaturation - no data to fit!");
183 B2INFO(
"\t Performing the hadron saturation fit...");
186 TFitter* minimizer =
new TFitter(5);
189 auto setPar = [&](
int idx,
const char* name,
double val,
double step,
190 double low,
double high,
bool fix =
false) {
191 minimizer->SetParameter(idx, name, val, step, low, high);
192 if (fix) minimizer->FixParameter(idx);
196 setPar(0,
"alpha",
m_alpha, gRandom->Rndm() * 0.001, -5.0, 5.0);
197 setPar(1,
"gamma",
m_gamma, gRandom->Rndm() * 0.001, -5.0, 5.0);
198 setPar(2,
"delta",
m_delta, gRandom->Rndm() * 0.001, 0, 0.50,
true);
199 setPar(3,
"power",
m_power, gRandom->Rndm() * 0.01, 0.05, 2.5);
200 setPar(4,
"ratio",
m_ratio, gRandom->Rndm() * 0.01, 0.5, 2,
true);
206 minimizer->ExecuteCommand(
"SET STRAT", &strategy, 1);
209 minimizer->ExecuteCommand(
"SET ERR", &up, 1);
213 minimizer->ExecuteCommand(
"SET PRINT", arg, 1);
215 double eps_machine(std::numeric_limits<double>::epsilon());
216 minimizer->ExecuteCommand(
"SET EPS", &eps_machine, 1);
219 double maxcalls(5000.), tolerance(0.1);
220 double arglist[] = {maxcalls, tolerance};
221 unsigned int nargs(2);
223 for (
int i = 0; i < 30; ++i) {
225 minimizer->SetParameter(0,
"alpha",
m_alpha, gRandom->Rndm() * 0.001, -5.0, 5.0);
226 minimizer->SetParameter(1,
"gamma",
m_gamma, gRandom->Rndm() * 0.001, -5.0, 5.0);
227 minimizer->SetParameter(2,
"delta",
m_delta, gRandom->Rndm() * 0.001, 0, 0.50);
228 minimizer->SetParameter(3,
"power",
m_power, gRandom->Rndm() * 0.01, 0.05, 2.5);
229 minimizer->SetParameter(4,
"ratio",
m_ratio, gRandom->Rndm() * 0.01, 0.5, 2);
230 minimizer->FixParameter(2);
231 minimizer->FixParameter(4);
234 minimizer->ExecuteCommand(
"MIGRAD", arglist, nargs);
235 minimizer->ExecuteCommand(
"MIGRAD", arglist, nargs);
236 int status = minimizer->ExecuteCommand(
"HESSE", arglist, nargs);
238 minimizer->PrintResults(1, 0);
239 B2INFO(
"\t iter = " << i <<
": Fit status: " << status);
242 while (status != 0 && counter < 5) {
243 minimizer->SetParameter(0,
"alpha",
m_alpha, gRandom->Rndm() * 0.001, -5.0, 5.0);
244 minimizer->SetParameter(1,
"gamma",
m_gamma, gRandom->Rndm() * 0.001, -5.0, 5.0);
245 minimizer->SetParameter(2,
"delta",
m_delta, gRandom->Rndm() * 0.001, 0, 0.50);
246 minimizer->SetParameter(3,
"power",
m_power, gRandom->Rndm() * 0.01, 0.05, 2.5);
247 minimizer->SetParameter(4,
"ratio",
m_ratio, gRandom->Rndm() * 0.01, 0.5, 2);
248 minimizer->FixParameter(2);
250 minimizer->FixParameter(4);
252 minimizer->ExecuteCommand(
"MIGRAD", arglist, nargs);
253 status = minimizer->ExecuteCommand(
"HESSE", arglist, nargs);
254 B2INFO(
"\t re-Fit iter: " << counter <<
", status code: " << status);
258 B2INFO(
"\t HadronSaturation::ERROR - BAD FIT!");
264 double fitpar[5], fiterr[5];
266 for (
int par = 0; par < 5; ++par) {
267 fitpar[par] = minimizer->GetParameter(par);
268 fiterr[par] = minimizer->GetParError(par);
271 B2INFO(
"\t Final Result: HadronSaturation: fit results");
272 B2INFO(
"\t alpha (" <<
m_alpha <<
"): " << fitpar[0] <<
" +- " << fiterr[0]);
273 B2INFO(
"\t gamma (" <<
m_gamma <<
"): " << fitpar[1] <<
" +- " << fiterr[1]);
274 B2INFO(
"\t delta (" <<
m_delta <<
"): " << fitpar[2] <<
" +- " << fiterr[2]);
275 B2INFO(
"\t power (" <<
m_power <<
"): " << fitpar[3] <<
" +- " << fiterr[3]);
276 B2INFO(
"\t ratio (" <<
m_ratio <<
"): " << fitpar[4] <<
" +- " << fiterr[4]);
280 double chi2, edm, errdef;
282 minimizer->GetStats(chi2, edm, errdef, nvpar, nparx);
283 B2INFO(
"\t\t Fit chi^2: " << chi2);
286 std::ofstream parfile(
"sat-pars.fit.txt");
287 if (parfile.is_open()) {
288 for (
int i = 0; i < 5; ++i) parfile << fitpar[i] << std::endl;
291 B2WARNING(
"Unable to open sat-pars.fit.txt for writing fit parameters");
Class to hold the hadron saturation functions.
double I2D(double cosTheta, double I) const
hadron saturation parameterization part 2
double D2I(double cosTheta, double D) const
hadron saturation parameterization part 1
Class to perform the hadron saturation calibration.
std::vector< double > m_costheta
a vector to hold cos(theta) values
double m_delta
the delta parameter for the hadron saturation correction
std::vector< double > m_betagamma
a vector to hold beta-gamma values
double m_ratio
the ratio parameter for the hadron saturation correction
std::vector< double > m_dedx
a vector to hold dE/dx measurements
double m_gamma
the gamma parameter for the hadron saturation correction
double myFunction(double alpha, double gamma, double delta, double power, double ratio)
some helper functions for the hadron saturation correction
std::vector< double > m_dedxerror
a vector to hold dE/dx errors
void printEvents(int firstevent, int nevents)
print a sample of events
void fillSample(TString infilename)
fill the vectors below
HadronSaturation()
Constructor: Sets the description, the properties and the parameters of the algorithm.
double m_alpha
the alpha parameter for the hadron saturation correction
void fitSaturation()
perform the hadron saturation fit
void clear()
clear the vectors
double m_power
the power parameter for the hadron saturation correction
static void minuitFunction(int &, double *, double &result, double *para, int)
functions for the hadron saturation correction
int m_cosbins
the number of cosine bins
Abstract base class for different kinds of events.