332 Float_t fit_range_high, Bool_t use_flat_background,
333 Bool_t use_step, Bool_t use_low_exp_tail,
334 Bool_t use_low_lin_tail, Bool_t use_high_exp_tail) {
336 working_hist_ =
static_cast<TH1 *
>(working_hist->Clone());
339 working_hist_->SetDirectory(
nullptr);
340 fit_range_low_ = fit_range_low;
341 fit_range_high_ = fit_range_high;
342 use_flat_background_ = use_flat_background;
343 use_step_ = use_step;
344 use_low_exp_tail_ = use_low_exp_tail;
345 use_low_lin_tail_ = use_low_lin_tail;
346 use_high_exp_tail_ = use_high_exp_tail;
347 use_manual_init_ = kFALSE;
348 interactive_ = kFALSE;
351 fit_range_low_, fit_range_high_, 12);
353 fit_function_->SetParName(0,
"Mu");
354 fit_function_->SetParName(1,
"Sigma");
355 fit_function_->SetParName(2,
"GausAmplitude");
356 fit_function_->SetParName(3,
"StepAmplitude");
357 fit_function_->SetParName(4,
"LowExpTailAmplitude");
358 fit_function_->SetParName(5,
"LowExpTailRatio");
359 fit_function_->SetParName(6,
"LowLinTailAmplitude");
360 fit_function_->SetParName(7,
"LowLinTailSlope");
361 fit_function_->SetParName(8,
"HighExpTailAmplitude");
362 fit_function_->SetParName(9,
"HighExpTailRatio");
363 fit_function_->SetParName(10,
"BkgConstant");
364 fit_function_->SetParName(11,
"LinBkgSlope");
366 Double_t mu_init = (fit_range_low_ + fit_range_high_) / 2;
367 Double_t range_width = fit_range_high_ - fit_range_low_;
368 Double_t sigma_init = range_width * 0.01;
370 Double_t max_bin = working_hist_->GetMaximumBin();
371 Double_t peak_height = working_hist_->GetBinContent(max_bin);
372 Double_t bkg_estimate = EstimateBackground();
375 fit_function_->SetParLimits(0, fit_range_low_, fit_range_high_);
376 fit_function_->SetParameter(0, mu_init);
377 fit_function_->SetParLimits(1, range_width * 0.001, range_width * 0.5);
378 fit_function_->SetParameter(1, sigma_init);
379 fit_function_->SetParLimits(2, 0, peak_height * 0.999);
380 fit_function_->SetParameter(2, peak_height * 0.999);
383 fit_function_->SetParLimits(3, 0, 0.5);
385 fit_function_->SetParameter(3, 0);
387 fit_function_->FixParameter(3, 0);
390 fit_function_->SetParLimits(4, 0, 0.5);
391 if (use_low_exp_tail_)
392 fit_function_->SetParameter(4, 0.1);
394 fit_function_->FixParameter(4, 0);
396 fit_function_->SetParLimits(5, 1.0, tail_ratio_max_);
397 if (use_low_exp_tail_)
398 fit_function_->SetParameter(5, 1.5);
400 fit_function_->FixParameter(5, 1);
402 fit_function_->SetParLimits(6, 0, 0.5);
403 if (use_low_lin_tail_)
404 fit_function_->SetParameter(6, 0.1);
406 fit_function_->FixParameter(6, 0);
408 fit_function_->SetParLimits(7, -0.1, 0.1);
409 if (use_low_lin_tail_)
410 fit_function_->SetParameter(7, 0);
412 fit_function_->FixParameter(7, 0);
415 fit_function_->SetParLimits(8, 0, 0.5);
416 if (use_high_exp_tail_)
417 fit_function_->SetParameter(8, 0.1);
419 fit_function_->FixParameter(8, 0);
421 fit_function_->SetParLimits(9, 1.0, tail_ratio_max_);
422 if (use_high_exp_tail_)
423 fit_function_->SetParameter(9, 1.5);
425 fit_function_->FixParameter(9, 1);
428 fit_function_->SetParLimits(10, 0, peak_height * 0.999);
429 fit_function_->SetParameter(10, bkg_estimate);
431 if (!use_flat_background_)
432 fit_function_->SetParLimits(11, -1000, 1000);
434 fit_function_->FixParameter(11, 0);
436 std::cout <<
"Fit configuration:" << std::endl;
437 std::cout << std::endl;
438 if (use_flat_background_) {
439 std::cout <<
"Background: FLAT" << std::endl;
441 std::cout <<
"Background: LINEAR" << std::endl;
443 std::cout <<
"Step function: " << (use_step_ ?
"ENABLED" :
"DISABLED")
445 std::cout <<
"Low exponential tail: "
446 << (use_low_exp_tail_ ?
"ENABLED" :
"DISABLED") << std::endl;
447 std::cout <<
"Low linear tail: "
448 << (use_low_lin_tail_ ?
"ENABLED" :
"DISABLED") << std::endl;
449 std::cout <<
"High exponential tail: "
450 << (use_high_exp_tail_ ?
"ENABLED" :
"DISABLED") << std::endl;
617 const TString peak_name,
618 const TString label) {
620 Double_t x_step = (fit_range_high_ - fit_range_low_) / (npts - 1);
623 TGraph *total_graph =
new TGraph(npts);
624 for (Int_t i = 0; i < npts; i++) {
625 Double_t x = fit_range_low_ + i * x_step;
626 total_graph->SetPoint(i, x, fit_function_->Eval(x));
628 total_graph->SetLineColor(kAzure);
629 total_graph->SetLineWidth(line_width);
632 fit_range_low_, fit_range_high_, 2);
633 background->SetParameter(0, fit_function_->GetParameter(10));
634 background->SetParameter(1, fit_function_->GetParameter(11));
636 TGraph *background_graph =
new TGraph(npts);
637 for (Int_t i = 0; i < npts; i++) {
638 Double_t x = fit_range_low_ + i * x_step;
639 background_graph->SetPoint(i, x, background->Eval(x));
641 background_graph->SetLineColor(kGreen);
642 background_graph->SetLineWidth(line_width);
644 std::vector<TGraph *> components;
645 components.push_back(background_graph);
647 Double_t ga = fit_function_->GetParameter(2);
651 peak->SetParameter(0, fit_function_->GetParameter(0));
652 peak->SetParameter(1, fit_function_->GetParameter(1));
653 peak->SetParameter(2, fit_function_->GetParameter(2));
654 TGraph *peak_graph =
new TGraph(npts);
655 for (Int_t i = 0; i < npts; i++) {
656 Double_t x = fit_range_low_ + i * x_step;
657 peak_graph->SetPoint(i, x, peak->Eval(x) + background->Eval(x));
659 peak_graph->SetLineColor(kBlack);
660 peak_graph->SetLineWidth(line_width);
661 components.push_back(peak_graph);
664 if (TMath::Abs(fit_function_->GetParameter(3)) > 1e-6) {
667 step->SetParameter(0, fit_function_->GetParameter(0));
668 step->SetParameter(1, fit_function_->GetParameter(1));
669 step->SetParameter(2, fit_function_->GetParameter(3) * ga);
670 TGraph *step_graph =
new TGraph(npts);
671 for (Int_t i = 0; i < npts; i++) {
672 Double_t x = fit_range_low_ + i * x_step;
673 step_graph->SetPoint(i, x, step->Eval(x) + background->Eval(x));
675 step_graph->SetLineColor(kGray);
676 step_graph->SetLineWidth(line_width);
677 components.push_back(step_graph);
681 if (TMath::Abs(fit_function_->GetParameter(4)) > 1e-6 ||
682 TMath::Abs(fit_function_->GetParameter(6)) > 1e-6) {
684 fit_range_low_, fit_range_high_, 6);
685 low_tail->SetParameter(0, fit_function_->GetParameter(0));
686 low_tail->SetParameter(1, fit_function_->GetParameter(1));
687 low_tail->SetParameter(2, fit_function_->GetParameter(4) * ga);
688 low_tail->SetParameter(3, fit_function_->GetParameter(5));
689 low_tail->SetParameter(4, fit_function_->GetParameter(6) * ga);
690 low_tail->SetParameter(5, fit_function_->GetParameter(7));
691 TGraph *low_tail_graph =
new TGraph(npts);
692 for (Int_t i = 0; i < npts; i++) {
693 Double_t x = fit_range_low_ + i * x_step;
694 low_tail_graph->SetPoint(i, x, low_tail->Eval(x) + background->Eval(x));
696 low_tail_graph->SetLineColor(kRed);
697 low_tail_graph->SetLineWidth(line_width);
698 components.push_back(low_tail_graph);
702 if (TMath::Abs(fit_function_->GetParameter(8)) > 1e-6) {
704 fit_range_low_, fit_range_high_, 4);
705 high_tail->SetParameter(0, fit_function_->GetParameter(0));
706 high_tail->SetParameter(1, fit_function_->GetParameter(1));
707 high_tail->SetParameter(2, fit_function_->GetParameter(8) * ga);
708 high_tail->SetParameter(3, fit_function_->GetParameter(9));
709 TGraph *high_tail_graph =
new TGraph(npts);
710 for (Int_t i = 0; i < npts; i++) {
711 Double_t x = fit_range_low_ + i * x_step;
712 high_tail_graph->SetPoint(i, x, high_tail->Eval(x) + background->Eval(x));
714 high_tail_graph->SetLineColor(kOrange);
715 high_tail_graph->SetLineWidth(line_width);
716 components.push_back(high_tail_graph);
723 working_hist_, total_graph, components, fit_range_low_, fit_range_high_,
724 peak_name +
"_" + input_name,
"fits", label, kTRUE);
727 for (Int_t i = 0; i < (Int_t)components.size(); i++) {
728 delete components[i];
851 const TString peak_name) {
853 results.
peaks.emplace_back();
855 Bool_t fit_valid = kFALSE;
856 Double_t final_chi2 = 0;
859 if (LoadInteractiveParams(input_name, peak_name)) {
860 TFitResultPtr refit = working_hist_->Fit(fit_function_,
"LSMRBENR+");
861 if (refit.Get() && refit->IsValid())
862 final_chi2 = refit->Chi2() / refit->Ndf();
863 else if (fit_function_->GetNDF() > 0)
864 final_chi2 = fit_function_->GetChisquare() / fit_function_->GetNDF();
865 std::cout <<
"Refit from saved params chi2/ndf = " << final_chi2
869 Bool_t was_batch = gROOT->IsBatch();
870 gROOT->SetBatch(kFALSE);
872 fit_range_low_, fit_range_high_, 1,
873 peak_name +
" / " + input_name)) {
874 Double_t rlo_tmp, rhi_tmp;
875 fit_function_->GetRange(rlo_tmp, rhi_tmp);
876 fit_range_low_ = rlo_tmp;
877 fit_range_high_ = rhi_tmp;
878 final_chi2 = fit_function_->GetChisquare() / fit_function_->GetNDF();
879 std::cout <<
"Interactive chi2/ndf = " << final_chi2 << std::endl;
880 SaveInteractiveParams(input_name, peak_name);
883 gROOT->SetBatch(was_batch);
889 fit_function_->FixParameter(3, 0);
890 fit_function_->FixParameter(4, 0);
891 fit_function_->FixParameter(5, 1);
892 fit_function_->FixParameter(6, 0);
893 fit_function_->FixParameter(7, 0);
894 fit_function_->FixParameter(8, 0);
895 fit_function_->FixParameter(9, 1);
897 if (use_flat_background_) {
898 fit_function_->FixParameter(11, 0);
901 if (use_manual_init_) {
902 std::cout <<
"Using manually initialized parameters" << std::endl;
903 for (
size_t i = 0; i < manual_params_.size(); i++) {
904 fit_function_->SetParameter(i, manual_params_[i]);
906 std::cout <<
"Skipping auto-initialization, using provided values"
909 if (!use_flat_background_) {
911 fit_range_low_, fit_range_high_, 2);
912 Double_t exclude_low =
913 fit_function_->GetParameter(0) - 3 * fit_function_->GetParameter(1);
914 working_hist_->Fit(bkg_only,
"QN0R",
"", fit_range_low_, exclude_low);
915 fit_function_->SetParameter(
916 10, ClampToBounds(10, bkg_only->GetParameter(0)));
917 fit_function_->SetParameter(
918 11, ClampToBounds(11, bkg_only->GetParameter(1)));
924 TFitResultPtr initial_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
926 if (!initial_fit.Get() || !initial_fit->IsValid()) {
927 std::cout <<
"ERROR: Initial fit failed" << std::endl;
931 Double_t best_chi2 = initial_fit->Chi2() / initial_fit->Ndf();
932 std::cout <<
"Initial chi2/ndf = " << best_chi2 << std::endl;
934 Double_t gaus_amp = TMath::Abs(fit_function_->GetParameter(2));
935 Double_t peak_height =
936 working_hist_->GetBinContent(working_hist_->GetMaximumBin());
937 Double_t range_width = fit_range_high_ - fit_range_low_;
938 Double_t bkg_estimate = EstimateBackground();
940 std::cout <<
"Background mode: "
941 << (use_flat_background_ ?
"FLAT" :
"LINEAR") << std::endl;
943 Int_t npar = fit_function_->GetNpar();
944 std::vector<Double_t> best_params(npar);
945 std::vector<Double_t> best_errors(npar);
946 for (Int_t i = 0; i < npar; i++) {
947 best_params[i] = fit_function_->GetParameter(i);
948 best_errors[i] = fit_function_->GetParError(i);
952 Bool_t any_low_side = use_step_ || use_low_exp_tail_ || use_low_lin_tail_;
955 std::cout <<
"Testing low-side component group..." << std::endl;
958 fit_function_->ReleaseParameter(3);
959 fit_function_->SetParLimits(3, 0, 0.5);
960 if (!use_manual_init_)
961 fit_function_->SetParameter(3, 0.15);
963 if (use_low_exp_tail_) {
964 fit_function_->ReleaseParameter(4);
965 fit_function_->ReleaseParameter(5);
966 fit_function_->SetParLimits(4, 0, 0.5);
967 fit_function_->SetParLimits(5, 1.0, tail_ratio_max_);
968 if (!use_manual_init_) {
969 fit_function_->SetParameter(4, 0.15);
970 fit_function_->SetParameter(5, 1.5);
973 if (use_low_lin_tail_) {
974 fit_function_->ReleaseParameter(6);
975 fit_function_->ReleaseParameter(7);
976 fit_function_->SetParLimits(6, 0, 0.5);
977 fit_function_->SetParLimits(7, -0.1, 0.1);
978 if (!use_manual_init_) {
979 fit_function_->SetParameter(6, 0.15);
980 fit_function_->SetParameter(7, 0);
984 TFitResultPtr group_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
986 if (group_fit.Get() && group_fit->IsValid()) {
987 Double_t chi2_group = group_fit->Chi2() / group_fit->Ndf();
988 std::cout <<
"Low-side group chi2/ndf: " << chi2_group <<
" vs "
989 << best_chi2 << std::endl;
991 if (chi2_group < best_chi2) {
992 std::cout <<
"Low-side group ACCEPTED, pruning..." << std::endl;
993 best_chi2 = chi2_group;
994 for (Int_t i = 0; i < npar; i++) {
995 best_params[i] = fit_function_->GetParameter(i);
996 best_errors[i] = fit_function_->GetParError(i);
1001 fit_function_->FixParameter(3, 0);
1002 TFitResultPtr prune_fit =
1003 working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1004 if (prune_fit.Get() && prune_fit->IsValid() &&
1005 prune_fit->Chi2() / prune_fit->Ndf() <= best_chi2) {
1006 std::cout <<
" Step pruned (not needed)" << std::endl;
1007 best_chi2 = prune_fit->Chi2() / prune_fit->Ndf();
1008 for (Int_t i = 0; i < npar; i++) {
1009 best_params[i] = fit_function_->GetParameter(i);
1010 best_errors[i] = fit_function_->GetParError(i);
1013 std::cout <<
" Step retained" << std::endl;
1014 fit_function_->ReleaseParameter(3);
1015 fit_function_->SetParLimits(3, 0, 0.5);
1016 for (Int_t i = 0; i < npar; i++) {
1017 fit_function_->SetParameter(i, best_params[i]);
1018 fit_function_->SetParError(i, best_errors[i]);
1024 if (use_low_exp_tail_) {
1025 fit_function_->FixParameter(4, 0);
1026 fit_function_->FixParameter(5, 1);
1027 TFitResultPtr prune_fit =
1028 working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1029 if (prune_fit.Get() && prune_fit->IsValid() &&
1030 prune_fit->Chi2() / prune_fit->Ndf() <= best_chi2) {
1031 std::cout <<
" Low exp tail pruned (not needed)" << std::endl;
1032 best_chi2 = prune_fit->Chi2() / prune_fit->Ndf();
1033 for (Int_t i = 0; i < npar; i++) {
1034 best_params[i] = fit_function_->GetParameter(i);
1035 best_errors[i] = fit_function_->GetParError(i);
1038 std::cout <<
" Low exp tail retained" << std::endl;
1039 fit_function_->ReleaseParameter(4);
1040 fit_function_->ReleaseParameter(5);
1041 fit_function_->SetParLimits(4, 0, 0.5);
1042 fit_function_->SetParLimits(5, 1.0, tail_ratio_max_);
1043 for (Int_t i = 0; i < npar; i++) {
1044 fit_function_->SetParameter(i, best_params[i]);
1045 fit_function_->SetParError(i, best_errors[i]);
1051 if (use_low_lin_tail_) {
1052 fit_function_->FixParameter(6, 0);
1053 fit_function_->FixParameter(7, 0);
1054 TFitResultPtr prune_fit =
1055 working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1056 if (prune_fit.Get() && prune_fit->IsValid() &&
1057 prune_fit->Chi2() / prune_fit->Ndf() <= best_chi2) {
1058 std::cout <<
" Low lin tail pruned (not needed)" << std::endl;
1059 best_chi2 = prune_fit->Chi2() / prune_fit->Ndf();
1060 for (Int_t i = 0; i < npar; i++) {
1061 best_params[i] = fit_function_->GetParameter(i);
1062 best_errors[i] = fit_function_->GetParError(i);
1065 std::cout <<
" Low lin tail retained" << std::endl;
1066 fit_function_->ReleaseParameter(6);
1067 fit_function_->ReleaseParameter(7);
1068 fit_function_->SetParLimits(6, 0, 0.5);
1069 fit_function_->SetParLimits(7, -0.1, 0.1);
1070 for (Int_t i = 0; i < npar; i++) {
1071 fit_function_->SetParameter(i, best_params[i]);
1072 fit_function_->SetParError(i, best_errors[i]);
1077 std::cout <<
"Low-side group REJECTED" << std::endl;
1079 fit_function_->FixParameter(3, 0);
1080 if (use_low_exp_tail_) {
1081 fit_function_->FixParameter(4, 0);
1082 fit_function_->FixParameter(5, 1);
1084 if (use_low_lin_tail_) {
1085 fit_function_->FixParameter(6, 0);
1086 fit_function_->FixParameter(7, 0);
1088 for (Int_t i = 0; i < npar; i++) {
1089 fit_function_->SetParameter(i, best_params[i]);
1090 fit_function_->SetParError(i, best_errors[i]);
1094 std::cout <<
"Low-side group fit FAILED" << std::endl;
1096 fit_function_->FixParameter(3, 0);
1097 if (use_low_exp_tail_) {
1098 fit_function_->FixParameter(4, 0);
1099 fit_function_->FixParameter(5, 1);
1101 if (use_low_lin_tail_) {
1102 fit_function_->FixParameter(6, 0);
1103 fit_function_->FixParameter(7, 0);
1105 for (Int_t i = 0; i < npar; i++) {
1106 fit_function_->SetParameter(i, best_params[i]);
1107 fit_function_->SetParError(i, best_errors[i]);
1113 if (use_high_exp_tail_) {
1114 std::cout <<
"Testing high exponential tail..." << std::endl;
1116 fit_function_->ReleaseParameter(8);
1117 fit_function_->ReleaseParameter(9);
1118 fit_function_->SetParLimits(8, 0, 0.5);
1119 fit_function_->SetParLimits(9, 1.0, tail_ratio_max_);
1121 if (!use_manual_init_) {
1122 fit_function_->SetParameter(8, 0.15);
1123 fit_function_->SetParameter(9, 1.5);
1126 TFitResultPtr htail_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1128 if (htail_fit.Get() && htail_fit->IsValid()) {
1129 Double_t chi2_with_htail = htail_fit->Chi2() / htail_fit->Ndf();
1130 std::cout <<
"Chi2/ndf: " << chi2_with_htail <<
" vs " << best_chi2
1133 if (chi2_with_htail < best_chi2) {
1134 std::cout <<
"High exp tail ACCEPTED" << std::endl;
1135 best_chi2 = chi2_with_htail;
1136 for (Int_t i = 0; i < npar; i++) {
1137 best_params[i] = fit_function_->GetParameter(i);
1138 best_errors[i] = fit_function_->GetParError(i);
1141 std::cout <<
"High exp tail REJECTED" << std::endl;
1142 fit_function_->FixParameter(8, 0);
1143 fit_function_->FixParameter(9, 1);
1144 for (Int_t i = 0; i < npar; i++) {
1145 fit_function_->SetParameter(i, best_params[i]);
1146 fit_function_->SetParError(i, best_errors[i]);
1150 std::cout <<
"High exp tail fit FAILED" << std::endl;
1151 fit_function_->FixParameter(8, 0);
1152 fit_function_->FixParameter(9, 1);
1153 for (Int_t i = 0; i < npar; i++) {
1154 fit_function_->SetParameter(i, best_params[i]);
1155 fit_function_->SetParError(i, best_errors[i]);
1161 std::cout <<
"Final fit with selected components..." << std::endl;
1162 for (Int_t i = 0; i < npar; i++) {
1163 fit_function_->SetParameter(i, best_params[i]);
1164 fit_function_->SetParError(i, best_errors[i]);
1167 if (use_flat_background_) {
1168 fit_function_->FixParameter(11, 0);
1171 TFitResultPtr final_fit = working_hist_->Fit(fit_function_,
"LSMRBENR+");
1173 if (final_fit.Get() && final_fit->IsValid()) {
1174 final_chi2 = final_fit->Chi2() / final_fit->Ndf();
1176 std::cout <<
"Final chi2/ndf = " << final_chi2 << std::endl;
1181 TString chi2label = Form(
"#chi^{2}/ndf = %.3f", final_chi2);
1185 peak.
mu = fit_function_->GetParameter(0);
1186 peak.
mu_error = fit_function_->GetParError(0);
1187 peak.
sigma = fit_function_->GetParameter(1);
1208 results.
peaks[0] = peak;
1209 results.
bkg_constant = fit_function_->GetParameter(10);
1214 results.
valid = kTRUE;
1216 std::cout <<
"ERROR: Fit did not converge" << std::endl;
1223 const TString peak_name,
1224 Double_t mu1_init, Double_t mu2_init) {
1226 results.
peaks.emplace_back();
1227 results.
peaks.emplace_back();
1229 if (mu1_init > mu2_init) {
1230 std::cout <<
"WARNING: mu1_init > mu2_init, swapping initial values"
1232 Double_t temp = mu1_init;
1233 mu1_init = mu2_init;
1237 delete fit_function_;
1239 fit_range_low_, fit_range_high_, 22);
1242 fit_function_->SetParName(0,
"Mu1");
1243 fit_function_->SetParName(1,
"Sigma1");
1244 fit_function_->SetParName(2,
"GausAmplitude1");
1245 fit_function_->SetParName(3,
"StepAmplitude1");
1246 fit_function_->SetParName(4,
"LowExpTailAmplitude1");
1247 fit_function_->SetParName(5,
"LowExpTailRatio1");
1248 fit_function_->SetParName(6,
"LowLinTailAmplitude1");
1249 fit_function_->SetParName(7,
"LowLinTailSlope1");
1250 fit_function_->SetParName(8,
"HighExpTailAmplitude1");
1251 fit_function_->SetParName(9,
"HighExpTailRatio1");
1254 fit_function_->SetParName(10,
"Mu2");
1255 fit_function_->SetParName(11,
"Sigma2");
1256 fit_function_->SetParName(12,
"GausAmplitude2");
1257 fit_function_->SetParName(13,
"StepAmplitude2");
1258 fit_function_->SetParName(14,
"LowExpTailAmplitude2");
1259 fit_function_->SetParName(15,
"LowExpTailRatio2");
1260 fit_function_->SetParName(16,
"LowLinTailAmplitude2");
1261 fit_function_->SetParName(17,
"LowLinTailSlope2");
1262 fit_function_->SetParName(18,
"HighExpTailAmplitude2");
1263 fit_function_->SetParName(19,
"HighExpTailRatio2");
1266 fit_function_->SetParName(20,
"BkgConst");
1267 fit_function_->SetParName(21,
"BkgSlope");
1269 Double_t range_width = fit_range_high_ - fit_range_low_;
1270 Double_t sigma_init = range_width * 0.01;
1271 Double_t peak_height =
1272 working_hist_->GetBinContent(working_hist_->GetMaximumBin());
1273 Double_t bkg_estimate = EstimateBackground();
1276 for (Int_t p = 0; p < 2; p++) {
1278 fit_function_->SetParLimits(o + 0, fit_range_low_, fit_range_high_);
1279 fit_function_->SetParLimits(o + 1, range_width * 0.001, range_width * 0.5);
1280 fit_function_->SetParLimits(o + 2, 0, peak_height * 0.999);
1281 fit_function_->SetParLimits(o + 3, 0, 0.5);
1282 fit_function_->SetParLimits(o + 4, 0, 0.5);
1283 fit_function_->SetParLimits(o + 5, 1.0, tail_ratio_max_);
1284 fit_function_->SetParLimits(o + 6, 0, 0.5);
1285 fit_function_->SetParLimits(o + 7, -0.1, 0.1);
1286 fit_function_->SetParLimits(o + 8, 0, 0.5);
1287 fit_function_->SetParLimits(o + 9, 1.0, tail_ratio_max_);
1290 fit_function_->SetParameter(0, mu1_init);
1291 fit_function_->SetParameter(1, sigma_init);
1292 fit_function_->SetParameter(2, peak_height * 0.999);
1294 fit_function_->SetParameter(10, mu2_init);
1295 fit_function_->SetParameter(11, sigma_init);
1296 fit_function_->SetParameter(12, peak_height * 0.999);
1299 for (Int_t p = 0; p < 2; p++) {
1302 fit_function_->SetParameter(o + 3, 0);
1304 fit_function_->FixParameter(o + 3, 0);
1306 if (use_low_exp_tail_) {
1307 fit_function_->SetParameter(o + 4, 0);
1308 fit_function_->SetParameter(o + 5, 1.5);
1310 fit_function_->FixParameter(o + 4, 0);
1311 fit_function_->FixParameter(o + 5, 1);
1314 if (use_low_lin_tail_) {
1315 fit_function_->SetParameter(o + 6, 0);
1316 fit_function_->SetParameter(o + 7, 0);
1318 fit_function_->FixParameter(o + 6, 0);
1319 fit_function_->FixParameter(o + 7, 0);
1322 if (use_high_exp_tail_) {
1323 fit_function_->SetParameter(o + 8, 0);
1324 fit_function_->SetParameter(o + 9, 1.5);
1326 fit_function_->FixParameter(o + 8, 0);
1327 fit_function_->FixParameter(o + 9, 1);
1332 fit_function_->SetParLimits(20, 0, peak_height * 0.999);
1333 if (!use_flat_background_) {
1334 fit_function_->SetParLimits(21, -0.1 * bkg_estimate / range_width,
1335 0.1 * bkg_estimate / range_width);
1337 fit_function_->SetParameter(20, bkg_estimate);
1338 fit_function_->SetParameter(21, 0);
1339 if (use_flat_background_) {
1340 fit_function_->FixParameter(21, 0);
1343 Bool_t fit_valid = kFALSE;
1344 Double_t final_chi2 = 0;
1347 if (LoadInteractiveParams(input_name, peak_name)) {
1348 TFitResultPtr refit = working_hist_->Fit(fit_function_,
"LSMRBENR+");
1349 if (refit.Get() && refit->IsValid())
1350 final_chi2 = refit->Chi2() / refit->Ndf();
1351 else if (fit_function_->GetNDF() > 0)
1352 final_chi2 = fit_function_->GetChisquare() / fit_function_->GetNDF();
1353 std::cout <<
"Refit from saved params chi2/ndf = " << final_chi2
1357 Bool_t was_batch = gROOT->IsBatch();
1358 gROOT->SetBatch(kFALSE);
1360 fit_range_low_, fit_range_high_, 2,
1361 peak_name +
" / " + input_name)) {
1362 Double_t rlo_tmp, rhi_tmp;
1363 fit_function_->GetRange(rlo_tmp, rhi_tmp);
1364 fit_range_low_ = rlo_tmp;
1365 fit_range_high_ = rhi_tmp;
1366 final_chi2 = fit_function_->GetChisquare() / fit_function_->GetNDF();
1367 std::cout <<
"Interactive chi2/ndf = " << final_chi2 << std::endl;
1368 SaveInteractiveParams(input_name, peak_name);
1371 gROOT->SetBatch(was_batch);
1375 fit_function_->FixParameter(3, 0);
1376 fit_function_->FixParameter(4, 0);
1377 fit_function_->FixParameter(5, 1);
1378 fit_function_->FixParameter(6, 0);
1379 fit_function_->FixParameter(7, 0);
1380 fit_function_->FixParameter(8, 0);
1381 fit_function_->FixParameter(9, 1);
1382 fit_function_->FixParameter(13, 0);
1383 fit_function_->FixParameter(14, 0);
1384 fit_function_->FixParameter(15, 1);
1385 fit_function_->FixParameter(16, 0);
1386 fit_function_->FixParameter(17, 0);
1387 fit_function_->FixParameter(18, 0);
1388 fit_function_->FixParameter(19, 1);
1391 TFitResultPtr initial_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1393 if (!initial_fit.Get() || !initial_fit->IsValid()) {
1394 std::cout <<
"ERROR: Initial double peak fit failed" << std::endl;
1398 Double_t gaus_amp1 = TMath::Abs(fit_function_->GetParameter(2));
1399 Double_t gaus_amp2 = TMath::Abs(fit_function_->GetParameter(12));
1401 Int_t npar = fit_function_->GetNpar();
1402 std::vector<Double_t> best_params(npar);
1403 std::vector<Double_t> best_errors(npar);
1404 for (Int_t i = 0; i < npar; i++) {
1405 best_params[i] = fit_function_->GetParameter(i);
1406 best_errors[i] = fit_function_->GetParError(i);
1409 Double_t best_chi2 = initial_fit->Chi2() / initial_fit->Ndf();
1410 std::cout <<
"Initial chi2/ndf = " << best_chi2 << std::endl;
1414 std::cout <<
"Testing low-side group for peak1..." << std::endl;
1416 fit_function_->ReleaseParameter(3);
1417 fit_function_->SetParLimits(3, 0, 0.5);
1418 fit_function_->SetParameter(3, 0.15);
1420 fit_function_->ReleaseParameter(4);
1421 fit_function_->ReleaseParameter(5);
1422 fit_function_->SetParLimits(4, 0, 0.5);
1423 fit_function_->SetParLimits(5, 1.0, tail_ratio_max_);
1424 fit_function_->SetParameter(4, 0.15);
1425 fit_function_->SetParameter(5, 1.5);
1427 fit_function_->ReleaseParameter(6);
1428 fit_function_->ReleaseParameter(7);
1429 fit_function_->SetParLimits(6, 0, 0.5);
1430 fit_function_->SetParLimits(7, -0.1, 0.1);
1431 fit_function_->SetParameter(6, 0.15);
1432 fit_function_->SetParameter(7, 0);
1434 TFitResultPtr group_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1436 if (group_fit.Get() && group_fit->IsValid() &&
1437 group_fit->Chi2() / group_fit->Ndf() < best_chi2) {
1438 std::cout <<
"Low-side group peak1 ACCEPTED, pruning..." << std::endl;
1439 best_chi2 = group_fit->Chi2() / group_fit->Ndf();
1440 for (Int_t i = 0; i < npar; i++) {
1441 best_params[i] = fit_function_->GetParameter(i);
1442 best_errors[i] = fit_function_->GetParError(i);
1446 fit_function_->FixParameter(3, 0);
1447 TFitResultPtr p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1448 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
1449 std::cout <<
" Step1 pruned" << std::endl;
1450 best_chi2 = p->Chi2() / p->Ndf();
1451 for (Int_t i = 0; i < npar; i++) {
1452 best_params[i] = fit_function_->GetParameter(i);
1453 best_errors[i] = fit_function_->GetParError(i);
1456 fit_function_->ReleaseParameter(3);
1457 fit_function_->SetParLimits(3, 0, 0.5);
1458 for (Int_t i = 0; i < npar; i++) {
1459 fit_function_->SetParameter(i, best_params[i]);
1460 fit_function_->SetParError(i, best_errors[i]);
1465 fit_function_->FixParameter(4, 0);
1466 fit_function_->FixParameter(5, 1);
1467 p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1468 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
1469 std::cout <<
" LowExpTail1 pruned" << std::endl;
1470 best_chi2 = p->Chi2() / p->Ndf();
1471 for (Int_t i = 0; i < npar; i++) {
1472 best_params[i] = fit_function_->GetParameter(i);
1473 best_errors[i] = fit_function_->GetParError(i);
1476 fit_function_->ReleaseParameter(4);
1477 fit_function_->ReleaseParameter(5);
1478 fit_function_->SetParLimits(4, 0, 0.5);
1479 fit_function_->SetParLimits(5, 1.0, tail_ratio_max_);
1480 for (Int_t i = 0; i < npar; i++) {
1481 fit_function_->SetParameter(i, best_params[i]);
1482 fit_function_->SetParError(i, best_errors[i]);
1487 fit_function_->FixParameter(6, 0);
1488 fit_function_->FixParameter(7, 0);
1489 p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1490 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
1491 std::cout <<
" LowLinTail1 pruned" << std::endl;
1492 best_chi2 = p->Chi2() / p->Ndf();
1493 for (Int_t i = 0; i < npar; i++) {
1494 best_params[i] = fit_function_->GetParameter(i);
1495 best_errors[i] = fit_function_->GetParError(i);
1498 fit_function_->ReleaseParameter(6);
1499 fit_function_->ReleaseParameter(7);
1500 fit_function_->SetParLimits(6, 0, 0.5);
1501 fit_function_->SetParLimits(7, -0.1, 0.1);
1502 for (Int_t i = 0; i < npar; i++) {
1503 fit_function_->SetParameter(i, best_params[i]);
1504 fit_function_->SetParError(i, best_errors[i]);
1508 std::cout <<
"Low-side group peak1 REJECTED" << std::endl;
1509 fit_function_->FixParameter(3, 0);
1510 fit_function_->FixParameter(4, 0);
1511 fit_function_->FixParameter(5, 1);
1512 fit_function_->FixParameter(6, 0);
1513 fit_function_->FixParameter(7, 0);
1514 for (Int_t i = 0; i < npar; i++) {
1515 fit_function_->SetParameter(i, best_params[i]);
1516 fit_function_->SetParError(i, best_errors[i]);
1523 std::cout <<
"Testing high tail for peak2..." << std::endl;
1524 fit_function_->ReleaseParameter(18);
1525 fit_function_->ReleaseParameter(19);
1526 fit_function_->SetParLimits(18, 0, 0.5);
1527 fit_function_->SetParLimits(19, 1.0, tail_ratio_max_);
1528 fit_function_->SetParameter(18, 0.15);
1529 fit_function_->SetParameter(19, 1.5);
1531 TFitResultPtr ht_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1532 if (ht_fit.Get() && ht_fit->IsValid() &&
1533 ht_fit->Chi2() / ht_fit->Ndf() < best_chi2) {
1534 std::cout <<
"HighTail2 ACCEPTED" << std::endl;
1535 best_chi2 = ht_fit->Chi2() / ht_fit->Ndf();
1536 for (Int_t i = 0; i < npar; i++) {
1537 best_params[i] = fit_function_->GetParameter(i);
1538 best_errors[i] = fit_function_->GetParError(i);
1541 std::cout <<
"HighTail2 REJECTED" << std::endl;
1542 fit_function_->FixParameter(18, 0);
1543 fit_function_->FixParameter(19, 1);
1544 for (Int_t i = 0; i < npar; i++) {
1545 fit_function_->SetParameter(i, best_params[i]);
1546 fit_function_->SetParError(i, best_errors[i]);
1555 <<
"Testing inter-peak group (peak1 high tail + peak2 low-side)..."
1559 fit_function_->ReleaseParameter(8);
1560 fit_function_->ReleaseParameter(9);
1561 fit_function_->SetParLimits(8, 0, 0.5);
1562 fit_function_->SetParLimits(9, 1.0, tail_ratio_max_);
1563 fit_function_->SetParameter(8, 0.15);
1564 fit_function_->SetParameter(9, 1.5);
1567 fit_function_->ReleaseParameter(13);
1568 fit_function_->SetParLimits(13, 0, 0.5);
1569 fit_function_->SetParameter(13, 0.15);
1571 fit_function_->ReleaseParameter(14);
1572 fit_function_->ReleaseParameter(15);
1573 fit_function_->SetParLimits(14, 0, 0.5);
1574 fit_function_->SetParLimits(15, 1.0, tail_ratio_max_);
1575 fit_function_->SetParameter(14, 0.15);
1576 fit_function_->SetParameter(15, 1.5);
1578 fit_function_->ReleaseParameter(16);
1579 fit_function_->ReleaseParameter(17);
1580 fit_function_->SetParLimits(16, 0, 0.5);
1581 fit_function_->SetParLimits(17, -0.1, 0.1);
1582 fit_function_->SetParameter(16, 0.15);
1583 fit_function_->SetParameter(17, 0);
1585 TFitResultPtr group_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1587 if (group_fit.Get() && group_fit->IsValid() &&
1588 group_fit->Chi2() / group_fit->Ndf() < best_chi2) {
1589 std::cout <<
"Inter-peak group ACCEPTED, pruning..." << std::endl;
1590 best_chi2 = group_fit->Chi2() / group_fit->Ndf();
1591 for (Int_t i = 0; i < npar; i++) {
1592 best_params[i] = fit_function_->GetParameter(i);
1593 best_errors[i] = fit_function_->GetParError(i);
1597 fit_function_->FixParameter(8, 0);
1598 fit_function_->FixParameter(9, 1);
1599 TFitResultPtr p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1600 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
1601 std::cout <<
" HighTail1 pruned" << std::endl;
1602 best_chi2 = p->Chi2() / p->Ndf();
1603 for (Int_t i = 0; i < npar; i++) {
1604 best_params[i] = fit_function_->GetParameter(i);
1605 best_errors[i] = fit_function_->GetParError(i);
1608 fit_function_->ReleaseParameter(8);
1609 fit_function_->ReleaseParameter(9);
1610 fit_function_->SetParLimits(8, 0, 0.5);
1611 fit_function_->SetParLimits(9, 1.0, tail_ratio_max_);
1612 for (Int_t i = 0; i < npar; i++) {
1613 fit_function_->SetParameter(i, best_params[i]);
1614 fit_function_->SetParError(i, best_errors[i]);
1619 fit_function_->FixParameter(13, 0);
1620 p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1621 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
1622 std::cout <<
" Step2 pruned" << std::endl;
1623 best_chi2 = p->Chi2() / p->Ndf();
1624 for (Int_t i = 0; i < npar; i++) {
1625 best_params[i] = fit_function_->GetParameter(i);
1626 best_errors[i] = fit_function_->GetParError(i);
1629 fit_function_->ReleaseParameter(13);
1630 fit_function_->SetParLimits(13, 0, 0.5);
1631 for (Int_t i = 0; i < npar; i++) {
1632 fit_function_->SetParameter(i, best_params[i]);
1633 fit_function_->SetParError(i, best_errors[i]);
1638 fit_function_->FixParameter(14, 0);
1639 fit_function_->FixParameter(15, 1);
1640 p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1641 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
1642 std::cout <<
" LowExpTail2 pruned" << std::endl;
1643 best_chi2 = p->Chi2() / p->Ndf();
1644 for (Int_t i = 0; i < npar; i++) {
1645 best_params[i] = fit_function_->GetParameter(i);
1646 best_errors[i] = fit_function_->GetParError(i);
1649 fit_function_->ReleaseParameter(14);
1650 fit_function_->ReleaseParameter(15);
1651 fit_function_->SetParLimits(14, 0, 0.5);
1652 fit_function_->SetParLimits(15, 1.0, tail_ratio_max_);
1653 for (Int_t i = 0; i < npar; i++) {
1654 fit_function_->SetParameter(i, best_params[i]);
1655 fit_function_->SetParError(i, best_errors[i]);
1660 fit_function_->FixParameter(16, 0);
1661 fit_function_->FixParameter(17, 0);
1662 p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1663 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
1664 std::cout <<
" LowLinTail2 pruned" << std::endl;
1665 best_chi2 = p->Chi2() / p->Ndf();
1666 for (Int_t i = 0; i < npar; i++) {
1667 best_params[i] = fit_function_->GetParameter(i);
1668 best_errors[i] = fit_function_->GetParError(i);
1671 fit_function_->ReleaseParameter(16);
1672 fit_function_->ReleaseParameter(17);
1673 fit_function_->SetParLimits(16, 0, 0.5);
1674 fit_function_->SetParLimits(17, -0.1, 0.1);
1675 for (Int_t i = 0; i < npar; i++) {
1676 fit_function_->SetParameter(i, best_params[i]);
1677 fit_function_->SetParError(i, best_errors[i]);
1681 std::cout <<
"Inter-peak group REJECTED" << std::endl;
1682 fit_function_->FixParameter(8, 0);
1683 fit_function_->FixParameter(9, 1);
1684 fit_function_->FixParameter(13, 0);
1685 fit_function_->FixParameter(14, 0);
1686 fit_function_->FixParameter(15, 1);
1687 fit_function_->FixParameter(16, 0);
1688 fit_function_->FixParameter(17, 0);
1689 for (Int_t i = 0; i < npar; i++) {
1690 fit_function_->SetParameter(i, best_params[i]);
1691 fit_function_->SetParError(i, best_errors[i]);
1697 std::cout <<
"Final fit with selected components..." << std::endl;
1698 for (Int_t i = 0; i < npar; i++) {
1699 fit_function_->SetParameter(i, best_params[i]);
1700 fit_function_->SetParError(i, best_errors[i]);
1702 if (use_flat_background_) {
1703 fit_function_->FixParameter(21, 0);
1706 TFitResultPtr fit_result = working_hist_->Fit(fit_function_,
"LSMRBENR+");
1708 if (fit_result.Get() && fit_result->IsValid()) {
1709 final_chi2 = fit_result->Chi2() / fit_result->Ndf();
1710 std::cout <<
"Double peak fit converged successfully" << std::endl;
1711 std::cout <<
"Final chi2/ndf = " << final_chi2 << std::endl;
1714 std::cout <<
"ERROR: Double peak fit failed to converge" << std::endl;
1721 TString chi2label = Form(
"#chi^{2}/ndf = %.3f", final_chi2);
1724 for (Int_t pk = 0; pk < 2; pk++) {
1727 p.
mu = fit_function_->GetParameter(o + 0);
1728 p.
mu_error = fit_function_->GetParError(o + 0);
1729 p.
sigma = fit_function_->GetParameter(o + 1);
1730 p.
sigma_error = fit_function_->GetParError(o + 1);
1749 results.
peaks[pk] = p;
1752 results.
bkg_constant = fit_function_->GetParameter(20);
1757 results.
valid = kTRUE;
1759 std::cout <<
"ERROR: Double peak fit failed" << std::endl;
1766 const TString peak_name,
1768 Double_t mu2_init) {
1770 results.
peaks.emplace_back();
1771 results.
peaks.emplace_back();
1773 delete fit_function_;
1775 fit_range_low_, fit_range_high_, 22);
1778 fit_function_->SetParName(0,
"Mu1");
1779 fit_function_->SetParName(1,
"Sigma1");
1780 fit_function_->SetParName(2,
"GausAmplitude1");
1781 fit_function_->SetParName(3,
"StepAmplitude1");
1782 fit_function_->SetParName(4,
"LowExpTailAmplitude1");
1783 fit_function_->SetParName(5,
"LowExpTailRatio1");
1784 fit_function_->SetParName(6,
"LowLinTailAmplitude1");
1785 fit_function_->SetParName(7,
"LowLinTailSlope1");
1786 fit_function_->SetParName(8,
"HighExpTailAmplitude1");
1787 fit_function_->SetParName(9,
"HighExpTailRatio1");
1790 fit_function_->SetParName(10,
"Mu2");
1791 fit_function_->SetParName(11,
"Sigma2");
1792 fit_function_->SetParName(12,
"GausAmplitude2");
1793 fit_function_->SetParName(13,
"StepAmplitude2");
1794 fit_function_->SetParName(14,
"LowExpTailAmplitude2");
1795 fit_function_->SetParName(15,
"LowExpTailRatio2");
1796 fit_function_->SetParName(16,
"LowLinTailAmplitude2");
1797 fit_function_->SetParName(17,
"LowLinTailSlope2");
1798 fit_function_->SetParName(18,
"HighExpTailAmplitude2");
1799 fit_function_->SetParName(19,
"HighExpTailRatio2");
1801 fit_function_->SetParName(20,
"BkgConst");
1802 fit_function_->SetParName(21,
"BkgSlope");
1804 Double_t range_width = fit_range_high_ - fit_range_low_;
1805 Double_t sigma_init = range_width * 0.01;
1806 Double_t peak_height =
1807 working_hist_->GetBinContent(working_hist_->GetMaximumBin());
1808 Double_t bkg_estimate = EstimateBackground();
1816 fit_function_->FixParameter(0, cp.
mu);
1817 fit_function_->FixParameter(1, cp.
sigma);
1819 fit_function_->SetParLimits(2, 0, peak_height * 2);
1823 fit_function_->FixParameter(4,
1825 fit_function_->FixParameter(
1827 fit_function_->FixParameter(6,
1831 fit_function_->FixParameter(8,
1833 fit_function_->FixParameter(
1838 fit_function_->SetParLimits(10, fit_range_low_, fit_range_high_);
1839 fit_function_->SetParLimits(11, range_width * 0.001, range_width * 0.5);
1840 fit_function_->SetParLimits(12, 0, peak_height * 0.999);
1841 fit_function_->SetParLimits(13, 0, 0.5);
1842 fit_function_->SetParLimits(14, 0, 0.5);
1843 fit_function_->SetParLimits(15, 1.0, tail_ratio_max_);
1844 fit_function_->SetParLimits(16, 0, 0.5);
1845 fit_function_->SetParLimits(17, -0.1, 0.1);
1846 fit_function_->SetParLimits(18, 0, 0.5);
1847 fit_function_->SetParLimits(19, 1.0, tail_ratio_max_);
1849 fit_function_->SetParameter(10, mu2_init);
1850 fit_function_->SetParameter(11, sigma_init);
1851 fit_function_->SetParameter(12, peak_height * 0.999);
1855 fit_function_->SetParameter(13, 0);
1857 fit_function_->FixParameter(13, 0);
1859 if (use_low_exp_tail_) {
1860 fit_function_->SetParameter(14, 0);
1861 fit_function_->SetParameter(15, 1.5);
1863 fit_function_->FixParameter(14, 0);
1864 fit_function_->FixParameter(15, 1);
1867 if (use_low_lin_tail_) {
1868 fit_function_->SetParameter(16, 0);
1869 fit_function_->SetParameter(17, 0);
1871 fit_function_->FixParameter(16, 0);
1872 fit_function_->FixParameter(17, 0);
1875 if (use_high_exp_tail_) {
1876 fit_function_->SetParameter(18, 0);
1877 fit_function_->SetParameter(19, 1.5);
1879 fit_function_->FixParameter(18, 0);
1880 fit_function_->FixParameter(19, 1);
1884 fit_function_->SetParLimits(20, 0, peak_height * 0.999);
1885 if (!use_flat_background_) {
1886 fit_function_->SetParLimits(21, -0.1 * bkg_estimate / range_width,
1887 0.1 * bkg_estimate / range_width);
1889 fit_function_->SetParameter(20, bkg_estimate);
1890 fit_function_->SetParameter(21, 0);
1891 if (use_flat_background_) {
1892 fit_function_->FixParameter(21, 0);
1895 Bool_t fit_valid = kFALSE;
1896 Double_t final_chi2 = 0;
1899 if (LoadInteractiveParams(input_name, peak_name)) {
1900 TFitResultPtr refit = working_hist_->Fit(fit_function_,
"LSMRBENR+");
1901 if (refit.Get() && refit->IsValid())
1902 final_chi2 = refit->Chi2() / refit->Ndf();
1903 else if (fit_function_->GetNDF() > 0)
1904 final_chi2 = fit_function_->GetChisquare() / fit_function_->GetNDF();
1905 std::cout <<
"Refit from saved params chi2/ndf = " << final_chi2
1909 Bool_t was_batch = gROOT->IsBatch();
1910 gROOT->SetBatch(kFALSE);
1912 fit_range_low_, fit_range_high_, 2,
1913 peak_name +
" / " + input_name)) {
1914 Double_t rlo_tmp, rhi_tmp;
1915 fit_function_->GetRange(rlo_tmp, rhi_tmp);
1916 fit_range_low_ = rlo_tmp;
1917 fit_range_high_ = rhi_tmp;
1918 final_chi2 = fit_function_->GetChisquare() / fit_function_->GetNDF();
1919 std::cout <<
"Interactive chi2/ndf = " << final_chi2 << std::endl;
1920 SaveInteractiveParams(input_name, peak_name);
1923 gROOT->SetBatch(was_batch);
1927 fit_function_->FixParameter(13, 0);
1928 fit_function_->FixParameter(14, 0);
1929 fit_function_->FixParameter(15, 1);
1930 fit_function_->FixParameter(16, 0);
1931 fit_function_->FixParameter(17, 0);
1932 fit_function_->FixParameter(18, 0);
1933 fit_function_->FixParameter(19, 1);
1936 TFitResultPtr initial_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1938 if (!initial_fit.Get() || !initial_fit->IsValid()) {
1939 std::cout <<
"ERROR: Initial double peak fit (constrained) failed"
1944 Double_t gaus_amp2 = TMath::Abs(fit_function_->GetParameter(12));
1946 Int_t npar = fit_function_->GetNpar();
1947 std::vector<Double_t> best_params(npar);
1948 std::vector<Double_t> best_errors(npar);
1949 for (Int_t i = 0; i < npar; i++) {
1950 best_params[i] = fit_function_->GetParameter(i);
1951 best_errors[i] = fit_function_->GetParError(i);
1954 Double_t best_chi2 = initial_fit->Chi2() / initial_fit->Ndf();
1955 std::cout <<
"Initial chi2/ndf = " << best_chi2 << std::endl;
1959 std::cout <<
"Testing low-side group for peak2..." << std::endl;
1961 fit_function_->ReleaseParameter(13);
1962 fit_function_->SetParLimits(13, 0, 0.5);
1963 fit_function_->SetParameter(13, 0.15);
1965 fit_function_->ReleaseParameter(14);
1966 fit_function_->ReleaseParameter(15);
1967 fit_function_->SetParLimits(14, 0, 0.5);
1968 fit_function_->SetParLimits(15, 1.0, tail_ratio_max_);
1969 fit_function_->SetParameter(14, 0.15);
1970 fit_function_->SetParameter(15, 1.5);
1972 fit_function_->ReleaseParameter(16);
1973 fit_function_->ReleaseParameter(17);
1974 fit_function_->SetParLimits(16, 0, 0.5);
1975 fit_function_->SetParLimits(17, -0.1, 0.1);
1976 fit_function_->SetParameter(16, 0.15);
1977 fit_function_->SetParameter(17, 0);
1979 TFitResultPtr group_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1981 if (group_fit.Get() && group_fit->IsValid() &&
1982 group_fit->Chi2() / group_fit->Ndf() < best_chi2) {
1983 std::cout <<
"Low-side group peak2 ACCEPTED, pruning..." << std::endl;
1984 best_chi2 = group_fit->Chi2() / group_fit->Ndf();
1985 for (Int_t i = 0; i < npar; i++) {
1986 best_params[i] = fit_function_->GetParameter(i);
1987 best_errors[i] = fit_function_->GetParError(i);
1991 fit_function_->FixParameter(13, 0);
1992 TFitResultPtr p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
1993 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
1994 std::cout <<
" Step2 pruned" << std::endl;
1995 best_chi2 = p->Chi2() / p->Ndf();
1996 for (Int_t i = 0; i < npar; i++) {
1997 best_params[i] = fit_function_->GetParameter(i);
1998 best_errors[i] = fit_function_->GetParError(i);
2001 fit_function_->ReleaseParameter(13);
2002 fit_function_->SetParLimits(13, 0, 0.5);
2003 for (Int_t i = 0; i < npar; i++) {
2004 fit_function_->SetParameter(i, best_params[i]);
2005 fit_function_->SetParError(i, best_errors[i]);
2010 fit_function_->FixParameter(14, 0);
2011 fit_function_->FixParameter(15, 1);
2012 p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
2013 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
2014 std::cout <<
" LowExpTail2 pruned" << std::endl;
2015 best_chi2 = p->Chi2() / p->Ndf();
2016 for (Int_t i = 0; i < npar; i++) {
2017 best_params[i] = fit_function_->GetParameter(i);
2018 best_errors[i] = fit_function_->GetParError(i);
2021 fit_function_->ReleaseParameter(14);
2022 fit_function_->ReleaseParameter(15);
2023 fit_function_->SetParLimits(14, 0, 0.5);
2024 fit_function_->SetParLimits(15, 1.0, tail_ratio_max_);
2025 for (Int_t i = 0; i < npar; i++) {
2026 fit_function_->SetParameter(i, best_params[i]);
2027 fit_function_->SetParError(i, best_errors[i]);
2032 fit_function_->FixParameter(16, 0);
2033 fit_function_->FixParameter(17, 0);
2034 p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
2035 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
2036 std::cout <<
" LowLinTail2 pruned" << std::endl;
2037 best_chi2 = p->Chi2() / p->Ndf();
2038 for (Int_t i = 0; i < npar; i++) {
2039 best_params[i] = fit_function_->GetParameter(i);
2040 best_errors[i] = fit_function_->GetParError(i);
2043 fit_function_->ReleaseParameter(16);
2044 fit_function_->ReleaseParameter(17);
2045 fit_function_->SetParLimits(16, 0, 0.5);
2046 fit_function_->SetParLimits(17, -0.1, 0.1);
2047 for (Int_t i = 0; i < npar; i++) {
2048 fit_function_->SetParameter(i, best_params[i]);
2049 fit_function_->SetParError(i, best_errors[i]);
2053 std::cout <<
"Low-side group peak2 REJECTED" << std::endl;
2054 fit_function_->FixParameter(13, 0);
2055 fit_function_->FixParameter(14, 0);
2056 fit_function_->FixParameter(15, 1);
2057 fit_function_->FixParameter(16, 0);
2058 fit_function_->FixParameter(17, 0);
2059 for (Int_t i = 0; i < npar; i++) {
2060 fit_function_->SetParameter(i, best_params[i]);
2061 fit_function_->SetParError(i, best_errors[i]);
2068 std::cout <<
"Testing high tail for peak2..." << std::endl;
2069 fit_function_->ReleaseParameter(18);
2070 fit_function_->ReleaseParameter(19);
2071 fit_function_->SetParLimits(18, 0, 0.5);
2072 fit_function_->SetParLimits(19, 1.0, tail_ratio_max_);
2073 fit_function_->SetParameter(18, 0.15);
2074 fit_function_->SetParameter(19, 1.5);
2076 TFitResultPtr ht_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
2077 if (ht_fit.Get() && ht_fit->IsValid() &&
2078 ht_fit->Chi2() / ht_fit->Ndf() < best_chi2) {
2079 std::cout <<
"HighTail2 ACCEPTED" << std::endl;
2080 best_chi2 = ht_fit->Chi2() / ht_fit->Ndf();
2081 for (Int_t i = 0; i < npar; i++) {
2082 best_params[i] = fit_function_->GetParameter(i);
2083 best_errors[i] = fit_function_->GetParError(i);
2086 std::cout <<
"HighTail2 REJECTED" << std::endl;
2087 fit_function_->FixParameter(18, 0);
2088 fit_function_->FixParameter(19, 1);
2089 for (Int_t i = 0; i < npar; i++) {
2090 fit_function_->SetParameter(i, best_params[i]);
2091 fit_function_->SetParError(i, best_errors[i]);
2097 std::cout <<
"Final fit with selected components..." << std::endl;
2098 for (Int_t i = 0; i < npar; i++) {
2099 fit_function_->SetParameter(i, best_params[i]);
2100 fit_function_->SetParError(i, best_errors[i]);
2102 if (use_flat_background_) {
2103 fit_function_->FixParameter(21, 0);
2106 TFitResultPtr fit_result = working_hist_->Fit(fit_function_,
"LSMRBENR+");
2108 if (fit_result.Get() && fit_result->IsValid()) {
2109 final_chi2 = fit_result->Chi2() / fit_result->Ndf();
2110 std::cout <<
"Double peak fit (constrained) converged successfully"
2112 std::cout <<
"Final chi2/ndf = " << final_chi2 << std::endl;
2115 std::cout <<
"ERROR: Double peak fit (constrained) failed to converge"
2123 TString chi2label = Form(
"#chi^{2}/ndf = %.3f", final_chi2);
2126 for (Int_t pk = 0; pk < 2; pk++) {
2129 p.
mu = fit_function_->GetParameter(o + 0);
2130 p.
mu_error = fit_function_->GetParError(o + 0);
2131 p.
sigma = fit_function_->GetParameter(o + 1);
2132 p.
sigma_error = fit_function_->GetParError(o + 1);
2151 results.
peaks[pk] = p;
2154 results.
bkg_constant = fit_function_->GetParameter(20);
2159 results.
valid = kTRUE;
2161 std::cout <<
"ERROR: Double peak fit (constrained) failed" << std::endl;
2168 const TString peak_name,
2170 Double_t mu3_init) {
2172 results.
peaks.emplace_back();
2173 results.
peaks.emplace_back();
2174 results.
peaks.emplace_back();
2176 delete fit_function_;
2178 fit_range_low_, fit_range_high_, 32);
2181 fit_function_->SetParName(0,
"Mu1");
2182 fit_function_->SetParName(1,
"Sigma1");
2183 fit_function_->SetParName(2,
"GausAmplitude1");
2184 fit_function_->SetParName(3,
"StepAmplitude1");
2185 fit_function_->SetParName(4,
"LowExpTailAmplitude1");
2186 fit_function_->SetParName(5,
"LowExpTailRatio1");
2187 fit_function_->SetParName(6,
"LowLinTailAmplitude1");
2188 fit_function_->SetParName(7,
"LowLinTailSlope1");
2189 fit_function_->SetParName(8,
"HighExpTailAmplitude1");
2190 fit_function_->SetParName(9,
"HighExpTailRatio1");
2193 fit_function_->SetParName(10,
"Mu2");
2194 fit_function_->SetParName(11,
"Sigma2");
2195 fit_function_->SetParName(12,
"GausAmplitude2");
2196 fit_function_->SetParName(13,
"StepAmplitude2");
2197 fit_function_->SetParName(14,
"LowExpTailAmplitude2");
2198 fit_function_->SetParName(15,
"LowExpTailRatio2");
2199 fit_function_->SetParName(16,
"LowLinTailAmplitude2");
2200 fit_function_->SetParName(17,
"LowLinTailSlope2");
2201 fit_function_->SetParName(18,
"HighExpTailAmplitude2");
2202 fit_function_->SetParName(19,
"HighExpTailRatio2");
2205 fit_function_->SetParName(20,
"Mu3");
2206 fit_function_->SetParName(21,
"Sigma3");
2207 fit_function_->SetParName(22,
"GausAmplitude3");
2208 fit_function_->SetParName(23,
"StepAmplitude3");
2209 fit_function_->SetParName(24,
"LowExpTailAmplitude3");
2210 fit_function_->SetParName(25,
"LowExpTailRatio3");
2211 fit_function_->SetParName(26,
"LowLinTailAmplitude3");
2212 fit_function_->SetParName(27,
"LowLinTailSlope3");
2213 fit_function_->SetParName(28,
"HighExpTailAmplitude3");
2214 fit_function_->SetParName(29,
"HighExpTailRatio3");
2216 fit_function_->SetParName(30,
"BkgConst");
2217 fit_function_->SetParName(31,
"BkgSlope");
2219 Double_t range_width = fit_range_high_ - fit_range_low_;
2220 Double_t sigma_init = range_width * 0.01;
2221 Double_t peak_height =
2222 working_hist_->GetBinContent(working_hist_->GetMaximumBin());
2223 Double_t bkg_estimate = EstimateBackground();
2229 &constrained_peaks.
peaks[1]};
2230 for (Int_t pk = 0; pk < 2; pk++) {
2235 fit_function_->FixParameter(o + 0, cp.
mu);
2236 fit_function_->FixParameter(o + 1, cp.
sigma);
2239 fit_function_->SetParLimits(o + 2, 0, peak_height * 2);
2245 fit_function_->FixParameter(o + 4,
2247 fit_function_->FixParameter(
2249 fit_function_->FixParameter(o + 6,
2252 fit_function_->FixParameter(o + 8,
2254 fit_function_->FixParameter(
2259 fit_function_->SetParLimits(20, fit_range_low_, fit_range_high_);
2260 fit_function_->SetParLimits(21, range_width * 0.001, range_width * 0.5);
2261 fit_function_->SetParLimits(22, 0, peak_height * 0.999);
2262 fit_function_->SetParLimits(23, 0, 0.5);
2263 fit_function_->SetParLimits(24, 0, 0.5);
2264 fit_function_->SetParLimits(25, 1.0, tail_ratio_max_);
2265 fit_function_->SetParLimits(26, 0, 0.5);
2266 fit_function_->SetParLimits(27, -0.1, 0.1);
2267 fit_function_->SetParLimits(28, 0, 0.5);
2268 fit_function_->SetParLimits(29, 1.0, tail_ratio_max_);
2270 fit_function_->SetParameter(20, mu3_init);
2271 fit_function_->SetParameter(21, sigma_init);
2272 fit_function_->SetParameter(22, peak_height * 0.999);
2276 fit_function_->SetParameter(23, 0);
2278 fit_function_->FixParameter(23, 0);
2280 if (use_low_exp_tail_) {
2281 fit_function_->SetParameter(24, 0);
2282 fit_function_->SetParameter(25, 1.5);
2284 fit_function_->FixParameter(24, 0);
2285 fit_function_->FixParameter(25, 1);
2288 if (use_low_lin_tail_) {
2289 fit_function_->SetParameter(26, 0);
2290 fit_function_->SetParameter(27, 0);
2292 fit_function_->FixParameter(26, 0);
2293 fit_function_->FixParameter(27, 0);
2296 if (use_high_exp_tail_) {
2297 fit_function_->SetParameter(28, 0);
2298 fit_function_->SetParameter(29, 1.5);
2300 fit_function_->FixParameter(28, 0);
2301 fit_function_->FixParameter(29, 1);
2305 fit_function_->SetParLimits(30, 0, peak_height * 0.999);
2306 if (!use_flat_background_) {
2307 fit_function_->SetParLimits(31, -0.1 * bkg_estimate / range_width,
2308 0.1 * bkg_estimate / range_width);
2310 fit_function_->SetParameter(30, bkg_estimate);
2311 fit_function_->SetParameter(31, 0);
2312 if (use_flat_background_) {
2313 fit_function_->FixParameter(31, 0);
2316 Bool_t fit_valid = kFALSE;
2317 Double_t final_chi2 = 0;
2320 if (LoadInteractiveParams(input_name, peak_name)) {
2321 TFitResultPtr refit = working_hist_->Fit(fit_function_,
"LSMRBENR+");
2322 if (refit.Get() && refit->IsValid())
2323 final_chi2 = refit->Chi2() / refit->Ndf();
2324 else if (fit_function_->GetNDF() > 0)
2325 final_chi2 = fit_function_->GetChisquare() / fit_function_->GetNDF();
2326 std::cout <<
"Refit from saved params chi2/ndf = " << final_chi2
2330 Bool_t was_batch = gROOT->IsBatch();
2331 gROOT->SetBatch(kFALSE);
2333 fit_range_low_, fit_range_high_, 3,
2334 peak_name +
" / " + input_name)) {
2335 Double_t rlo_tmp, rhi_tmp;
2336 fit_function_->GetRange(rlo_tmp, rhi_tmp);
2337 fit_range_low_ = rlo_tmp;
2338 fit_range_high_ = rhi_tmp;
2339 final_chi2 = fit_function_->GetChisquare() / fit_function_->GetNDF();
2340 std::cout <<
"Interactive chi2/ndf = " << final_chi2 << std::endl;
2341 SaveInteractiveParams(input_name, peak_name);
2344 gROOT->SetBatch(was_batch);
2348 fit_function_->FixParameter(23, 0);
2349 fit_function_->FixParameter(24, 0);
2350 fit_function_->FixParameter(25, 1);
2351 fit_function_->FixParameter(26, 0);
2352 fit_function_->FixParameter(27, 0);
2353 fit_function_->FixParameter(28, 0);
2354 fit_function_->FixParameter(29, 1);
2357 TFitResultPtr initial_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
2359 if (!initial_fit.Get() || !initial_fit->IsValid()) {
2360 std::cout <<
"ERROR: Initial triple peak fit failed" << std::endl;
2364 Double_t gaus_amp3 = TMath::Abs(fit_function_->GetParameter(22));
2366 Int_t npar = fit_function_->GetNpar();
2367 std::vector<Double_t> best_params(npar);
2368 std::vector<Double_t> best_errors(npar);
2369 for (Int_t i = 0; i < npar; i++) {
2370 best_params[i] = fit_function_->GetParameter(i);
2371 best_errors[i] = fit_function_->GetParError(i);
2374 Double_t best_chi2 = initial_fit->Chi2() / initial_fit->Ndf();
2375 std::cout <<
"Initial chi2/ndf = " << best_chi2 << std::endl;
2379 std::cout <<
"Testing low-side group for peak3..." << std::endl;
2381 fit_function_->ReleaseParameter(23);
2382 fit_function_->SetParLimits(23, 0, 0.5);
2383 fit_function_->SetParameter(23, 0.15);
2385 fit_function_->ReleaseParameter(24);
2386 fit_function_->ReleaseParameter(25);
2387 fit_function_->SetParLimits(24, 0, 0.5);
2388 fit_function_->SetParLimits(25, 1.0, tail_ratio_max_);
2389 fit_function_->SetParameter(24, 0.15);
2390 fit_function_->SetParameter(25, 1.5);
2392 fit_function_->ReleaseParameter(26);
2393 fit_function_->ReleaseParameter(27);
2394 fit_function_->SetParLimits(26, 0, 0.5);
2395 fit_function_->SetParLimits(27, -0.1, 0.1);
2396 fit_function_->SetParameter(26, 0.15);
2397 fit_function_->SetParameter(27, 0);
2399 TFitResultPtr group_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
2401 if (group_fit.Get() && group_fit->IsValid() &&
2402 group_fit->Chi2() / group_fit->Ndf() < best_chi2) {
2403 std::cout <<
"Low-side group peak3 ACCEPTED, pruning..." << std::endl;
2404 best_chi2 = group_fit->Chi2() / group_fit->Ndf();
2405 for (Int_t i = 0; i < npar; i++) {
2406 best_params[i] = fit_function_->GetParameter(i);
2407 best_errors[i] = fit_function_->GetParError(i);
2411 fit_function_->FixParameter(23, 0);
2412 TFitResultPtr p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
2413 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
2414 std::cout <<
" Step3 pruned" << std::endl;
2415 best_chi2 = p->Chi2() / p->Ndf();
2416 for (Int_t i = 0; i < npar; i++) {
2417 best_params[i] = fit_function_->GetParameter(i);
2418 best_errors[i] = fit_function_->GetParError(i);
2421 fit_function_->ReleaseParameter(23);
2422 fit_function_->SetParLimits(23, 0, 0.5);
2423 for (Int_t i = 0; i < npar; i++) {
2424 fit_function_->SetParameter(i, best_params[i]);
2425 fit_function_->SetParError(i, best_errors[i]);
2430 fit_function_->FixParameter(24, 0);
2431 fit_function_->FixParameter(25, 1);
2432 p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
2433 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
2434 std::cout <<
" LowExpTail3 pruned" << std::endl;
2435 best_chi2 = p->Chi2() / p->Ndf();
2436 for (Int_t i = 0; i < npar; i++) {
2437 best_params[i] = fit_function_->GetParameter(i);
2438 best_errors[i] = fit_function_->GetParError(i);
2441 fit_function_->ReleaseParameter(24);
2442 fit_function_->ReleaseParameter(25);
2443 fit_function_->SetParLimits(24, 0, 0.5);
2444 fit_function_->SetParLimits(25, 1.0, tail_ratio_max_);
2445 for (Int_t i = 0; i < npar; i++) {
2446 fit_function_->SetParameter(i, best_params[i]);
2447 fit_function_->SetParError(i, best_errors[i]);
2452 fit_function_->FixParameter(26, 0);
2453 fit_function_->FixParameter(27, 0);
2454 p = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
2455 if (p.Get() && p->IsValid() && p->Chi2() / p->Ndf() <= best_chi2) {
2456 std::cout <<
" LowLinTail3 pruned" << std::endl;
2457 best_chi2 = p->Chi2() / p->Ndf();
2458 for (Int_t i = 0; i < npar; i++) {
2459 best_params[i] = fit_function_->GetParameter(i);
2460 best_errors[i] = fit_function_->GetParError(i);
2463 fit_function_->ReleaseParameter(26);
2464 fit_function_->ReleaseParameter(27);
2465 fit_function_->SetParLimits(26, 0, 0.5);
2466 fit_function_->SetParLimits(27, -0.1, 0.1);
2467 for (Int_t i = 0; i < npar; i++) {
2468 fit_function_->SetParameter(i, best_params[i]);
2469 fit_function_->SetParError(i, best_errors[i]);
2473 std::cout <<
"Low-side group peak3 REJECTED" << std::endl;
2474 fit_function_->FixParameter(23, 0);
2475 fit_function_->FixParameter(24, 0);
2476 fit_function_->FixParameter(25, 1);
2477 fit_function_->FixParameter(26, 0);
2478 fit_function_->FixParameter(27, 0);
2479 for (Int_t i = 0; i < npar; i++) {
2480 fit_function_->SetParameter(i, best_params[i]);
2481 fit_function_->SetParError(i, best_errors[i]);
2488 std::cout <<
"Testing high tail for peak3..." << std::endl;
2489 fit_function_->ReleaseParameter(28);
2490 fit_function_->ReleaseParameter(29);
2491 fit_function_->SetParLimits(28, 0, 0.5);
2492 fit_function_->SetParLimits(29, 1.0, tail_ratio_max_);
2493 fit_function_->SetParameter(28, 0.15);
2494 fit_function_->SetParameter(29, 1.5);
2496 TFitResultPtr ht_fit = working_hist_->Fit(fit_function_,
"LSMBNQ0R");
2497 if (ht_fit.Get() && ht_fit->IsValid() &&
2498 ht_fit->Chi2() / ht_fit->Ndf() < best_chi2) {
2499 std::cout <<
"HighTail3 ACCEPTED" << std::endl;
2500 best_chi2 = ht_fit->Chi2() / ht_fit->Ndf();
2501 for (Int_t i = 0; i < npar; i++) {
2502 best_params[i] = fit_function_->GetParameter(i);
2503 best_errors[i] = fit_function_->GetParError(i);
2506 std::cout <<
"HighTail3 REJECTED" << std::endl;
2507 fit_function_->FixParameter(28, 0);
2508 fit_function_->FixParameter(29, 1);
2509 for (Int_t i = 0; i < npar; i++) {
2510 fit_function_->SetParameter(i, best_params[i]);
2511 fit_function_->SetParError(i, best_errors[i]);
2517 std::cout <<
"Final fit with selected components..." << std::endl;
2518 for (Int_t i = 0; i < npar; i++) {
2519 fit_function_->SetParameter(i, best_params[i]);
2520 fit_function_->SetParError(i, best_errors[i]);
2522 if (use_flat_background_) {
2523 fit_function_->FixParameter(31, 0);
2526 TFitResultPtr fit_result = working_hist_->Fit(fit_function_,
"LSMRBENR+");
2528 if (fit_result.Get() && fit_result->IsValid()) {
2529 final_chi2 = fit_result->Chi2() / fit_result->Ndf();
2530 std::cout <<
"Triple peak fit converged successfully" << std::endl;
2531 std::cout <<
"Final chi2/ndf = " << final_chi2 << std::endl;
2534 std::cout <<
"ERROR: Triple peak fit failed to converge" << std::endl;
2541 TString chi2label = Form(
"#chi^{2}/ndf = %.3f", final_chi2);
2544 for (Int_t pk = 0; pk < 3; pk++) {
2547 p.
mu = fit_function_->GetParameter(o + 0);
2548 p.
mu_error = fit_function_->GetParError(o + 0);
2549 p.
sigma = fit_function_->GetParameter(o + 1);
2550 p.
sigma_error = fit_function_->GetParError(o + 1);
2569 results.
peaks[pk] = p;
2572 results.
bkg_constant = fit_function_->GetParameter(30);
2577 results.
valid = kTRUE;
2579 std::cout <<
"ERROR: Triple peak fit failed" << std::endl;