ICRC2017/UnfoldSpectrum.cc
Go to the documentation of this file.
1 /* Authors: I. ValiƱo, G. Rodriguez, Alan Coleman, Alex Schulz
2  based on an original code of H. Dembinski */
3 
4 #include <iostream>
5 #include <iomanip>
6 #include <fstream>
7 #include <cmath>
8 #include <vector>
9 #include <cstring>
10 #include <sstream>
11 
12 #include <TFile.h>
13 #include <TCanvas.h>
14 
15 #include <TMath.h>
16 #include <TF1.h>
17 #include "Math/WrappedTF1.h"
18 #include "Math/Integrator.h"
19 
20 #include <TH1D.h>
21 #include <TNtupleD.h>
22 #include <TMath.h>
23 #include <TMinuit.h>
24 #include <TGraphAsymmErrors.h>
25 #include <TGraphErrors.h>
26 #include <TGraph.h>
27 #include <TAxis.h>
28 #include <TMatrixD.h>
29 #include <TVectorD.h>
30 #include <TApplication.h>
31 #include <TMinuit.h>
32 #include <TImage.h>
33 #include <TROOT.h>
34 #include <TStyle.h>
35 #include <TLegend.h>
36 
37 using namespace std;
38 
41 TAxis* thLgE;
42 TVectorD vecLgE;
43 TMatrixD kmatrix;
44 TAxis* rawAxis_lgE;
45 
46 const bool HeraldAnalysis = false;
47 
48 #include "UnfoldUtilities.icc"
49 #include "FittingFunctions.icc"
50 #include "Statistics.icc"
51 
54 
55 // Format for parameters is (Regular, Infill)
56 
57 /* energy limits of the spectrum */
58 const double SpectrumMin[2] = {18.4, 17.5};
59 const double SpectrumMax[2] = {20.2, 19.7};
60 const double SpectrumBinSize[2] = {0.1, 0.1};
61 
62 /* energy integration limits */
63 const double IntXmin[2] = {17.9, 16.9};
64 const double IntXmax[2] = {20.9, 19.9};
65 const int IntegrationSteps = 10; // Number of integration steps per bin (should be >~ 10)
66 
67 const bool DoArray[2] = {true, true}; // Which spectra to do
68 
69 const char* RegularDataFileName = "Events_SD1500_ICRC2017_Offline.dat";
70 const char* InfillDataFileName = "Events_SD750_ICRC2017_Offline.dat";
71 //onst char* InfillDataFileName = "Events_SD750_ICRC2017_Herald.dat";
72 //const char* RegularDataFileName = "Events_SD1500_ICRC2017_Herald.dat";
73 
74 const bool ResolutionFromData = false; //True = Resolution calculated from data; False = from sim
75 const bool Rebinning[2] = {true, true};
76 
77 // Re-binning for SD1500 and SD750
78 const double SpectrumBins[15][15] = {{18.4, 18.5, 18.6, 18.7, 18.8, 18.9, 19.0, 19.1, 19.2, 19.3, 19.4, 19.5, 19.7, 19.9, 20.2},
79  {17.5, 17.6, 17.7, 17.8, 17.9, 18.0, 18.1, 18.2, 18.3, 18.4, 18.5, 18.7, 18.9, 19.2, 19.7}};
80 const int BinNum[2] = {14, 14};
81 
82 // see FittingFunctions.h
84 // const modeltype modelfunctions[2] = {StandardICRC2015, InfillHard};
85 
88 
89 
90 // Number of fit parameters per array
91 const int NParArray[2] = {modelfunctions[0] == StandardMultiSmooth ? 8 : 6, 4};
92 const int Npar = 8; //Set this to the larger of the two values above
93 
94 int iarray = 0;
95 
96 double fParFitInit[Npar];
97 TVectorD parsFit(Npar);
98 TVectorD parsErrorsFit(Npar);
99 
100 double exposure;
101 
103 
108 
109 TVectorD MinuitMinimization(double* start, bool computeCovStat);
110 void FitFCN(Int_t& npar, Double_t* gin, Double_t& f, Double_t* par, Int_t iflag);
111 double Likelihood(double* pars);
112 void PrintResults();
113 
114 int main(void)
115 {
116 
117  gROOT->SetStyle("Plain");
118  gStyle->SetCanvasDefH(700);
119  gStyle->SetCanvasDefW(900);
120  gStyle->SetCanvasBorderMode(0);
121  gStyle->SetCanvasColor(0);
122 
123  gStyle->SetPadTopMargin(0.05);
124  gStyle->SetPadBottomMargin(0.15);
125  gStyle->SetPadLeftMargin(0.18);
126  gStyle->SetPadRightMargin(0.05);
127  gStyle->SetPadColor(0);
128  gStyle->SetPadBorderMode(0);
129 
130  gStyle->SetFrameBorderMode(0);
131  gStyle->SetTitleFillColor(0);
132  gStyle->SetTitleBorderSize(1);
133  gStyle->SetStatColor(0);
134  gStyle->SetStatBorderSize(1);
135 
136  gStyle->SetOptTitle(0);
137  gStyle->SetOptStat(0);
138 
139  gStyle->SetPalette(1, 0);
140  gStyle->SetTitleBorderSize(0);
141  gStyle->SetTitleX(0.1f);
142  gStyle->SetTitleW(0.8f);
143 
144  gStyle->SetTitleFont(42, "X");
145  gStyle->SetTitleFont(42, "Y");
146  gStyle->SetLabelFont(42, "X");
147  gStyle->SetLabelFont(42, "Y");
148 
149  gStyle->SetTitleAlign(21);
150 
151 
152  gStyle->SetMarkerStyle(8);
153  gStyle->SetMarkerSize(1.4);
154 
155  gStyle->SetTitleXOffset(1.);
156  gStyle->SetTitleYOffset(1.4);
157  gStyle->SetTitleSize(0.06, "X");
158  gStyle->SetTitleSize(0.06, "Y");
159 
160  gStyle->SetTextSize(20);
161  gStyle->SetStripDecimals(0);
162 
163  gStyle->SetErrorX(0.);
164  gStyle->cd();
165 
166  double arrayExposure[2];
167  ifstream fOpenExposure("exposure");
168  for (iarray = 0; iarray < 2; iarray++)
169  fOpenExposure >> arrayExposure[iarray];
170  fOpenExposure.close();
171 
172  for (iarray = 0; iarray < 2; iarray++) {
173 
174  if (!DoArray[iarray])
175  continue;
176 
177  int hnbins = round((SpectrumMax[iarray] - SpectrumMin[iarray]) / SpectrumBinSize[iarray]);
178  exposure = arrayExposure[iarray];
179 
180  TH1D* thEnergySpectrum = new TH1D(Form("thEnergySpectrum%d", iarray), "", hnbins, SpectrumMin[iarray], SpectrumMax[iarray]);
181 
182  TH1D* thEnergySpectrum_rebinned;
183 
184  if (Rebinning[iarray]) {
185  std::cerr << "Re-binning active for " << Form("%s", iarray ? "Infill" : "Regular") << " array data...\n";
186  thEnergySpectrum_rebinned = new TH1D(Form("thEnergySpectrum_rebinned%d", iarray), "", BinNum[iarray], SpectrumBins[iarray]);
187  }
188 
189  rawAxis_lgE = thEnergySpectrum->GetXaxis();
190 
191  // Open file with Rec. events
192 
193  /* variables */
194  long int AugerId;
195  long int EventId;
196  int nst;
197  double lgE, S1000, dS1000, theta, phi, dec, ra;
198 
199  ifstream evtFile;
200  evtFile.open((iarray ? InfillDataFileName : RegularDataFileName), ios::in);
201 
202  char header[1024];
203  evtFile.getline(header, 1024);
204 
205  std::cerr << "Reading " << Form("%s", iarray ? "Infill" : "Regular") << " array data...\n";
206 
207  while (!evtFile.eof()) {
208  evtFile >> AugerId >> EventId >> lgE >> S1000 >> dS1000 >> nst >> theta >> phi >> dec >> ra;
209 
210  if (HeraldAnalysis) // energies given in EeV
211  lgE = log10(lgE) + 18;
212 
213  if (!evtFile.eof()){
214  thEnergySpectrum->Fill(lgE);
215  if (Rebinning[iarray])
216  thEnergySpectrum_rebinned->Fill(lgE);
217  }
218  }
219  evtFile.close();
220 
221  //*****************************************************
222  // RAW SPECTRUM
223  //*****************************************************
224  int Nbins = thEnergySpectrum->GetNbinsX();
225  raw_lgEs.ResizeTo(Nbins), raw_nevents.ResizeTo(Nbins), raw_flux.ResizeTo(Nbins), raw_staterrlow.ResizeTo(Nbins), raw_staterrup.ResizeTo(Nbins);
226 
227  TGraphAsymmErrors* tgEnergySpectrum = new TGraphAsymmErrors();
228  for (int i = 1; i <= Nbins; ++i) {
229 
230  double binW = thEnergySpectrum->GetBinWidth(i);
231  double we = pow(10, thEnergySpectrum->GetBinCenter(i) + binW / 2) - pow(10, thEnergySpectrum->GetBinCenter(i) - binW / 2);
232  double factor = exposure * we;
233  double lgE = thEnergySpectrum->GetBinCenter(i);
234  double content = thEnergySpectrum->GetBinContent(i) / factor;
235 
236  tgEnergySpectrum->SetPoint(i - 1, lgE, content);
237 
238  double plow, pup;
239  poisson_uncertainty(thEnergySpectrum->GetBinContent(i), plow, pup);
240 
241  tgEnergySpectrum->SetPointError(i - 1, 0., 0., plow / factor, pup / factor);
242 
243 
244  raw_lgEs[i - 1] = lgE;
245  raw_nevents[i - 1] = thEnergySpectrum->GetBinContent(i);
246  raw_flux[i - 1] = content;
247  raw_staterrlow[i - 1] = plow / factor;
248  raw_staterrup[i - 1] = pup / factor;
249  }
250 
251 
252  //*****************************************************************
253  // Rebinned raw spectrum
254  //*****************************************************************
255  if (Rebinning[iarray]) {
256  int Nbins_rebinned = thEnergySpectrum_rebinned->GetNbinsX();
257  raw_lgEs_rebinned.ResizeTo(Nbins_rebinned), raw_nevents_rebinned.ResizeTo(Nbins_rebinned), raw_flux_rebinned.ResizeTo(Nbins_rebinned), raw_staterrlow_rebinned.ResizeTo(Nbins_rebinned), raw_staterrup_rebinned.ResizeTo(Nbins_rebinned);
258 
259  for (int i = 1; i <= Nbins_rebinned; ++i) {
260 
261  double binW_rebinned = thEnergySpectrum_rebinned->GetBinWidth(i);
262  double we_rebinned = pow(10, thEnergySpectrum_rebinned->GetBinCenter(i) + binW_rebinned / 2) - pow(10, thEnergySpectrum_rebinned->GetBinCenter(i) - binW_rebinned / 2);
263  double factor_rebinned = exposure * we_rebinned;
264  double lgE_rebinned = thEnergySpectrum_rebinned->GetBinCenter(i);
265  double content_rebinned = thEnergySpectrum_rebinned->GetBinContent(i) / factor_rebinned;
266 
267  double plow_rebinned, pup_rebinned;
268  poisson_uncertainty(thEnergySpectrum_rebinned->GetBinContent(i), plow_rebinned, pup_rebinned);
269 
270  raw_lgEs_rebinned[i - 1] = lgE_rebinned;
271  raw_nevents_rebinned[i - 1] = thEnergySpectrum_rebinned->GetBinContent(i);
272  raw_flux_rebinned[i - 1] = content_rebinned;
273  raw_staterrlow_rebinned[i - 1] = plow_rebinned / factor_rebinned;
274  raw_staterrup_rebinned[i - 1] = pup_rebinned / factor_rebinned;
275  }
276  }
277 
278  /* Model parameters: */
279  /* 0: normalization; 1: log10(energy) at ankle position; 2: spectral index before ankle; 3 spectra index after ankle;
280  4: log10(energy) at the 1/2 suppression; 5: increment of the spectral index beyond suppression */
281 
282  TF1* FitFunction;
283 
284  FitFunction = new TF1("RegularFunction", FluxModels(modelfunctions[iarray]), SpectrumMin[iarray], SpectrumMax[iarray], NParArray[iarray]);
285 
286  if (!iarray) {
287 
288  if (modelfunctions[iarray] == StandardICRC2015) {
289 
290  FitFunction->SetParameter(0, -19.);
291  FitFunction->SetParameter(1, 18.7);
292  FitFunction->SetParameter(2, 3.3);
293  FitFunction->SetParameter(3, 2.8);
294  FitFunction->SetParameter(4, 19.8);
295  FitFunction->SetParameter(5, 0.15);
296 
297  } else if (modelfunctions[iarray] == StandardMultiSmooth) {
298 
299  FitFunction->SetParameter(0, -22.5);
300  FitFunction->SetParameter(1, 18.7);
301  FitFunction->SetParameter(2, 19.15);
302  FitFunction->SetParameter(3, 19.65);
303  FitFunction->SetParameter(4, 3.3);
304  FitFunction->SetParameter(5, 2.6);
305  FitFunction->SetParameter(6, 3.0);
306  FitFunction->SetParameter(7, 5.0);
307  }
308 
309  } else {
310 
311  FitFunction->SetParameter(0, -19);
312  FitFunction->SetParameter(1, 18.7);
313  FitFunction->SetParameter(2, 3.3);
314  FitFunction->SetParameter(3, 2.8);
315  }
316 
317  FitFunction->SetLineColor(1);
318  FitFunction->SetLineStyle(9);
319  FitFunction->SetLineWidth(1);
320 
321  tgEnergySpectrum->Fit(FitFunction, "q");
322 
323  for (int i = 0; i < NParArray[iarray]; i++)
324  fParFitInit[i] = FitFunction->GetParameter(i);
325 
326 
327  //***************************************************
328  // UNFOLDING starts ....
329  //***************************************************
330 
331  /* Numerical integration made using a Rienmann sum */
332 
333  //do unfolding, x = lgE, y = count
334 
335  int nbins = round((IntXmax[iarray] - IntXmin[iarray]) / thEnergySpectrum->GetBinWidth(1));
336 
337  int N = nbins * IntegrationSteps;
338 
339  thLgE = new TAxis(N, IntXmin[iarray], IntXmax[iarray]);
340  vecLgE.ResizeTo(N);
341  for (int i = 1; i <= N; ++i)
342  vecLgE[i - 1] = thLgE->GetBinCenter(i);
343 
344  TVectorD pCal = GetSDCalPars(iarray);
345 
346  double resolutionOffset[2] = {0, 0};
347  kmatrix.ResizeTo(N, N);
348  kmatrix = kResolutionMatrix(pCal, vecLgE, resolutionOffset, ResolutionFromData, iarray);
349 
350  double lgExp = log10(exposure);
351 
352  // Set Initial guess parameters from fit
353  double start[NParArray[iarray]];
354  start[0] = fParFitInit[0] + lgExp; // Special treatment for norm
355  for (int ipar = 1; ipar < NParArray[iarray]; ipar++)
356  start[ipar] = fParFitInit[ipar];
357 
358  UnfoldCorrectionFactor.ResizeTo(N);
360 
361  // statistics errors due to unfolding.
362  TVectorD unfoldstat(N);
363  TVectorD dlgE(N);
364 
365  for (int i = 0; i < N; ++i) {
366 
367  unfoldstat[i] = sqrt(UnfoldCorrectionFactorCoV[i][i]);
368  dlgE[i] = thLgE->GetBinCenter(1) / 2.;
369  }
370 
371  TGraph* tgUnfoldStatValue = new TGraph(N, &vecLgE[0], &unfoldstat[0]);
372 
373  TCanvas* c1 = new TCanvas();
374  c1->SetGridx(1);
375  c1->SetGridy(1);
376 
377  TGraphAsymmErrors* tgUnfoldStat = new TGraphAsymmErrors(N, &vecLgE[0], &UnfoldCorrectionFactor[0], &dlgE[0], &dlgE[0], &unfoldstat[0], &unfoldstat[0]);
378  tgUnfoldStat->Draw("a3");
379  tgUnfoldStat->SetMinimum(0);
380  tgUnfoldStat->SetMaximum(1.2);
381  tgUnfoldStat->SetFillColor(kGray);
382 
383  TGraph* tgUnfold = new TGraph(N, &vecLgE[0], &UnfoldCorrectionFactor[0]);
384  tgUnfold->Draw("l");
385  tgUnfold->SetMarkerStyle(3);
386 
387  tgUnfold->SetFillColor(kBlack);
388  tgUnfold->SetLineWidth(3);
389 
390  tgUnfoldStat->GetYaxis()->CenterTitle(kTRUE);
391  tgUnfoldStat->GetXaxis()->CenterTitle(kTRUE);
392 
393  tgUnfoldStat->GetYaxis()->SetTitle("Correction factor: J_{true}/J_{folded}");
394  tgUnfoldStat->GetXaxis()->SetTitle("log_{10}(E/eV)");
395 
396  tgUnfoldStat->GetXaxis()->SetRangeUser(SpectrumMin[iarray], SpectrumMax[iarray]);
397  tgUnfoldStat->GetYaxis()->SetRangeUser(0.7, 1.05);
398 
399 
400  TGraphAsymmErrors* tgUnfoldSpectrum = new TGraphAsymmErrors();
401 
402  /* Writing the resulting spectrum in an output file */
403 
404  ofstream fOut(Form("%sSpectrum.dat", iarray ? "Infill" : "Regular"), ios::out);
405  fOut << "# lg(E/eV) lgE_hw raw_counts exposure[km2 sr yr] J [km-2 sr-1 yr-1 eV-1] lower_sigma[J]_stat upper_sigma[J]_stat unfolding_correction sigma[unfolding_correction]_stat" << endl;
406 
407  for (int i = 0; i < raw_lgEs.GetNoElements(); ++i) {
408 
409  double factorunfold = tgUnfold->Eval(raw_lgEs[i]);
410  double statunc_factorunfold = tgUnfoldStatValue->Eval(raw_lgEs[i]);
411  double nmod = raw_flux[i] * factorunfold;
412  double lowerror = raw_staterrlow[i] * factorunfold;
413  double uperror = raw_staterrup[i] * factorunfold;
414 
415  fOut << raw_lgEs[i] << " " << thEnergySpectrum->GetBinWidth(i) / 2. << " " << raw_nevents[i] << " " << exposure << " " << nmod << " " << lowerror << " " << uperror << " " << factorunfold << " " << statunc_factorunfold << endl;
416 
417  tgUnfoldSpectrum->SetPoint(i, raw_lgEs[i], nmod);
418  tgUnfoldSpectrum->SetPointError(i, 0., 0., lowerror, uperror);
419  }
420 
421  if (Rebinning[iarray]){
422  ofstream fOutRebinned(Form("%sSpectrum_rebinned.dat", iarray ? "Infill" : "Regular"), ios::out);
423  fOutRebinned << "# lg(E/eV) lgE_hw raw_counts exposure[km2 sr yr] J [km-2 sr-1 yr-1 eV-1] lower_sigma[J]_stat upper_sigma[J]_stat unfolding_correction" << endl;
424  for (int i = 0; i < raw_lgEs_rebinned.GetNoElements(); ++i) {
425  double factorunfold_rebinned = tgUnfold->Eval(raw_lgEs_rebinned[i]);
426  double statunc_factorunfold_rebinned = tgUnfoldStatValue->Eval(raw_lgEs_rebinned[i]);
427  double nmod_rebinned = raw_flux_rebinned[i] * factorunfold_rebinned;
428  double lowerror_rebinned = raw_staterrlow_rebinned[i] * factorunfold_rebinned;
429  double uperror_rebinned = raw_staterrup_rebinned[i] * factorunfold_rebinned;
430 
431 
432  fOutRebinned << raw_lgEs_rebinned[i] << " " << thEnergySpectrum_rebinned->GetBinWidth(i+1) / 2. << " " << raw_nevents_rebinned[i] << " " << exposure << " " << nmod_rebinned << " " << lowerror_rebinned << " " << uperror_rebinned << " " << factorunfold_rebinned << " " << statunc_factorunfold_rebinned << endl;
433 
434  }
435  fOutRebinned.close();
436  }
437  fOut.close();
438 
439 
440  TCanvas* c2 = new TCanvas();
441  c2->SetLogy();
442  tgEnergySpectrum->SetMarkerStyle(22);
443  tgEnergySpectrum->SetMarkerSize(2.2);
444  tgEnergySpectrum->SetMarkerColor(1);
445  tgEnergySpectrum->GetYaxis()->CenterTitle(kTRUE);
446  tgEnergySpectrum->GetXaxis()->CenterTitle(kTRUE);
447  tgEnergySpectrum->GetYaxis()->SetTitle("J(E) [eV^{-1} km^{-2} sr^{-1} yr^{-1}]");
448  tgEnergySpectrum->GetXaxis()->SetTitle("log_{10}(E/eV)");
449  tgEnergySpectrum->Draw("ap");
450 
451  tgUnfoldSpectrum->SetMarkerStyle(20);
452  tgUnfoldSpectrum->SetMarkerSize(1.8);
453  tgUnfoldSpectrum->SetMarkerColor(2);
454  tgUnfoldSpectrum->SetLineColor(2);
455  tgUnfoldSpectrum->Draw("p");
456 
457  double hymin = FitFunction->Eval(SpectrumMax[iarray]) / 10.;
458  double hymax = FitFunction->Eval(SpectrumMin[iarray]) * 10.;
459 
460  tgEnergySpectrum->GetXaxis()->SetRangeUser(SpectrumMin[iarray], SpectrumMax[iarray]);
461  tgEnergySpectrum->GetYaxis()->SetRangeUser(hymin, hymax);
462 
463  FitFunction->SetLineColor(2);
464  FitFunction->SetLineStyle(9);
465  FitFunction->SetLineWidth(1);
466  tgUnfoldSpectrum->Fit(FitFunction, "q");
467 
468  TLegend* leg = new TLegend(0.2, 0.3, 0.5, 0.45);
469  leg->SetFillColor(0);
470  leg->SetLineColor(0);
471  leg->SetBorderSize(1);
472  leg->SetTextFont(42);
473  leg->SetTextSize(0.04);
474  leg->AddEntry(tgEnergySpectrum, "measured spectrum", "p");
475  leg->AddEntry(tgUnfoldSpectrum, "unfolded spectrum", "p");
476  leg->Draw();
477 
478 
479 
480  TImage* img1 = TImage::Create();
481  img1->FromPad(c1);
482  img1->WriteImage(Form("%sCorrectionFactor.png", iarray ? "Infill" : "Regular"));
483 
484  TImage* img2 = TImage::Create();
485  img2->FromPad(c2);
486  img2->WriteImage(Form("%sSpectrum.png", iarray ? "Infill" : "Regular"));
487 
488  PrintResults();
489  }
490 
491  return 0;
492 
493 } //close main function
494 
495 
496 TVectorD MinuitMinimization(double* start, bool computeCovStat = true)
497 {
498 
499  const int N = NParArray[iarray];
500 
501  TMinuit gMinuit(N);
502  double arglist[10];
503  int ierflg = 0;
504  arglist[0] = -1; // Minuit not verbose
505  //gMinuit.mnexcm("SET PRI", arglist, 1, ierflg);
506  //gMinuit.mnexcm("SET NOW", arglist, 1, ierflg);
507  gMinuit.SetPrintLevel(-1);
508 
509  arglist[0] = 0.5; // Set error param for negative-log-likelihood
510  gMinuit.mnexcm("SET ERR", arglist, 1, ierflg);
511 
512  double step = 0.01;
513 
514  gMinuit.mnparm(0, "Norm", start[0], step, 0, 0, ierflg);
515  gMinuit.mnparm(1, "lgEa", start[1], step, 0, 0, ierflg);
516 
517  if (!iarray) {
518 
520 
521  gMinuit.mnparm(2, "g1", start[2], step, 0, 0, ierflg);
522  gMinuit.mnparm(3, "g2", start[3], step, 0, 0, ierflg);
523  gMinuit.mnparm(4, "lgEs", start[4], step, 0, 0, ierflg);
524  gMinuit.mnparm(5, "Dgamma", start[5], step, 0, 0, ierflg);
525 
526  } else if (modelfunctions[iarray] == StandardMultiSmooth) {
527 
528  gMinuit.mnparm(2, "lgEx", start[2], step, 0, 0, ierflg);
529  gMinuit.mnparm(3, "lgEs", start[3], step, 0, 0, ierflg);
530  gMinuit.mnparm(4, "g1", start[4], step, 0, 0, ierflg);
531  gMinuit.mnparm(5, "g2", start[5], step, 0, 0, ierflg);
532  gMinuit.mnparm(6, "g3", start[6], step, 0, 0, ierflg);
533  gMinuit.mnparm(7, "g4", start[7], step, 0, 0, ierflg);
534 
535  }
536 
537  } else {
538 
539  gMinuit.mnparm(2, "g1", start[2], step, 0, 0, ierflg);
540  gMinuit.mnparm(3, "g2", start[3], step, 0, 0, ierflg);
541  }
542 
543  gMinuit.SetFCN(FitFCN);
544  // Now ready for minimization step
545  arglist[0] = 10000;
546  arglist[1] = 1.;
547 
548  gMinuit.mnexcm("MINIMIZE", arglist, 2, ierflg);
549 
550  if (ierflg)
551  cout << "\t Spectrum fit failed during Minuit." << endl;
552 
553 
554  double fitParameters[N];
555  double fitParErrors[N];
556  for (int i = 0; i < N; i++)
557  gMinuit.GetParameter(i, fitParameters[i], fitParErrors[i]);
558 
559  parsFit.ResizeTo(N);
560 
561  for (int i = 0; i < N; i++) {
562  parsFit[i] = fitParameters[i];
563  parsErrorsFit[i] = fitParErrors[i];
564  }
565 
566  int ncol = vecLgE.GetNoElements();
567  TVectorD CorrFactor(ncol);
569 
570  if (computeCovStat) {
571 
572  TMatrixD cov(N, N);
573  gMinuit.mnemat(&cov[0][0], N);
574  UnfoldCorrectionFactorCoV.ResizeTo(ncol, ncol);
576  }
577 
578  return CorrFactor;
579 }
580 
581 void FitFCN(Int_t& npar, Double_t* gin, Double_t& f, Double_t* par, Int_t iflag)
582 {
583  f = Likelihood(par);
584 }
585 
586 
587 double Likelihood(double* pars)
588 {
589 
590  int ncol = vecLgE.GetNoElements();
591  TVectorD mwraws0 = FluxModel(modelfunctions[iarray], vecLgE, pars);
592 
593  for (int i = 0; i < ncol; ++i)
594  mwraws0[i] = mwraws0[i] * pow(10., vecLgE[i]) * log(10);
595 
596  TVectorD mwraws = kmatrix * mwraws0;
597  mwraws *= thLgE->GetBinWidth(1);
598 
599  int N = raw_nevents.GetNoElements();
600  TVectorD mws(N);
601  mws.Zero();
602 
603  for (int i = 0; i < ncol; ++i) {
604 
605  double ilgE = vecLgE[i];
606 
607  int bin = rawAxis_lgE->FindBin(ilgE);
608 
609  if (bin < 1)
610  continue;
611 
612  if (bin > N)
613  break;
614 
615  mws[bin - 1] += mwraws[i] * thLgE->GetBinWidth(1); // expected number of events (delta in poisson distrib.)
616 
617  }
618 
619  TVectorD like(N);
620  for (int i = 0; i < N; ++i)
621  like[i] = mws[i] - raw_nevents[i] * log(mws[i]);
622 
623  // neg-log-likelihood fit assuming Poisson fluctuations
624  return like.Sum();
625 
626 }
627 
629 {
630  cout << setprecision(3) << endl;
631 
632  double J0 = pow(10., parsFit[0]) / exposure;
633  double errorJ0 = J0 * log(10) * parsErrorsFit[0];
634 
635  if (!iarray) {
636 
638 
639  cout << endl;
640  cout << "\t Resulting parameters fitting the regular array flux model (old model): \n" << endl;
641  cout << "\t Flux normalization: " << J0 << " +- " << errorJ0 << endl;
642  cout << "\t Eankle: " << pow(10., parsFit[1]) << " +- " << pow(10., parsFit[1])*log(10)*parsErrorsFit[1] << " eV " << endl;
643  cout << "\t Esuppression: " << pow(10., parsFit[4]) << " +- " << pow(10., parsFit[4])*log(10)*parsErrorsFit[4] << " eV " << endl;
644  cout << "\t gamma1 " << parsFit[2] << " +- " << parsErrorsFit[2] << endl;
645  cout << "\t gamma2 " << parsFit[3] << " +- " << parsErrorsFit[3] << endl;
646  cout << "\t Delta_gamma " << parsFit[5] << " +- " << parsErrorsFit[5] << endl;
647  cout << "\n" << endl;
648 
649  } else if (modelfunctions[iarray] == StandardMultiSmooth) {
650 
651  cout << endl;
652  cout << "\t Resulting parameters fitting the ICRC 2017 folding model: \n" << endl;
653  cout << "\t Flux normalization: " << J0 << " +- " << errorJ0 << endl;
654  cout << "\t Eankle: " << pow(10., parsFit[1]) << " +- " << pow(10., parsFit[1])*log(10)*parsErrorsFit[1] << " eV " << endl;
655  cout << "\t Ex: " << pow(10., parsFit[2]) << " +- " << pow(10., parsFit[2])*log(10)*parsErrorsFit[2] << " eV " << endl;
656  cout << "\t Esuppression: " << pow(10., parsFit[3]) << " +- " << pow(10., parsFit[3])*log(10)*parsErrorsFit[3] << " eV " << endl;
657  cout << "\t gamma1 " << parsFit[4] << " +- " << parsErrorsFit[4] << endl;
658  cout << "\t gamma2 " << parsFit[5] << " +- " << parsErrorsFit[5] << endl;
659  cout << "\t gamma3 " << parsFit[6] << " +- " << parsErrorsFit[6] << endl;
660  cout << "\t gamma4 " << parsFit[7] << " +- " << parsErrorsFit[7] << endl;
661  cout << "\n" << endl;
662 
663  }
664 
665  } else {
666 
667  cout << endl;
668  cout << "\t Resulting parameters fitting the Infill array flux model: \n" << endl;
669  cout << "\t Flux normalization: " << J0 << " +- " << errorJ0 << endl;
670  cout << "\t Eankle: " << pow(10., parsFit[1]) << " +- " << pow(10., parsFit[1])*log(10)*parsErrorsFit[1] << " eV " << endl;
671  cout << "\t gamma1 " << parsFit[2] << " +- " << parsErrorsFit[2] << endl;
672  cout << "\t gamma2 " << parsFit[3] << " +- " << parsErrorsFit[3] << endl;
673  cout << "\n" << endl;
674 
675  }
676 }
const char * RegularDataFileName
const int Npar
TVectorD raw_staterrup_rebinned
double FluxModel(const modeltype mtype, double *x, double *par)
const int NParArray[2]
TVectorD raw_lgEs
const bool HeraldAnalysis
modeltype
const char * InfillDataFileName
const bool Rebinning[2]
TVectorD parsErrorsFit
const double SpectrumBinSize[2]
TVectorD GetSDCalPars(bool infill=false)
void poisson_uncertainty(double x, double &plow, double &pup)
Definition: Statistics.icc:1
const unsigned int npar
Definition: UnivRec.h:75
vector< t2list > out
output of the algorithm: a list of clusters
Definition: XbAlgo.cc:32
double Likelihood(double *pars)
TVectorD raw_staterrlow_rebinned
const double SpectrumBins[15][15]
double pow(const double x, const unsigned int i)
double exposure
const double IntXmax[2]
const modeltype modelfunctions[2]
const bool DoArray[2]
const double IntXmin[2]
TAxis * rawAxis_lgE
TMatrixD UnfoldCorrectionFactorCoV
int main(int argc, char *argv[])
Definition: DBSync.cc:58
double fParFitErrors[Npar]
TVectorD MinuitMinimization(double *start, bool computeCovStat)
TVectorD raw_flux_rebinned
TVectorD raw_staterrup
TVectorD UnfoldCorrectionFactorMax
const double SpectrumMin[2]
TVectorD raw_flux
TVectorD parsFit
TAxis * thLgE
TMatrixD propagate_covariance(TVectorD(*f)(TVectorD, const modeltype), TVectorD x, TMatrixD xcov, const modeltype mtype)
Definition: Statistics.icc:50
void PrintResults()
const int IntegrationSteps
TVectorD UnfoldCorrectionFactorMin
double(*)(double *, double *) FluxModels(const modeltype mtype)
double fParFit[Npar]
TMatrixD kResolutionMatrix(TVectorD pCal, TVectorD xos, double *resolutionOffset, const bool useResFromData, const bool infill)
TMatrixD kmatrix
TVectorD raw_staterrlow
const int BinNum[2]
void FitFCN(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
const bool ResolutionFromData
TVectorD vecLgE
TVectorD raw_lgEs_rebinned
TVectorD UnfoldCorrectionFactor
TVectorD raw_nevents_rebinned
const double SpectrumMax[2]
TVectorD raw_nevents
double fParFitInit[Npar]
TVectorD GetCorrectionFactor(const TVectorD x, const TMatrixD m, double *par, const modeltype mtype)

, generated on Tue Sep 26 2023.