|
| 1 | +#include "GlobaldEdxFitter.h" |
| 2 | + |
| 3 | +#include "bethe_bloch.h" |
| 4 | +#include "TF1.h" |
| 5 | +#include "TF2.h" |
| 6 | +#include "TF3.h" |
| 7 | +#include "TChain.h" |
| 8 | +#include "TGraph.h" |
| 9 | +#include "Math/Minimizer.h" |
| 10 | +#include "Math/Functor.h" |
| 11 | +#include "Math/Factory.h" |
| 12 | + |
| 13 | +void GlobaldEdxFitter::processResidualData(const std::string& infile, size_t ntracks, size_t skip) |
| 14 | +{ |
| 15 | + std::unique_ptr<TChain> t = std::make_unique<TChain>(); |
| 16 | + t->Add((infile+"?#residualtree").c_str()); |
| 17 | +// TFile* f = TFile::Open(infile.c_str()); |
| 18 | +// TTree* t = (TTree*)f->Get("residualtree"); |
| 19 | + |
| 20 | + float px; |
| 21 | + float py; |
| 22 | + float pz; |
| 23 | + float dedx; |
| 24 | + float eta; |
| 25 | + int nmaps; |
| 26 | + int nintt; |
| 27 | + int ntpc; |
| 28 | + float dcaxy; |
| 29 | + |
| 30 | + t->SetBranchAddress("px",&px); |
| 31 | + t->SetBranchAddress("py",&py); |
| 32 | + t->SetBranchAddress("pz",&pz); |
| 33 | + t->SetBranchAddress("dedx",&dedx); |
| 34 | + t->SetBranchAddress("eta",&eta); |
| 35 | + t->SetBranchAddress("nmaps",&nmaps); |
| 36 | + t->SetBranchAddress("nintt",&nintt); |
| 37 | + t->SetBranchAddress("ntpc",&ntpc); |
| 38 | + t->SetBranchAddress("dcaxy",&dcaxy); |
| 39 | + |
| 40 | + size_t total_entries = t->GetEntriesFast(); |
| 41 | + |
| 42 | + for(size_t entry=skip; entry<(skip+ntracks); entry++) |
| 43 | + { |
| 44 | + if(entry==total_entries) |
| 45 | + { |
| 46 | + break; |
| 47 | + } |
| 48 | + if(entry % 1000 == 0) |
| 49 | + { |
| 50 | + std::cout << entry << std::endl; |
| 51 | + } |
| 52 | + t->GetEntry(entry); |
| 53 | + if(nmaps>0 && nintt>0 && std::fabs(eta)<1. && dcaxy<0.5 && ntpc>30) |
| 54 | + { |
| 55 | + p.push_back(std::sqrt(px*px+py*py+pz*pz)); |
| 56 | + dEdx.push_back(dedx); |
| 57 | + } |
| 58 | + } |
| 59 | + std::cout << "number of good tracks: " << p.size() << std::endl; |
| 60 | + //f->Close(); |
| 61 | +} |
| 62 | + |
| 63 | +void GlobaldEdxFitter::addTrack(double trk_dEdx, double trk_p) |
| 64 | +{ |
| 65 | + dEdx.push_back(trk_dEdx); |
| 66 | + p.push_back(trk_p); |
| 67 | +} |
| 68 | + |
| 69 | +double GlobaldEdxFitter::get_fitquality_new(double A) |
| 70 | +{ |
| 71 | + //double chi2 = 0.; |
| 72 | + //double ndf = -1.; |
| 73 | + |
| 74 | + double pi_chi2 = 0.; |
| 75 | + double K_chi2 = 0.; |
| 76 | + double p_chi2 = 0.; |
| 77 | + double d_chi2 = 0.; |
| 78 | + double pi_ndf = -1.; |
| 79 | + double K_ndf = -1.; |
| 80 | + double p_ndf = -1.; |
| 81 | + double d_ndf = -1.; |
| 82 | + |
| 83 | + for(size_t i=0; i<dEdx.size(); i++) |
| 84 | + { |
| 85 | + const double dedx_pi = bethe_bloch_new_1D(p[i]/dedx_constants::m_pi,A); |
| 86 | + const double dedx_K = bethe_bloch_new_1D(p[i]/dedx_constants::m_K,A); |
| 87 | + const double dedx_p = bethe_bloch_new_1D(p[i]/dedx_constants::m_p,A); |
| 88 | + const double dedx_d = bethe_bloch_new_1D(p[i]/dedx_constants::m_d,A); |
| 89 | + |
| 90 | + //std::cout << "dedx: (" << dedx_pi << ", " << dedx_K << ", " << dedx_p << ", " << dedx_d << ")" << std::endl; |
| 91 | + //std::cout << "measured: " << dEdx[i] << std::endl; |
| 92 | + |
| 93 | + const double pi_dist = fabs(dEdx[i]-dedx_pi); |
| 94 | + const double K_dist = fabs(dEdx[i]-dedx_K); |
| 95 | + const double p_dist = fabs(dEdx[i]-dedx_p); |
| 96 | + const double d_dist = fabs(dEdx[i]-dedx_d); |
| 97 | + |
| 98 | + //std::cout << "dist: (" << pi_dist << ", " << K_dist << ", " << p_dist << ", " << d_dist << ")" << std::endl; |
| 99 | + |
| 100 | + if(pi_dist<K_dist && pi_dist<p_dist && pi_dist<d_dist) |
| 101 | + { |
| 102 | + //std::cout << "pion" << std::endl; |
| 103 | + //chi2 += pi_dist*pi_dist; |
| 104 | + pi_chi2 += pi_dist*pi_dist; |
| 105 | + pi_ndf += 1.; |
| 106 | + } |
| 107 | + else if(K_dist<pi_dist && K_dist<p_dist && K_dist<d_dist) |
| 108 | + { |
| 109 | + //std::cout << "K" << std::endl; |
| 110 | + //chi2 += K_dist*K_dist; |
| 111 | + K_chi2 += K_dist*K_dist; |
| 112 | + K_ndf += 1.; |
| 113 | + } |
| 114 | + else if(p_dist<pi_dist && p_dist<K_dist && p_dist<d_dist) |
| 115 | + { |
| 116 | + //std::cout << "p" << std::endl; |
| 117 | + //chi2 += p_dist*p_dist; |
| 118 | + p_chi2 += p_dist*p_dist; |
| 119 | + p_ndf += 1.; |
| 120 | + } |
| 121 | + |
| 122 | + else if(d_dist<pi_dist && d_dist<K_dist && d_dist<p_dist) |
| 123 | + { |
| 124 | + //std::cout << "d" << std::endl; |
| 125 | + //chi2 += d_dist*d_dist; |
| 126 | + d_chi2 += d_dist*d_dist; |
| 127 | + d_ndf += 1.; |
| 128 | + } |
| 129 | + |
| 130 | + //ndf += 1.; |
| 131 | + //std::cout << "chi2: " << chi2 << std::endl; |
| 132 | + //std::cout << "ndf: " << ndf << std::endl; |
| 133 | + } |
| 134 | + |
| 135 | + if(pi_ndf<1.) {pi_chi2 = 0.; pi_ndf = 1.;} |
| 136 | + if(K_ndf<1.) {K_chi2 = 0.; K_ndf = 1.;} |
| 137 | + if(p_ndf<1.) {p_chi2 = 0.; p_ndf = 1.;} |
| 138 | + if(d_ndf<1.) {d_chi2 = 0.; d_ndf = 1.;} |
| 139 | + |
| 140 | + const double quality = sqrt((pi_chi2*pi_chi2)/(pi_ndf*pi_ndf)+(K_chi2*K_chi2)/(K_ndf*K_ndf)+(p_chi2*p_chi2)/(p_ndf*p_ndf)+(d_chi2*d_chi2)/(d_ndf*d_ndf)); |
| 141 | + //const double quality = chi2/ndf; |
| 142 | + |
| 143 | + //std::cout << "A: " << A << " quality: " << quality << std::endl; |
| 144 | + |
| 145 | + return quality; |
| 146 | +} |
| 147 | + |
| 148 | +double GlobaldEdxFitter::get_fitquality(double norm, double ZS_loss) |
| 149 | +{ |
| 150 | + float pi_chi2 = 0.; |
| 151 | + float K_chi2 = 0.; |
| 152 | + float p_chi2 = 0.; |
| 153 | + float d_chi2 = 0.; |
| 154 | + float pi_ndf = -1.; |
| 155 | + float K_ndf = -1.; |
| 156 | + float p_ndf = -1.; |
| 157 | + float d_ndf = -1.; |
| 158 | + //float ndf = -1; |
| 159 | + |
| 160 | + for(size_t i=0; i<dEdx.size(); i++) |
| 161 | + { |
| 162 | + |
| 163 | + const float dedx_pi = norm*bethe_bloch_total(p[i]/dedx_constants::m_pi) - ZS_loss; |
| 164 | + const float dedx_K = norm*bethe_bloch_total(p[i]/dedx_constants::m_K) - ZS_loss; |
| 165 | + const float dedx_p = norm*bethe_bloch_total(p[i]/dedx_constants::m_p) - ZS_loss; |
| 166 | + const float dedx_d = norm*bethe_bloch_total(p[i]/dedx_constants::m_d) - ZS_loss; |
| 167 | + |
| 168 | + const float pi_dist = fabs(dedx_pi-dEdx[i]); |
| 169 | + const float K_dist = fabs(dedx_K-dEdx[i]); |
| 170 | + const float p_dist = fabs(dedx_p-dEdx[i]); |
| 171 | + const float d_dist = fabs(dedx_d-dEdx[i]); |
| 172 | + |
| 173 | + if(pi_dist<K_dist && pi_dist<p_dist && pi_dist<d_dist) |
| 174 | + { |
| 175 | + pi_chi2 += pi_dist*pi_dist/std::fabs(dedx_pi); |
| 176 | + pi_ndf += 2.; |
| 177 | + } |
| 178 | + else if(K_dist<pi_dist && K_dist<p_dist && K_dist<d_dist) |
| 179 | + { |
| 180 | + K_chi2 += K_dist*K_dist/std::fabs(dedx_K); |
| 181 | + K_ndf += 2.; |
| 182 | + } |
| 183 | + else if(p_dist<pi_dist && p_dist<K_dist && p_dist<d_dist) |
| 184 | + { |
| 185 | + p_chi2 += p_dist*p_dist/std::fabs(dedx_p); |
| 186 | + p_ndf += 2.; |
| 187 | + } |
| 188 | + else if(d_dist<pi_dist && d_dist<K_dist && d_dist<p_dist) |
| 189 | + { |
| 190 | + d_chi2 += d_dist*d_dist/std::fabs(dedx_d); |
| 191 | + d_ndf += 2.; |
| 192 | + } |
| 193 | + //ndf += 2; |
| 194 | + } |
| 195 | + |
| 196 | + const double quality = std::sqrt((pi_chi2*pi_chi2)/(pi_ndf*pi_ndf) + |
| 197 | + (K_chi2*K_chi2)/(K_ndf*K_ndf) + |
| 198 | + (p_chi2*p_chi2)/(p_ndf*p_ndf) + |
| 199 | + (d_chi2*d_chi2)/(d_ndf*d_ndf)); |
| 200 | + |
| 201 | +/* |
| 202 | + const double quality = sqrt((pi_chi2*pi_chi2 + |
| 203 | + K_chi2*K_chi2 + |
| 204 | + p_chi2*p_chi2) |
| 205 | + /(ndf*ndf)); |
| 206 | +*/ |
| 207 | + //std::cout << "norm: " << norm << " ZS: " << ZS_loss << std::endl; |
| 208 | + //std::cout << "quality: " << quality << std::endl; |
| 209 | + |
| 210 | + return quality; |
| 211 | +} |
| 212 | + |
| 213 | +std::vector<double> GlobaldEdxFitter::get_betagamma(double A) |
| 214 | +{ |
| 215 | + std::vector<double> betagamma; |
| 216 | + for(size_t i=0; i<dEdx.size(); i++) |
| 217 | + { |
| 218 | + const double dedx_pi = bethe_bloch_new_1D(p[i]/dedx_constants::m_pi,A); |
| 219 | + const double dedx_K = bethe_bloch_new_1D(p[i]/dedx_constants::m_K,A); |
| 220 | + const double dedx_p = bethe_bloch_new_1D(p[i]/dedx_constants::m_p,A); |
| 221 | + const double dedx_d = bethe_bloch_new_1D(p[i]/dedx_constants::m_d,A); |
| 222 | + |
| 223 | + //std::cout << "dedx: (" << dedx_pi << ", " << dedx_K << ", " << dedx_p << ", " << dedx_d << ")" << std::endl; |
| 224 | + //std::cout << "measured: " << dEdx[i] << std::endl; |
| 225 | + |
| 226 | + const double pi_dist = fabs(dEdx[i]-dedx_pi); |
| 227 | + const double K_dist = fabs(dEdx[i]-dedx_K); |
| 228 | + const double p_dist = fabs(dEdx[i]-dedx_p); |
| 229 | + const double d_dist = fabs(dEdx[i]-dedx_d); |
| 230 | + |
| 231 | + if(pi_dist<K_dist && pi_dist<p_dist && pi_dist<d_dist) |
| 232 | + { |
| 233 | + betagamma.push_back(p[i]/dedx_constants::m_pi); |
| 234 | + } |
| 235 | + else if(K_dist<pi_dist && K_dist<p_dist && K_dist<d_dist) |
| 236 | + { |
| 237 | + betagamma.push_back(p[i]/dedx_constants::m_K); |
| 238 | + } |
| 239 | + else if(p_dist<pi_dist && p_dist<K_dist && p_dist<d_dist) |
| 240 | + { |
| 241 | + betagamma.push_back(p[i]/dedx_constants::m_p); |
| 242 | + } |
| 243 | + else if(d_dist<pi_dist && d_dist<K_dist && d_dist<p_dist) |
| 244 | + { |
| 245 | + betagamma.push_back(p[i]/dedx_constants::m_d); |
| 246 | + } |
| 247 | + } |
| 248 | + return betagamma; |
| 249 | +} |
| 250 | + |
| 251 | +double GlobaldEdxFitter::get_fitquality_functor(const double* x) |
| 252 | +{ |
| 253 | + return get_fitquality_new(x[0]); |
| 254 | +} |
| 255 | + |
| 256 | +double GlobaldEdxFitter::get_fitquality_wrapper(double* x, double* /* par */) |
| 257 | +{ |
| 258 | + return get_fitquality(x[0]); |
| 259 | +} |
| 260 | + |
| 261 | +double GlobaldEdxFitter::get_fitquality_wrapper_ZS(double* x, double* /* par */) |
| 262 | +{ |
| 263 | + return get_fitquality(x[0],x[1]); |
| 264 | +} |
| 265 | + |
| 266 | +double GlobaldEdxFitter::get_fitquality_wrapper_new(double* x, double* /* par */) |
| 267 | +{ |
| 268 | + return get_fitquality_new(x[0]); |
| 269 | +} |
| 270 | + |
| 271 | +TF3* GlobaldEdxFitter::create_TF3_new(const std::string& name) |
| 272 | +{ |
| 273 | + TF3* f = new TF3(name.c_str(),this,&GlobaldEdxFitter::get_fitquality_wrapper_new,min_norm,max_norm,min_B,max_B,min_ZS,max_ZS,0,"GlobaldEdxFitter","get_fitquality_wrapper_new"); |
| 274 | + return f; |
| 275 | +} |
| 276 | + |
| 277 | +TF1* GlobaldEdxFitter::create_TF1(const std::string& name) |
| 278 | +{ |
| 279 | + TF1* f = new TF1(name.c_str(),this,&GlobaldEdxFitter::get_fitquality_wrapper_new,min_norm,max_norm,0,"GlobaldEdxFitter","get_fitquality_wrapper"); |
| 280 | + return f; |
| 281 | +} |
| 282 | + |
| 283 | +TF2* GlobaldEdxFitter::create_TF2(const std::string& name) |
| 284 | +{ |
| 285 | + TF2* f = new TF2(name.c_str(),this,&GlobaldEdxFitter::get_fitquality_wrapper_ZS,min_norm,max_norm,min_ZS,max_ZS,0,"GlobaldEdxFitter","get_fitquality_wrapper_ZS"); |
| 286 | + return f; |
| 287 | +} |
| 288 | + |
| 289 | +double GlobaldEdxFitter::get_minimum_new() |
| 290 | +{ |
| 291 | +/* |
| 292 | + TF3* f = create_TF3_new("temp"); |
| 293 | + double minA; |
| 294 | + double minB; |
| 295 | + double minC; |
| 296 | + f->GetMinimumXYZ(minA,minB,minC); |
| 297 | + delete f; |
| 298 | + return std::make_tuple(minA,minB,minC); |
| 299 | +*/ |
| 300 | + ROOT::Math::Minimizer* minimizer = ROOT::Math::Factory::CreateMinimizer("Minuit2"); |
| 301 | + minimizer->SetMaxFunctionCalls(1000000); |
| 302 | + minimizer->SetMaxIterations(10000); |
| 303 | + minimizer->SetTolerance(0.1); |
| 304 | + minimizer->SetPrintLevel(1); |
| 305 | + ROOT::Math::Functor f(this,&GlobaldEdxFitter::get_fitquality_functor,1); |
| 306 | + double step[1] = {.01}; |
| 307 | + double variable[1] = {20.}; |
| 308 | + minimizer->SetFunction(f); |
| 309 | + minimizer->SetVariable(0,"A",variable[0],step[0]); |
| 310 | + minimizer->Minimize(); |
| 311 | + const double *xs = minimizer->X(); |
| 312 | + delete minimizer; |
| 313 | + return xs[0]; |
| 314 | +} |
| 315 | + |
| 316 | +double GlobaldEdxFitter::get_minimum() |
| 317 | +{ |
| 318 | + TF1* f = create_TF1("temp"); |
| 319 | + f->SetNpx(1000); |
| 320 | + double minX = f->GetMinimumX(); |
| 321 | + delete f; |
| 322 | + return minX; |
| 323 | +} |
| 324 | + |
| 325 | +std::pair<double,double> GlobaldEdxFitter::get_minimum_ZS() |
| 326 | +{ |
| 327 | + TF2* f = create_TF2("temp"); |
| 328 | + double minX; |
| 329 | + double minY; |
| 330 | + f->GetMinimumXY(minX,minY); |
| 331 | + delete f; |
| 332 | + return std::make_pair(minX,minY); |
| 333 | +} |
| 334 | + |
| 335 | +TGraph* GlobaldEdxFitter::graph_vsbetagamma(double A) |
| 336 | +{ |
| 337 | + std::vector<double> betagamma = get_betagamma(A); |
| 338 | + TGraph* g = new TGraph(dEdx.size(),betagamma.data(),dEdx.data()); |
| 339 | + return g; |
| 340 | +} |
| 341 | + |
| 342 | +TGraph* GlobaldEdxFitter::graph_vsp() |
| 343 | +{ |
| 344 | + TGraph* g = new TGraph(dEdx.size(),p.data(),dEdx.data()); |
| 345 | + return g; |
| 346 | +} |
0 commit comments