14 :
TGRSIFit(
"multipeakbg", this, &
TMultiPeak::MultiPhotoPeakBG, xlow, xhigh, centroids.size() * 6 + 5,
"TMultiPeak",
"MultiPhotoPeakBG")
16 std::cout <<
"Warning, the class TMultiPeak is deprecated (use TPeakFitter instead)!" << std::endl;
19 fBackground =
new TF1(Form(
"MPbackground_%d_to_%d",
static_cast<Int_t
>(xlow),
static_cast<Int_t
>(xhigh)),
this, &
TMultiPeak::MultiStepBG, xlow, xhigh, centroids.size() * 6 + 5,
"TMuliPeak",
"MultiStepBG");
25 for(
double cent : centroids) {
26 Bool_t out_of_range_flag =
false;
28 std::cout <<
"centroid " << cent <<
" is higher than range" << std::endl;
29 out_of_range_flag =
true;
30 }
else if(cent < xlow) {
31 std::cout <<
"centroid " << cent <<
" is lower than range" << std::endl;
32 out_of_range_flag =
true;
34 if(out_of_range_flag) {
35 std::cout <<
"ignoring peak at " << cent <<
", make a new multi peak with the corrected energy" << std::endl;
38 peak->AddToGlobalList(kFALSE);
42 SetRange(xlow, xhigh);
44 SetName(Form(
"MultiPeak_%d_to_%d",
static_cast<Int_t
>(xlow),
45 static_cast<Int_t
>(xhigh)));
123 if((fithist ==
nullptr) && (
GetHist() !=
nullptr)) {
127 if(fithist ==
nullptr) {
128 std::cout <<
"No histogram is associated yet, no initial guesses made" << std::endl;
132 FixParameter(0,
static_cast<double>(
fPeakVec.size()));
136 GetRange(xlow, xhigh);
137 Int_t binlow = fithist->GetXaxis()->FindBin(xlow);
138 Int_t binhigh = fithist->GetXaxis()->FindBin(xhigh);
141 SetParLimits(1, 0.0, fithist->GetBinContent(binlow) * 100.0);
142 SetParameter(
"A", fithist->GetBinContent(binlow));
143 SetParameter(
"B", (fithist->GetBinContent(binlow) - fithist->GetBinContent(binhigh)) / (xlow - xhigh));
144 SetParameter(
"C", 0.0000);
145 SetParameter(
"bg_offset", (xhigh + xlow) / 2.0);
150 for(
int i = 0; i < static_cast<int>(
fPeakVec.size()); ++i) {
151 Double_t centroid =
fPeakVec.at(i)->GetCentroid();
152 Int_t bin = fithist->GetXaxis()->FindBin(centroid);
153 SetParLimits(6 * i + 5, 0, fithist->GetBinContent(bin) * 5.);
154 SetParLimits(6 * i + 6, centroid - 4, centroid + 4);
156 SetParLimits(6 * i + 7, 0.1, 1.5);
157 SetParLimits(6 * i + 8, 0.000001, 10);
158 SetParLimits(6 * i + 9, 0.000001, 100);
159 SetParLimits(6 * i + 10, 0.0, 1.0E2);
163 SetParameter(Form(
"Height_%i", i), fithist->GetBinContent(bin));
164 SetParameter(Form(
"Centroid_%i", i), centroid);
167 SetParameter(Form(
"Sigma_%i", i), TMath::Sqrt(9.0 + 4. * GetParameter(Form(
"Centroid_%i", i)) / 1000.));
168 SetParameter(Form(
"Beta_%i", i), GetParameter(Form(
"Sigma_%i", i)) / 2.0);
169 SetParameter(Form(
"R_%i", i), 1.0);
170 SetParameter(Form(
"Step_%i", i), 1.0);
173 FixParameter(6 * i + 8, GetParameter(Form(
"Beta_%i", i)));
174 FixParameter(6 * i + 9, 0.00);
183 TString optstr = opt;
184 if((fithist ==
nullptr) && (
GetHist() ==
nullptr)) {
185 std::cout <<
"No hist passed, trying something...";
186 fithist = fHistogram;
188 if(fithist ==
nullptr) {
189 std::cout <<
"No histogram associated with Peak" << std::endl;
196 TVirtualFitter::SetMaxIterations(100000);
197 ROOT::Math::MinimizerOptions::SetDefaultMinimizer(
"Minuit2",
"Combination");
200 TString options(opt);
201 bool print_flag =
true;
202 if(options.Contains(
"Q")) {
208 TFitResultPtr fitres;
211 fitres = fithist->Fit(
this, Form(
"%sLRSQ", opt));
213 fitres = fithist->Fit(
this, Form(
"%sRSQ", opt));
216 std::vector<Double_t> sigma_list(
static_cast<int>(GetParameter(0) + 0.5));
217 for(
int i = 0; i < static_cast<int>(GetParameter(0) + 0.5); ++i) {
219 sigma_list[i] = GetParameter(6 * i + 7);
221 std::sort(sigma_list.begin(), sigma_list.end(), std::greater<>());
222 Double_t median = sigma_list.at(sigma_list.size() / 2);
224 Double_t range_low = 0.;
225 Double_t range_high = 0.;
226 for(
int i = 0; i < static_cast<int>(GetParameter(0) + 0.5); ++i) {
227 GetParLimits(6 * i + 7, range_low, range_high);
228 if(range_low != range_high) {
229 SetParLimits(6 * i + 7, median * .95, median * 1.05);
235 fitres = fithist->Fit(
this, Form(
"%sLRS", opt));
237 fitres = fithist->Fit(
this, Form(
"%sRS", opt));
245 TMatrixDSym CovMat = fitres->GetCovarianceMatrix();
257 TMatrixDSym emptyCovMat = CovMat;
258 for(
size_t i = 0; i <
fPeakVec.size(); ++i) {
259 emptyCovMat(6 * i + 5, 6 * i + 5) = 0.0;
260 emptyCovMat(6 * i + 6, 6 * i + 6) = 0.0;
261 emptyCovMat(6 * i + 7, 6 * i + 7) = 0.0;
262 emptyCovMat(6 * i + 8, 6 * i + 8) = 0.0;
263 emptyCovMat(6 * i + 9, 6 * i + 9) = 0.0;
264 emptyCovMat(6 * i + 10, 6 * i + 10) = 0.0;
268 std::cout <<
"Chi^2/NDF = " << fitres->Chi2() / fitres->Ndf() << std::endl;
271 for(
int i = 0; i < static_cast<int>(
fPeakVec.size()); ++i) {
273 tmpMp->ClearParameters();
274 Double_t binWidth = fithist->GetBinWidth(1);
276 TMatrixDSym tmpCovMat = emptyCovMat;
277 peak->SetParameter(
"Height", GetParameter(Form(
"Height_%i", i)));
278 peak->SetParameter(
"centroid", GetParameter(Form(
"Centroid_%i", i)));
279 peak->SetParameter(
"sigma", GetParameter(Form(
"Sigma_%i", i)));
280 peak->SetParameter(
"beta", GetParameter(Form(
"Beta_%i", i)));
281 peak->SetParameter(
"R", GetParameter(Form(
"R_%i", i)));
282 peak->SetParameter(
"step", GetParameter(Form(
"Step_%i", i)));
283 peak->SetParameter(
"A", 0.0);
284 peak->SetParameter(
"B", 0.0);
285 peak->SetParameter(
"C", 0.0);
286 peak->SetParameter(
"bg_offset", 0.0);
288 peak->
SetNdf(fitres->Ndf());
291 tmpCovMat(6 * i + 5, 6 * i + 5) = CovMat(6 * i + 5, 6 * i + 5);
292 tmpCovMat(6 * i + 6, 6 * i + 6) = CovMat(6 * i + 6, 6 * i + 6);
293 tmpCovMat(6 * i + 7, 6 * i + 7) = CovMat(6 * i + 7, 6 * i + 7);
294 tmpCovMat(6 * i + 8, 6 * i + 8) = CovMat(6 * i + 8, 6 * i + 8);
295 tmpCovMat(6 * i + 9, 6 * i + 9) = CovMat(6 * i + 9, 6 * i + 9);
297 tmpMp->SetParameter(
"N_Peaks", GetParameter(
"N_Peaks"));
298 tmpMp->SetParameter(Form(
"Height_%i", i), GetParameter(Form(
"Height_%i", i)));
299 tmpMp->SetParameter(Form(
"Centroid_%i", i), GetParameter(Form(
"Centroid_%i", i)));
300 tmpMp->SetParameter(Form(
"Sigma_%i", i), GetParameter(Form(
"Sigma_%i", i)));
301 tmpMp->SetParameter(Form(
"Beta_%i", i), GetParameter(Form(
"Beta_%i", i)));
302 tmpMp->SetParameter(Form(
"R_%i", i), GetParameter(Form(
"R_%i", i)));
304 Double_t width = GetParameter(Form(
"Sigma_%i", i));
307 GetRange(xlow, xhigh);
308 Double_t int_low = xlow - 10. * width;
309 Double_t int_high = xhigh + 10. * width;
313 tmpMp->SetRange(int_low, int_high);
317 peak->
SetArea((tmpMp->Integral(int_low, int_high)) / binWidth);
318 peak->
SetAreaErr((tmpMp->IntegralError(int_low, int_high, tmpMp->GetParameters(), tmpCovMat.GetMatrixArray())) /
320 peak->SetParameter(
"centroid", GetParameter(Form(
"Centroid_%i", i)));
321 peak->SetParError(peak->GetParNumber(
"centroid"), GetParError(GetParNumber(Form(
"Centroid_%i", i))));
322 peak->SetParameter(
"sigma", GetParameter(GetParNumber(Form(
"Sigma_%i", i))));
323 peak->SetParError(peak->GetParNumber(
"sigma"), GetParError(GetParNumber(Form(
"Sigma_%i", i))));
325 std::cout <<
"Integral: " << peak->
GetArea() <<
" +- " << peak->
GetAreaErr() << std::endl;
447 GetRange(xlow, xhigh);
451 Double_t centroid = peak->GetCentroid();
452 Double_t range = 2. * peak->GetFWHM();
454 auto* sum =
new TF1(Form(
"tmp%s", peak->GetName()),
this, &
TMultiPeak::SinglePeakBG, centroid - range, centroid + range,
455 fPeakVec.size() * 6 + 11,
"TMultiPeak",
"SinglePeakBG");
457 for(
int j = 0; j < GetNpar(); ++j) {
458 sum->SetParameter(j, GetParameter(j));
460 for(
int j = 0; j < 5; ++j) {
461 sum->SetParameter(npeaks * 6 + 5 + j, peak->GetParameter(j));
465 sum->SetLineStyle(2);
466 sum->SetLineColor(kMagenta);
468 sum->SetRange(centroid - range, centroid + range);
469 sum->DrawCopy(
"SAME");