PRD2020/UnfoldUtilities.hh
Go to the documentation of this file.
1 /* Utilities to unfold the vertical spectrum such as done for ICRC 2015 */
2 
3 /* Author: I. ValiƱo, based on functions provided by A. Schulz */
4 
5 string CodeUsed;
6 map <string, Double_t> mapParameters;
7 string Verbose = "no";
8 string SDFile;
11 string Model;
12 string MatrixType;
14 string BiasFlag;
17 string VersionInput = "standard";
18 string UseNewTriggers = "no";
19 string PrintCompact = "no";
20 TVectorD GetSDCalPars() {
21  //Calibration constants
22  TVectorD pCal(2);
23  pCal[0] = mapParameters["A"];
24  pCal[1] = mapParameters["B"];
25  return pCal;
26 }
27 
28 double InverseSdCalibration(const double lgE, TVectorD pCal) {
29  return (lgE - log10(pCal[0])) / pCal[1]; /* returns lgS38 or lgS35 */
30 }
31 
32 double ScaledErrorFunction(const double x, const std::vector<double>& pars) {
33  return 0.5 * (1 + TMath::Erf((x - pars[0] ) / pars[1]));
34 }
35 
37 // TRIGGER EFFICIENCY
39 double SDTriggerEfficiency_AveragedZenithAngle(const double lgE) {
40 //The functions can be used integrated in zenith angle
41  const double thmax = mapParameters["MaxZenith"] * TMath::DegToRad();
42  const double thmin = 0.;
43  const double thStep = 0.0005; //0.0005 delivers a result consistent with root methods within 0.01%.
44  double integralTheta = 0;
45  const TVectorD pCal = GetSDCalPars();
46  const bool oldTrig = ("no" == UseNewTriggers);
47 
48  for (double thIntegr = thmin; thIntegr < thmax; thIntegr += thStep) {
49  if (EfficiencyFlag == "ICRC17_SD1500")
50  integralTheta += SDTriggerEfficiencyICRC2017_SD1500(lgE, thIntegr, pCal) * thStep * TMath::Cos(thIntegr) * TMath::Sin(thIntegr);
51  if (EfficiencyFlag == "ICRC17_SD750")
52  integralTheta += SDTriggerEfficiencyICRC2017_SD750(lgE, thIntegr, pCal) * thStep * TMath::Cos(thIntegr) * TMath::Sin(thIntegr);
53  if (EfficiencyFlag == "ICRC19_SD750")
54  integralTheta += SDTriggerEfficiencyICRC2019_SD750(lgE, thIntegr, pCal, oldTrig) * thStep * TMath::Cos(thIntegr) * TMath::Sin(thIntegr);
55  if (EfficiencyFlag == "ICRC19_SD1500_June2019")
56  integralTheta += SD1500TriggerEfficiency_ICRC2019(lgE, thIntegr) * thStep * TMath::Cos(thIntegr) * TMath::Sin(thIntegr);
57  }
58  double fnorm = 0.5 * (pow(TMath::Sin(thmax), 2) - pow(TMath::Sin(thmin), 2));
59  return integralTheta / fnorm;
60 }
61 
62 double EfficiencyValues(double lgE, double zenith) {
63  const TVectorD pCal = GetSDCalPars();
64  double efficiency = 1;
65  const bool oldTrig = ("no" == UseNewTriggers);
66 
67  if (EfficiencyFlag == "ICRC17_SD1500")
68  efficiency = SDTriggerEfficiencyICRC2017_SD1500(lgE, zenith, pCal);
69  else if (EfficiencyFlag == "ICRC17_SD750")
70  efficiency = SDTriggerEfficiencyICRC2017_SD750(lgE, zenith, pCal);
71  else if (EfficiencyFlag == "ICRC19_SD1500_May2019")
72  efficiency = SD1500TriggerEfficiencyHybrids2019(lgE);
73  else if (EfficiencyFlag == "ICRC19_SD1500_June2019")
74  efficiency = SD1500TriggerEfficiency_ICRC2019(lgE, zenith);
75  else if (EfficiencyFlag == "ICRC19_SD750")
76  efficiency = SDTriggerEfficiencyICRC2019_SD750(lgE, zenith, pCal, oldTrig);
77  else if ( EfficiencyFlag == "TriggerEfficiency_TestExample" )
78  efficiency = TriggerEfficiency_TestExample(lgE);
79  else {
80  cerr << endl;
81  cerr << EfficiencyFlag << ": no valid efficiency parameterization chosen " << endl;
82  throw std::exception();
83  }
84  return efficiency;
85 }
86 
87 double EfficiencyValuesNoDeclDep(double lgE) {
88  //If values are zenith angle dependent average over the entire zenith angle range
89  double efficiency = 1;
90  if (EfficiencyFlag == "ICRC17_SD1500" ||
91  EfficiencyFlag == "ICRC17_SD750" ||
92  EfficiencyFlag == "ICRC19_SD1500_June2019" ||
93  EfficiencyFlag == "ICRC19_SD750")
95  else if (EfficiencyFlag == "ICRC19_SD1500_May2019")
96  efficiency = SD1500TriggerEfficiencyHybrids2019(lgE);
97  else if ( EfficiencyFlag == "TriggerEfficiency_TestExample" )
98  efficiency = TriggerEfficiency_TestExample(lgE);
99  else {
100  cerr << endl;
101  cerr << EfficiencyFlag << ": no valid efficiency parameterization chosen " << endl;
102  throw std::exception();
103  }
104 
105  return efficiency;
106 }
107 
109 // BIAS
111 TVectorD EnergyBias(TVectorD lgEs, TVectorD pCal) {
112  //used by the non-declination dependent matrix calculation
113  int ncol = lgEs.GetNoElements();
114  TVectorD biasEnergy(ncol);
115 
116  for (int i = 0; i < ncol; ++i) {
117  if (BiasFlag == "BiasICRC19_SD1500_preliminary") {
118  //calculates the average over cos2theta of bias for each energy
119  double integral = 0.;
120  double deltacos2theta = 0.001;
121  for (Double_t cos2theta = 0.25; cos2theta < 1; cos2theta += deltacos2theta) {
122  double costheta = sqrt(cos2theta);
123  integral += (HybridBias_2019_SD1500(lgEs[i], costheta, mapParameters["MaxZenith"]) - 1.) * deltacos2theta;
124  }
125  integral /= 0.75; //normalization
126  integral += 1.;
127 
128  if ( lgEs[i] > 18.4)
129  integral = 1.;
130  biasEnergy[i] = integral;
131  } else if (BiasFlag == "BiasICRC19_SD1500_Offline") {
132  //calculates the average over cos2theta of bias for each energy
133  double integral = 0.;
134  double deltacos2theta = 0.001;
135  for (Double_t cos2theta = 0.25; cos2theta < 1; cos2theta += deltacos2theta) {
136  double costheta = sqrt(cos2theta);
137  integral += (HybridBias_2019_11_06_Offline_SD1500(lgEs[i], costheta, mapParameters["MaxZenith"]) - 1.) * deltacos2theta;
138  }
139  integral /= 0.75; //normalization
140  integral += 1.;
141 
142  if ( lgEs[i] > 18.4)
143  integral = 1.;
144  biasEnergy[i] = integral;
145  } else if (BiasFlag == "BiasICRC19_SD1500_Herald") {
146  //calculates the average over cos2theta of bias for each energy
147  double integral = 0.;
148  double deltacos2theta = 0.001;
149  for (Double_t cos2theta = 0.25; cos2theta < 1; cos2theta += deltacos2theta) {
150  double costheta = sqrt(cos2theta);
151  integral += (HybridBias_2019_11_06_Herald_SD1500(lgEs[i], costheta, mapParameters["MaxZenith"]) - 1.) * deltacos2theta;
152  }
153  integral /= 0.75; //normalization
154  integral += 1.;
155 
156  if ( lgEs[i] > 18.4)
157  integral = 1.;
158  biasEnergy[i] = integral;
159  } else if (BiasFlag == "BiasICRC19_SD750") {
160  const double fdB = pCal[1];
161  biasEnergy[i] = HybridBias_2019_SD750(lgEs[i], fdB);
162  } else if (BiasFlag == "Bias_TestExample") {
163  //something...
164  //......
165  biasEnergy[i] = 1.;
166  } else if (BiasFlag == "TOZERO")
167  biasEnergy[i] = 1.;
168  else {
169  cerr << endl;
170  cerr << BiasFlag << ": no valid bias parameterization chosen " << endl;
171  throw std::exception();
172  }
173  }
174 
175  return biasEnergy;
176 }
177 
178 double EnergyBias_DD(double lgE, double cosTheta, TVectorD pCal) {
179  double bias = 1;
180  if (BiasFlag == "BiasICRC19_SD1500_preliminary")
181  bias = HybridBias_2019_SD1500(lgE, cosTheta, mapParameters["MaxZenith"]);
182  else if (BiasFlag == "BiasICRC19_SD1500_Offline")
183  bias = HybridBias_2019_11_06_Offline_SD1500(lgE, cosTheta, mapParameters["MaxZenith"]);
184  else if (BiasFlag == "BiasICRC19_SD1500_Herald")
185  bias = HybridBias_2019_11_06_Herald_SD1500(lgE, cosTheta, mapParameters["MaxZenith"]);
186  else if (BiasFlag == "BiasICRC19_SD750")
187  {
188  const double fdB = pCal[1];
189  bias = HybridBias_2019_SD750(lgE, fdB);
190  }
191  else if (BiasFlag == "Bias_TestExample")
192  bias = Bias_TestExample(lgE, cosTheta);
193  else if (BiasFlag == "TOZERO")
194  bias = 1;
195  else {
196  cerr << endl;
197  cerr << BiasFlag << ": no valid bias parameterization chosen " << endl;
198  throw std::exception();
199  }
200 
201  return bias;
202 }
203 
205 // SHOWER TO SHOWER FLUCTUATIONS
207 double ShowerToShowerFluctuation(const double lgE) {
208  double shsh = 0;
209  if (ShowerToShowerFlag == "ICRC17_SD1500Data") {
210  const double xmin = 16.5;
211  const double xmax = 20.5;
212  const double z = (lgE - xmin) / (xmax - xmin);
213  const double pars[2] = {0.2, 0.0783};
214  shsh = (1 - z) * pars[0] + z * pars[1];
215  } else if (ShowerToShowerFlag == "ICRC17_SD750Data")
216  shsh = 0.13;
217  else if (ShowerToShowerFlag == "TOZERO")
218  shsh = 0;
219  else {
220  cerr << endl;
221  cerr << ShowerToShowerFlag << ": no valid shower to shower parameterization chosen " << endl;
222  throw std::exception();
223  }
224  return shsh;
225 }
226 
228 // RESOLUTION
230 double ResolutionZenithDistrib(double lgE, double zenith) {
231  TVectorD pCal = GetSDCalPars();//only for data resolution
232  const double lgS38 = InverseSdCalibration(lgE, pCal);
233 
234  double res;
235  if (ResolutionFlag == "ICRC17_SD750Data")
236  res = DataSD750EnergyResolution_ICRC2017(lgE, zenith, pCal, lgS38);
237  else if (ResolutionFlag == "ICRC17_SD1500Data")
238  res = DataSD1500EnergyResolution(lgE, zenith, pCal, lgS38);
239  else if (ResolutionFlag == "ICRC17_SD750Simu")
240  res = SimulationSD750EnergyResolution_ICRC2017(lgE, zenith);
241  else if (ResolutionFlag == "ICRC17_SD1500Simu") //Zenith angle independent... Not necessary here in the zenith integration
242  res = SimulationSD1500EnergyResolution(lgE, zenith);
243  else if (ResolutionFlag == "Valerio12_11_2018")
244  res = Valerio12_11_2018(lgE);
245  else if (ResolutionFlag == "Hybrids_ICRC_2019_preliminary") //Zenith angle independent... Not necessary here in the zenith integration
246  res = Hybrids_ICRC_2019_SD1500(lgE);
247  else if (ResolutionFlag == "Hybrids_ICRC_2019_SD750")
248  res = Hybrids_ICRC_2019_SD750(lgE);
249  else if (ResolutionFlag == "Hybrids_ICRC_2019_Offline")
251  else if (ResolutionFlag == "Hybrids_ICRC_2019_Offline_05_07")
253  else if (ResolutionFlag == "Hybrids_ICRC_2019_Herald")
255  else if (ResolutionFlag == "Resolution_TestExample") //Zenith angle independent... Not necessary here in the zenith integration
256  res = Resolution_TestExample(lgE);
257  else {
258  cerr << endl;
259  cerr << ResolutionFlag << ": no valid resolution parameterization chosen " << endl;
260  throw std::exception();
261  }
262 
263  return res;
264 }
265 
266 double IntegrateEnergyResolution(const double lgE) {
267  const double thmax = mapParameters["MaxZenith"] * TMath::DegToRad();
268  const double thmin = 0.;
269  const double thStep = 0.0005;
270  double integralTheta = 0;
271  for (double thIntegr = thmin; thIntegr < thmax; thIntegr += thStep) {
272  integralTheta += ResolutionZenithDistrib(lgE, thIntegr) * thStep * TMath::Cos(thIntegr) * TMath::Sin(thIntegr);
273  }
274  double fnorm = 0.5 * (pow(TMath::Sin(thmax), 2) - pow(TMath::Sin(thmin), 2));
275  return integralTheta / fnorm;
276 }
277 
278 TVectorD EnergyResolution(TVectorD lgEs) {
279  int ncol = lgEs.GetNoElements();
280  TVectorD EnergyRes(ncol);
281 
282  for (int i = 0; i < ncol; ++i) {
283  double lgE = lgEs[i];
284  double Esd = pow(10., lgE);
285 
286  double relErrs1 = IntegrateEnergyResolution(lgE);
287  double relErrs2 = 0;
288  relErrs2 = ShowerToShowerFluctuation(lgE);
289 
290  double relErrs = TMath::Sqrt(pow(relErrs1, 2) + pow(relErrs2, 2));
291 
292  EnergyRes[i] = relErrs * Esd;
293  }
294 
295  return EnergyRes;
296 }
297 
298 double ResolutionValue(double lgE, double_t cosTheta) {
299  TVectorD pCal = GetSDCalPars();//only for data resolution
300  const double lgS38 = InverseSdCalibration(lgE, pCal);
301 
302  double resolution = 0;
303  if (ResolutionFlag == "ICRC17_SD1500Data")
304  resolution = DataSD1500EnergyResolution(lgE, acos(cosTheta), pCal, lgS38);
305  else if (ResolutionFlag == "ICRC17_SD750Data")
306  resolution = DataSD750EnergyResolution_ICRC2017(lgE, acos(cosTheta), pCal, lgS38);
307  else if (ResolutionFlag == "ICRC17_SD1500Simu")
308  resolution = SimulationSD1500EnergyResolution(lgE, acos(cosTheta));
309  else if (ResolutionFlag == "ICRC17_SD750Simu")
310  resolution = SimulationSD750EnergyResolution_ICRC2017(lgE, acos(cosTheta));
311  else if (ResolutionFlag == "Valerio12_11_2018")
312  resolution = Valerio12_11_2018(lgE);
313  else if (ResolutionFlag == "Hybrids_ICRC_2019_preliminary")
314  resolution = Hybrids_ICRC_2019_SD1500(lgE);
315  else if (ResolutionFlag == "Hybrids_ICRC_2019_SD750")
316  resolution = Hybrids_ICRC_2019_SD750(lgE);
317  else if (ResolutionFlag == "Hybrids_ICRC_2019_Offline")
318  resolution = Hybrids_ICRC_2019_Offline_11_06(lgE);
319  else if (ResolutionFlag == "Hybrids_ICRC_2019_Offline_05_07")
320  resolution = Hybrids_ICRC_2019_Offline_05_07(lgE);
321  else if (ResolutionFlag == "Hybrids_ICRC_2019_Herald")
322  resolution = Hybrids_ICRC_2019_Herald_11_06(lgE);
323  else if (ResolutionFlag == "Resolution_TestExample")
324  resolution = Resolution_TestExample(lgE);
325  else {
326  cerr << endl;
327  cerr << ResolutionFlag << ": no valid resolution parameterization chosen " << endl;
328  throw std::exception();
329  }
330  return resolution;
331 }
332 
333 
334 // Standard migration matrix
335 TMatrixD kResolutionMatrix(TVectorD pCal, TVectorD xos, double* resolutionOffset) {
336  int N = xos.GetNoElements();
337  TVectorD ses = EnergyResolution(xos);
338  TVectorD Ebias = EnergyBias(xos, pCal);
339  TMatrixD tmp_kmatrix(N, N);
340  for (int j = 0; j < N; ++j) {
341  double ex = pow(10, xos[j]);
342  double efficiency = EfficiencyValuesNoDeclDep(xos[j]);
343 
344  for (int i = 0; i < N; ++i) {
345  double ey = pow(10, xos[i]);
346  tmp_kmatrix[i][j] = TMath::Gaus(ey, ex * Ebias[j], ses[j], true) * ey * log(10.) * efficiency;
347  }
348  }
349 
350  /* ofstream outMatrixFile("matrixFile_OLD.txt");
351  for (int i = 0; i < N; ++i)
352  {
353  for (int j = 0; j < N; ++j)
354  outMatrixFile<<tmp_kmatrix[i][j]<<" ";
355 
356  outMatrixFile<<endl;
357  }
358  */
359  return tmp_kmatrix;
360 }
361 
362 // Zenith dependent migration matrix
363 TMatrixD kResolutionMatrixZenith(TVectorD pCal, TVectorD xos, double* resolutionOffset){
364  Int_t diagonalOfMatrix = 40;
365  Double_t fac = 1;
366  if (mapParameters["IntegrationSteps"]>10) {
367  fac = mapParameters["IntegrationSteps"]/10.;
368  diagonalOfMatrix = diagonalOfMatrix * fac;
369  }
370  cout << "Declination dependent migration matrix" << endl;
371  cout << "Calculates only +-" << diagonalOfMatrix << " elements out of " << xos.GetNoElements() << "around diagonal to speed up calculation! " << endl;
372  Double_t deltaTheta = 0.5;
373  Double_t maxtheta = mapParameters["MaxZenith"];
374  Double_t minTheta = mapParameters["MinZenith"];
375 
376  int N = xos.GetNoElements();
377  TMatrixD tmp_kmatrixTH(N, N);
378  TMatrixD tmp_kmatrixTH_norm(N, N);
379  for (int i = 0; i < N; ++i)
380  for (int j = 0; j < N; ++j) {
381  tmp_kmatrixTH_norm[i][j] = 0.;
382  tmp_kmatrixTH[i][j] = 0.;
383  }
384  for (int i = 0; i < N; ++i) {
385  double ey = pow(10, xos[i]);//reco
386  for (int j = 0; j < N; ++j) {
387  double ex = pow(10, xos[j]);//real
388  if (fabs(i - j) < diagonalOfMatrix)
389  for (Double_t th = minTheta; th < maxtheta; th += deltaTheta)
390  {
391  Double_t th_half = th + 0.5*deltaTheta;
392  Double_t cosTheta = cos(th_half*TMath::DegToRad());
393  double resolution = ResolutionValue(xos[j], cosTheta);
394  double sh_shfluct = ShowerToShowerFluctuation(xos[j]);
395  double tot_sigma = sqrt(pow(resolution, 2) + pow(sh_shfluct, 2));
396  double efficiency = EfficiencyValues(xos[j], th_half*TMath::DegToRad());
397  double bias = EnergyBias_DD(xos[j], cosTheta, pCal);
398  tmp_kmatrixTH_norm[i][j] += sin(2.* th_half*TMath::DegToRad()) * 2. * TMath::Pi() * deltaTheta;
399  tmp_kmatrixTH[i][j] += sin(2.* th_half*TMath::DegToRad()) * 2. * TMath::Pi() * deltaTheta * efficiency * TMath::Gaus(ey, ex * bias , tot_sigma * ex, true) * ey * log(10.);
400  }
401 
402  if (tmp_kmatrixTH_norm[i][j] > 0)
403  tmp_kmatrixTH[i][j] /= tmp_kmatrixTH_norm[i][j];
404  }
405  }
406 
407  ofstream outMatrixFile("matrixFile_FULL_TH.txt");
408  for (int i = 0; i < N; ++i)
409  {
410  for (int j = 0; j < N; ++j)
411  outMatrixFile<<tmp_kmatrixTH[i][j]<<" ";
412 
413  outMatrixFile<<endl;
414  }
415 
416  return tmp_kmatrixTH;
417 
418 }
419 
420 
421 
422 // Declination dependent migration matrix
423 TMatrixD kResolutionMatrixDD(TVectorD pCal, TVectorD xos, Double_t lat, Double_t deltaMin, Double_t deltaMax) {
424  Int_t diagonalOfMatrix = 40;
425 // To speed up! verify always if there is a bias...
426 // The edges of the diagonal should be always very small. In first approximation they can be neglected..
427  Double_t fac = 1;
428  if (mapParameters["IntegrationSteps"]>10) {
429  fac = mapParameters["IntegrationSteps"]/10.;
430  diagonalOfMatrix = diagonalOfMatrix * fac;
431  }
432  cout << "Declination dependent migration matrix" << endl;
433  cout << "Calculates only +-" << diagonalOfMatrix << " elements out of " << xos.GetNoElements() << "around diagonal to speed up calculation! " << endl;
434  Double_t deltah = 0.1;
435  Double_t deltadelta = 0.1;
436  int N = xos.GetNoElements();
437  TMatrixD tmp_kmatrixDD(N, N);
438  TMatrixD tmp_kmatrixDD_norm(N, N);
439  for (int i = 0; i < N; ++i)
440  for (int j = 0; j < N; ++j) {
441  tmp_kmatrixDD_norm[i][j] = 0.;
442  tmp_kmatrixDD[i][j] = 0.;
443  }
444 
445  for (int i = 0; i < N; ++i) {
446  double ey = pow(10, xos[i]);//reco
447  for (int j = 0; j < N; ++j) {
448  double ex = pow(10, xos[j]);//real
449  if (fabs(i - j) < diagonalOfMatrix)
450  for (Double_t h = 0; h < 2.*TMath::Pi(); h += deltah) { //integrate over h
451  for (Double_t delta = deltaMin; delta < deltaMax; delta += deltadelta) { // integrate over delta
452  Double_t cosTheta = sin(lat) * sin(delta) + cos(lat) * cos(delta) * cos(h);
453 
454  double resolution = ResolutionValue(xos[j], cosTheta);
455  double sh_shfluct = ShowerToShowerFluctuation(xos[j]);
456  double tot_sigma = sqrt(pow(resolution, 2) + pow(sh_shfluct, 2));
457  double efficiency = EfficiencyValues(xos[j], acos(cosTheta));
458  double bias = EnergyBias_DD(xos[j], cosTheta, pCal);
459 
460  if (acos(cosTheta) < mapParameters["MaxZenith"] * TMath::DegToRad() && acos(cosTheta) > 0.) {
461  tmp_kmatrixDD_norm[i][j] += deltah * deltadelta * cos (delta) * cosTheta;
462  tmp_kmatrixDD[i][j] += deltah * deltadelta * cos (delta) * cosTheta * efficiency * TMath::Gaus(ey, ex * bias , tot_sigma * ex, true) * ey * log(10.);
463  }
464  }
465  }
466  if (tmp_kmatrixDD_norm[i][j] > 0)
467  tmp_kmatrixDD[i][j] /= tmp_kmatrixDD_norm[i][j];
468  }
469  if (i % 25 == 0)
470  cout << i << endl;
471  }
472  /*
473  ofstream outMatrixFile("matrixFile_FULL_NEW.txt");
474  for (int i = 0; i < N; ++i)
475  {
476  for (int j = 0; j < N; ++j)
477  outMatrixFile<<tmp_kmatrixDD[i][j]<<" ";
478 
479  outMatrixFile<<endl;
480  }
481  */
482  return tmp_kmatrixDD;
483 }
484 
485 
486 // Zenith dependent migration matrix with J
487 // To produce a compact version of the matrix (Originally developed for the PRD paper - 2020)
488 void kResolutionMatrixZenith_J(TVectorD pCal, TVectorD xos, double* resolutionOffset,TF1 *FitFunctionFitted){
489 
490  double binSize = mapParameters["SpectrumBinSize"];//Bins in energy
491  int N = (mapParameters["MaxIntegration"] - mapParameters["MinIntegration"]) / binSize ;//Bins in energy
492  int binnumber = 10;//sub-bins in energy (Simpson calculation on the single energy bin)
493 
494  Double_t deltaTheta = 0.1;//bins in theta
495  Double_t maxtheta = mapParameters["MaxZenith"];
496  Double_t minTheta = mapParameters["MinZenith"];
497  Int_t numBinTot = (maxtheta - minTheta) / deltaTheta;
498 
499  TMatrixD tmp_kmatrixTH(N, N);
500  TMatrixD tmp_kmatrixTH_norm(N, N);
501  for (int i = 0; i < N; ++i)
502  for (int j = 0; j < N; ++j) {
503  tmp_kmatrixTH_norm[i][j] = 0.;
504  tmp_kmatrixTH[i][j] = 0.;
505  }
506 
507  for (int i = 0; i < N; ++i) {
508  double XoSi = mapParameters["MinIntegration"] + 0.5 * binSize + binSize * i;//reco
509  for (int j = 0; j < N; ++j) {
510  double XoSj = mapParameters["MinIntegration"] + 0.5 * binSize + binSize * j;//real
511 
512  double norm =0.;
513  double normE =0.;
514  double ey_low = pow(10, XoSi-0.5 * binSize);
515  double ey_high = pow(10, XoSi+0.5 * binSize);
516  double dE_integr = (ey_high - ey_low)/binnumber;
517 
518  double ey_lowT = pow(10, XoSj-0.5 * binSize);
519  double ey_highT = pow(10, XoSj+0.5 * binSize);
520  double dE_integrT = (ey_highT - ey_lowT)/binnumber;
521 
522  double integralE=0;
523  for(Int_t ww=0;ww<=binnumber;ww++)
524  {
525  double E_tmp = ey_low + ww * dE_integr;
526 
527  double integralEreal=0;
528  normE =0.;
529  for(Int_t w=0;w<=binnumber;w++)
530  {
531  double E_tmpT = ey_lowT + w * dE_integrT;
532  double logEreal = log10(E_tmpT);
533  double SpectrumJ = FitFunctionFitted->Eval(logEreal);
534  norm =0.;
535  double matrixTH =0.;
536  Int_t countTh=0;
537  for (Double_t th = minTheta; th <= maxtheta; th += deltaTheta)
538  {
539  Double_t th_rad=th*TMath::DegToRad();
540  Double_t cosTheta = cos(th_rad);
541  double resolution = ResolutionValue(logEreal, cosTheta);
542  double sh_shfluct = ShowerToShowerFluctuation(logEreal);
543  double tot_sigma = sqrt(pow(resolution, 2) + pow(sh_shfluct, 2));
544  double efficiency = EfficiencyValues(logEreal, th_rad);
545  double bias = EnergyBias_DD(logEreal, cosTheta, pCal);
546  if(countTh==0 || countTh==numBinTot)
547  {
548  norm += sin(2.* th_rad) * 2. * TMath::Pi()* SpectrumJ;
549  matrixTH += sin(2.* th_rad) * 2. * TMath::Pi() * efficiency * TMath::Gaus(E_tmp, E_tmpT * bias , tot_sigma * E_tmpT, true) * SpectrumJ ;
550  }
551  else
552  {
553  if(countTh%2)
554  {
555  norm += 4 * sin(2.* th_rad) * 2. * TMath::Pi() * SpectrumJ;
556  matrixTH += 4 * sin(2.* th_rad) * 2. * TMath::Pi() * efficiency * TMath::Gaus(E_tmp, E_tmpT * bias , tot_sigma * E_tmpT, true) * SpectrumJ;
557  }
558  else
559  {
560  norm += 2 * sin(2.* th_rad) * 2. * TMath::Pi() * SpectrumJ;
561  matrixTH += 2 * sin(2.* th_rad) * 2. * TMath::Pi() * efficiency * TMath::Gaus(E_tmp, E_tmpT * bias , tot_sigma * E_tmpT, true) * SpectrumJ;
562  }
563  }
564  countTh++;
565  }
566  norm*=deltaTheta/3.;
567  matrixTH*=deltaTheta/3.;
568 
569  if(w==0 || w==binnumber)
570  {
571  integralEreal+=matrixTH;
572  normE+=norm;
573  }
574  else
575  {
576  if(w%2)
577  {
578  integralEreal+=4.*matrixTH;
579  normE+=4*norm;
580  }
581  else
582  {
583  integralEreal+=2.*matrixTH;
584  normE+=2*norm;
585  }
586  }
587 
588  }
589  integralEreal*=dE_integrT/3.;
590  normE*=dE_integrT/3.;
591 
592 
593  if(ww==0 || ww==binnumber)
594  integralE+=integralEreal;
595  else
596  {
597  if(ww%2)
598  integralE+=4.*integralEreal;
599  else
600  integralE+=2.*integralEreal;
601  }
602 
603  }
604  integralE*=dE_integr/3.;
605 
606  if (normE > 0)
607  integralE/=normE;
608 
609  tmp_kmatrixTH[i][j] = integralE;
610 
611  }
612  }
613  ofstream outMatrixFile("matrixFile_FULL_TH_J.txt");
614  for (int i = 0; i < N; ++i)
615  {
616  for (int j = 0; j < N; ++j)
617  outMatrixFile<<tmp_kmatrixTH[i][j]<<" ";
618 
619  outMatrixFile<<endl;
620  }
621 
622 
623 }
624 
625 Double_t DirectionalExposure(Double_t lat, Double_t deltaMin, Double_t deltaMax) {
626  Double_t deltah = 0.001;
627  Double_t deltadelta = 0.00001;//To make the exposure calculation more precise
628  Double_t normalization=0;
629  const double tilt = -30 * TMath::DegToRad();
630  int countDelta=0;
631  Double_t exposure = 0.;
632 
633  for (Double_t delta = mapParameters["ExposureMinRangeDecl"]*TMath::DegToRad(); delta < mapParameters["ExposureMaxRangeDecl"]*TMath::DegToRad(); delta += 0.0001) {
634  for (Double_t h = 0; h < 2.*TMath::Pi(); h += 0.001) { //integrate over h
635  Double_t cosTheta = sin(lat) * sin(delta) + cos(lat) * cos(delta) * cos(h);
636  Double_t theta = acos(cosTheta);
637  if (acos(cosTheta) < mapParameters["MaxZenith"]* TMath::DegToRad() && acos(cosTheta) > 0.) {
638  double phi = atan2(sin(delta) * cos(lat) - cos(delta) * cos(h) * sin(lat), cos(delta) * sin(h));
639  normalization += 0.001 * 0.0001 * cos(delta) * cosTheta * (1 + 0.00348 * tan(theta) * cos(phi - tilt));
640  if(countDelta%10000000==0)
641  cout<<"Normalization calculation step "<<countDelta<<endl;
642 
643  countDelta++;
644 
645  }
646  }
647  }
648  cout<<"Normalization exposure integral "<< normalization<<endl;
649 
650  countDelta=0;
651  for (Double_t delta = deltaMin; delta < deltaMax; delta += deltadelta) {
652  for (Double_t h = 0; h < 2.*TMath::Pi(); h += deltah) { //integrate over h
653  Double_t cosTheta = sin(lat) * sin(delta) + cos(lat) * cos(delta) * cos(h);
654  Double_t theta = acos(cosTheta);
655  if (acos(cosTheta) < mapParameters["MaxZenith"]* TMath::DegToRad() && acos(cosTheta) > 0.) {
656  double phi = atan2(sin(delta) * cos(lat) - cos(delta) * cos(h) * sin(lat), cos(delta) * sin(h));
657  exposure += deltah * deltadelta * cos(delta) * cosTheta * (1 + 0.00348 * tan(theta) * cos(phi - tilt));
658  }
659 
660  if(countDelta%10000000==0)
661  cout<<"Exposure calculation step "<<countDelta<<endl;
662 
663  countDelta++;
664  }
665  }
666  cout << " Exposure " << mapParameters["Exposure"] * exposure / normalization << "km2 sr yr" << endl;
667  //return mapParameters["Exposure"] * exposure / normalization;
668  return mapParameters["Exposure"] * exposure / 2.35718;
669 }
670 
671 
672 Double_t DirectionalExposureZenith(Double_t thetaMin, Double_t thetaMax) {
673  Double_t deltatheta = 0.0001;
674  Double_t normalization=0;
675  for (Double_t theta = mapParameters["ExposureMinRangeZenith"]; theta < mapParameters["ExposureMaxRangeZenith"]; theta += deltatheta) {
676  normalization+=sin(2.*theta*TMath::DegToRad())*deltatheta * TMath::DegToRad();
677  }
678  cout<<"Normalization exposure integral "<< normalization<<endl;
679 
680  Double_t exposure = 0.;
681  for (Double_t theta = thetaMin; theta < thetaMax; theta += deltatheta) {
682  exposure+=sin(2.*theta*TMath::DegToRad())*deltatheta * TMath::DegToRad();
683  }
684 
685  cout << " Exposure " << mapParameters["Exposure"] * exposure / normalization << "km2 sr yr" << endl;
686 // return mapParameters["Exposure"] * exposure / normalization;
687  return mapParameters["Exposure"] * exposure / 0.75;
688 }
689 
690 
692  cerr << "\n---------------------------------------------------\n";
693  cerr << "------------------Parameter Map--------------------\n";
694  cerr << "---------------------------------------------------\n";
695 
696  std::map<string, Double_t>::iterator it = mapParameters.begin();
697  while (it != mapParameters.end()) {
698  std::string keyName = it->first;
699  double val = it->second;
700  cout << keyName << " :: " << val << endl;
701  it++;
702  }
703 
704  cout << "Model---------------------" << Model << endl;
705  cout << "MatrixType---" << MatrixType << endl;
706  cout << "ResolutionFlag------------" << ResolutionFlag << endl;
707  cout << "BiasFlag------------------" << BiasFlag << endl;
708  cout << "EfficiencyFlag------------" << EfficiencyFlag << endl;
709  cout << "ShowerToShowerFlag--------" << ShowerToShowerFlag << endl;
710  cout << "VersionInput--------------" << VersionInput << endl;
711  cout << "UseNewTriggers------------" << UseNewTriggers << endl;
712  cerr << "---------------------------------------------------\n";
713  cerr << "---------------------------------------------------\n";
714 }
715 
716 void LoadParam(string paramFileName) {
717  ifstream in;
718  in.open(paramFileName.c_str());
719  string paramString, line;
720 
721  while (!in.eof()) {
722  getline(in, line);
723  Int_t pos = line.find('#');
724  string lineNew = line.substr(0, pos);
725  if (lineNew.length()) {
726  Int_t pos2 = lineNew.find(' ');
727  string key = lineNew.substr(0, pos2);
728 
729  string lineNew2 = lineNew.substr(pos2, 1000);
730  Int_t posVal = lineNew2.find_first_not_of(' ');
731  string lineNew3 = lineNew2.substr(posVal, 1000);
732  Int_t posVal2 = lineNew3.find(' ');
733  string val = lineNew3.substr(0, posVal2);
734 
735  Double_t tmpVal;
736  if (key == "Code") { //if we read a string... Define a string variable
737  CodeUsed = val;
738  } else if (key == "DataFileName") {
739  SDFile = val;
740  } else if (key == "OutPutFileName") {
741  OutPutFileName = val;
742  } else if (key == "OutPutFileNameRebinned") {
744  } else if (key == "ModelFunction") {
745  Model = val;
746  } else if (key == "MatrixType") {
747  MatrixType = val;
748  } else if (key == "ResolutionFlag") {
749  ResolutionFlag = val;
750  } else if (key == "BiasFlag") {
751  BiasFlag = val;
752  } else if (key == "EfficiencyFlag") {
753  EfficiencyFlag = val;
754  } else if (key == "ShowerToShowerFlag") {
755  ShowerToShowerFlag = val;
756  } else if (key == "VersionInput") {
757  VersionInput = val;
758  } else if (key == "UseNewTriggers") {
759  UseNewTriggers = val;
760  } else if (key == "PrintCompact") {
761  PrintCompact= val;
762  } else if (key == "Verbose") {
763  Verbose = val;
764  } else { // if we read a number do nothing... Only add parameter into the config file.
765  istringstream stringstream(val.c_str());
766  stringstream >> tmpVal;
767  mapParameters.insert(make_pair(key.c_str(), tmpVal));
768  }
769  }
770  }
771 
772  if ("no" != Verbose)
774 
775 }
776 
777 
778 void ReadEventList(vector <double> &vLogESD, TH1D* th1, TH1D* th2, string FileName) {
779 
780  long int AugerId;
781  long int EventId;
782  int nst;
783  double lgE, S1000, dS1000, theta, phi, dec, ra;
784  Double_t A, B;
785  string labelA, labelB;
786  ifstream evtFile;
787 
788  vLogESD.clear();
789 
790  // test format. Minimal check: verify that the number of columns is compatible with expectations...
791  // The user is responsible for the content of the event file!
792  if ("no" != Verbose)
793  TestFormat(FileName, 0);
794 
795 
796  evtFile.open(FileName.c_str(), ios::in);
797  if (evtFile.fail()) {
798  cerr << endl;
799  cerr << FileName << ": no valid file name chosen " << endl;
800  throw std::exception();
801  }
802 
803  string headerline;
804  getline(evtFile, headerline);
805  headerline = headerline.substr(0, 1);
806  evtFile >> labelA >> A;
807  evtFile >> labelB >> B;
808  if (headerline != "#" || labelA != "A" || labelB != "B") {
809  cerr << endl;
810  cerr << FileName << " does not look to be formatted properly " << endl;
811  cerr << "Add header line and calibration parameters" << endl;
812  throw std::exception();
813  }
814  mapParameters.insert(make_pair(labelA.c_str(), A));
815  mapParameters.insert(make_pair(labelB.c_str(), B));
816 
817  Double_t maxDecl = mapParameters["MaxDeclination"];
818  Double_t minDecl = mapParameters["MinDeclination"];
819  Double_t maxZenith = mapParameters["MaxZenith"];
820  Double_t minZenith = mapParameters["MinZenith"];
821 
822  if (MatrixType == "Standard")
823  { //TODO
824  maxDecl = 9000.;
825  minDecl = -9000;
826  maxZenith = 9000.;
827  minZenith = -9000;
828  }
829  else if(MatrixType == "Zenith")
830  {
831  maxDecl = 9000.;
832  minDecl = -9000;
833  }
834  else if(MatrixType == "Declination")
835  {
836  maxZenith = 9000.;
837  minZenith = -9000;
838  }
839 
840  while (!evtFile.eof()) {
841 
842  evtFile >> AugerId >> EventId >> lgE >> S1000 >> dS1000 >> nst >> theta >> phi >> dec >> ra;
843 
844  if (HeraldAnalysis)
845  lgE = log10(lgE) + 18;
846 
847  if (!evtFile.eof()) {
848  if (dec < maxDecl && dec >= minDecl && theta<maxZenith && theta>=minZenith) {
849  th1->Fill(lgE);
850  th2->Fill(lgE);
851  if ( lgE >= th1->GetBinLowEdge(1) )
852  vLogESD.push_back(lgE);
853  }
854  }
855  }
856 
857  evtFile.close();
858 }
859 
860 
861 void ReadEventListICRC2019(vector <double> &vLogESD, TH1D* th1, TH1D* th2, string FileName) {
862 
863  long int AugerId;
864  long int EventId;
865  long int GPSTime;
866  int isHybrid;
867  double lgE, S1000, dS1000, theta, dtheta, phi, dphi, dec, ra, XCore, YCore, S1000_corr, S38, Nst, Nst_sat;
868  Double_t A, B;
869  string labelA, labelB;
870  ifstream evtFile;
871 
872  vLogESD.clear();
873 
874  // test format. Minimal check: verify that the number of columns is compatible with expectations...
875  // The user is responsible for the content of the event file!
876  if ("no" != Verbose)
877  TestFormat(FileName, 1);
878 
879  evtFile.open(FileName.c_str(), ios::in);
880  if (evtFile.fail()) {
881  cerr << endl;
882  cerr << FileName << ": no valid file name chosen " << endl;
883  throw std::exception();
884  }
885  string headerline;
886  getline(evtFile, headerline);
887  headerline = headerline.substr(0, 1);
888  evtFile >> labelA >> A;
889  evtFile >> labelB >> B;
890  if (headerline != "#" || labelA != "A" || labelB != "B") {
891  cerr << endl;
892  cerr << FileName << " does not look to be formatted properly " << endl;
893  cerr << "Add header line and calibration parameters" << endl;
894  throw std::exception();
895  }
896 
897  mapParameters.insert(make_pair(labelA.c_str(), A));
898  mapParameters.insert(make_pair(labelB.c_str(), B));
899 
900  Double_t maxDecl = mapParameters["MaxDeclination"];
901  Double_t minDecl = mapParameters["MinDeclination"];
902  Double_t maxZenith = mapParameters["MaxZenith"];
903  Double_t minZenith = mapParameters["MinZenith"];
904 
905  if (MatrixType == "Standard")
906  { //TODO
907  maxDecl = 9000.;
908  minDecl = -9000;
909  maxZenith = 9000.;
910  minZenith = -9000;
911  }
912  else if(MatrixType == "Zenith")
913  {
914  maxDecl = 9000.;
915  minDecl = -9000;
916  }
917  else if(MatrixType == "Declination")
918  {
919  maxZenith = 9000.;
920  minZenith = -9000;
921  }
922 
923  while (!evtFile.eof()) {
924 
925  evtFile >> AugerId >> EventId >> GPSTime >> isHybrid >> Nst >> Nst_sat >> lgE >> theta >> dtheta >> phi >> dphi >> XCore >> YCore >> ra >> dec >> S1000 >> dS1000 >> S1000_corr >> S38;
926 // evtFile >> AugerId >> EventId >> GPSTime>> isHybrid >> lgE >> theta >> dtheta >> phi >> dphi >> XCore >> YCore >> ra>> dec >> S1000 >> dS1000 >> S1000_corr >> S38;//PRELIMINARY VERSION FOR ICRC2019
927 
928  if (!evtFile.eof()) {
929  if (dec < maxDecl && dec >= minDecl && theta<maxZenith && theta>=minZenith) {
930  th1->Fill(lgE);
931  th2->Fill(lgE);
932  if ( lgE >= th1->GetBinLowEdge(1) )
933  vLogESD.push_back(lgE);
934  }
935  }
936  }
937  evtFile.close();
938 }
939 
940 
941 void TestFormat(string inputName, int flagversion) {
942  ifstream evtFile;
943  string headerline;
944  evtFile.open(inputName.c_str(), ios::in);
945  stringstream testString;
946  getline(evtFile, headerline);
947  getline(evtFile, headerline);
948  getline(evtFile, headerline);
949  getline(evtFile, headerline);
950  testString << headerline;
951  double x;
952  int countCol = 0;
953  cout << endl;
954 
955  while (testString >> x) {
956  cout << x << " ";
957  countCol++;
958  }
959  cout << endl;
960  cout << countCol << " columns in the input event file" << endl;
961 
962  cout << "Check consistency with... " << endl;
963  if (flagversion == 1)
964  cout << "evtFile >> AugerId >> EventId >> GPSTime>> isHybrid>> Nst>> Nst_sat >> lgE >> theta >> dtheta >> phi >> dphi >> XCore >> YCore >> ra>> dec >> S1000 >> dS1000 >> S1000_corr >> S38;" << endl;
965  if (flagversion == 0)
966  cout << "evtFile >> AugerId >> EventId >> lgE >> S1000 >> dS1000 >> nst >> theta >> phi >> dec >> ra;" << endl;
967  evtFile.close();
968 }
969 
970 
971 void PrintUsage(int nArgs) {
972  cerr << "The correct number of inputs were not found " << endl;
973  cerr << "Expected 2 and got " << nArgs << endl;
974  cerr << "Run this program as ./UnfoldSpectrum <parameter file>" << endl;
975 }
double SDTriggerEfficiency_AveragedZenithAngle(const double lgE)
double SD1500TriggerEfficiencyHybrids2019(const double lgE)
void PrintUsage(int nArgs)
string OutPutFileNameRebinned
string ShowerToShowerFlag
string PrintCompact
double ResolutionValue(double lgE, double_t cosTheta)
const bool HeraldAnalysis
TMatrixD kResolutionMatrixDD(TVectorD pCal, TVectorD xos, Double_t lat, Double_t deltaMin, Double_t deltaMax)
TVectorD EnergyResolution(TVectorD lgEs, const bool data, const bool infill)
string Verbose
void PrintMapParameters()
double ResolutionZenithDistrib(double *x, double *par)
double Hybrids_ICRC_2019_SD1500(const double lgE)
double EfficiencyValuesNoDeclDep(double lgE)
TVectorD GetSDCalPars(bool infill=false)
double SD1500TriggerEfficiency_ICRC2019(const double lgE, const double zenith)
void TestFormat(string, int)
double DataSD750EnergyResolution_ICRC2017(const double lgE, const double zenith, TVectorD pCal, double lgS35)
string ResolutionFlag
Double_t DirectionalExposureZenith(Double_t thetaMin, Double_t thetaMax)
double pow(const double x, const unsigned int i)
double EfficiencyValues(double lgE, double zenith)
double exposure
double Hybrids_ICRC_2019_SD750(const double lgE)
double HybridBias_2019_11_06_Herald_SD1500(double ESD, double coszenith, double maxZenith)
void LoadParam(string paramFileName)
double HybridBias_2019_11_06_Offline_SD1500(double ESD, double coszenith, double maxZenith)
double IntegrateEnergyResolution(const double lgE, const bool data, const bool infill)
static int binnumber
Definition: XbAlgo.cc:25
double DataSD1500EnergyResolution(const double lgE, const double zenith)
string UseNewTriggers
map< string, Double_t > mapParameters
string VersionInput
double HybridBias_2019_SD750(double lgE, double fdB)
double SDTriggerEfficiencyICRC2017_SD750(const double lgE, const double zenith, TVectorD pCal)
double SimulationSD1500EnergyResolution(const double lgE, const double zenith)
string BiasFlag
double InverseSdCalibration(const double lgE, TVectorD pCal)
double EnergyBias_DD(double lgE, double cosTheta, TVectorD pCal)
string SDFile
double SDTriggerEfficiencyICRC2017_SD1500(const double lgE, const double zenith, TVectorD pCal)
TVectorD EnergyBias(TVectorD lgEs, TVectorD pCal, const bool infill)
double ScaledErrorFunction(const double x, const std::vector< double > &pars)
string OutPutFileName
double ShowerToShowerFluctuation(const double lgE)
void ReadEventListICRC2019(TH1D *th1, TH1D *th2, string FileName)
double SimulationSD750EnergyResolution_ICRC2017(const double lgE, const double zenith)
void ReadEventList(TH1D *th1, TH1D *th2, string FileName)
TMatrixD kResolutionMatrix(TVectorD pCal, TVectorD xos, double *resolutionOffset, const bool useResFromData, const bool infill)
double Valerio12_11_2018(const double lgE)
double norm(utl::Vector x)
Double_t DirectionalExposure(Double_t lat, Double_t deltaMin, Double_t deltaMax)
TMatrixD kResolutionMatrixZenith(TVectorD pCal, TVectorD xos, double *resolutionOffset)
double HybridBias_2019_SD1500(double ESD, double coszenith, double maxZenith)
void kResolutionMatrixZenith_J(TVectorD pCal, TVectorD xos, double *resolutionOffset, TF1 *FitFunctionFitted)
double Hybrids_ICRC_2019_Offline_05_07(const double lgE)
double Resolution_TestExample(const double lgE)
string CodeUsed
double Hybrids_ICRC_2019_Herald_11_06(const double lgE)
string Model
double Hybrids_ICRC_2019_Offline_11_06(const double lgE)
double Bias_TestExample(double ESD, double coszenith)
string MatrixType
double TriggerEfficiency_TestExample(const double lgE)
string EfficiencyFlag
double SDTriggerEfficiencyICRC2019_SD750(const double lgE, const double zenith, TVectorD pCal, bool oldTrig)

, generated on Tue Sep 26 2023.