NAGASH 0.9.8
Next Generation Analysis System
Loading...
Searching...
No Matches
ProfileFitter.h
Go to the documentation of this file.
1//***************************************************************************************
4//***************************************************************************************
5
6#pragma once
7
8#include "NAGASH/Tool.h"
9#include "NAGASH/Global.h"
10#include "NAGASH/ThreadPool.h"
11
12#include "Minuit2/FCNBase.h"
13#include "Minuit2/FCNGradientBase.h"
14#include "Minuit2/FunctionMinimum.h"
15#include "Minuit2/MnUserParameterState.h"
16#include "Minuit2/MnPrint.h"
17#include "Minuit2/MnMigrad.h"
18#include "Minuit2/MnSimplex.h"
19#include "Minuit2/MnHesse.h"
20#include "Minuit2/MnMinos.h"
21#include "Minuit2/MnScan.h"
22#include "Minuit2/MnContours.h"
23#include "Minuit2/MnPlot.h"
24
25#include "Eigen/Dense"
26
27namespace NAGASH
28{
29 class ProfileFitter : public Tool
30 {
31 public:
33 enum class ParameterType
34 {
35 Nuisance,
36 Interest,
37 StatGamma,
40 };
47
49 {
50 public:
51 TString Name;
52 double Value;
53 double Error;
54 double Min;
55 double Max;
56 double Init;
58
61
62 enum class ExtrapStrategy
63 {
66 };
67
69 bool isFitted = false;
70 bool isFixed = false;
71
72 double GetLikelihood();
73 void SetStrategy(ExtrapStrategy str) { Strategy = str; }
74 static double GetLikelihood_Thread(Parameter *tpar) { return tpar->GetLikelihood(); }
75 };
76
78 {
79 public:
80 std::map<TString, double> Num_Map;
81
82 double GetCache(const TString &name) { return Num_Map[name]; }
83 void SaveCache(const TString &name, double val) { Num_Map.emplace(std::pair<TString, double>(name, val)); }
84 };
85
87 {
88 public:
89 TString Name;
90 std::vector<double> Data;
91 std::vector<double> Data_Stat;
92 std::vector<double> Profile;
93
94 class Sample
95 {
96 public:
97 TString Name;
98 std::vector<double> Nominal;
99 std::vector<double> Nominal_Stat;
100 std::vector<double> Profile;
101
102 std::map<Parameter *, bool> NeedSymmetrization_Map;
103 std::map<Parameter *, int> SmoothLevel_Map;
104
105 std::map<Parameter *, std::vector<double>> Variation_Nominal_Map;
106 std::map<Parameter *, std::vector<double>> Variation_Up_Map;
107 std::map<Parameter *, std::vector<double>> Variation_Down_Map;
108
109 std::map<Parameter *, std::vector<double>> Variation_Sigma_Map;
110 std::map<Parameter *, std::vector<std::vector<double>>> Variation_Map;
111
112 std::map<Parameter *, std::vector<std::shared_ptr<ProfileCache>>> Variation_Cache;
113
114 std::vector<Parameter *> Gamma_Vec;
115 Parameter *Norm_Par = nullptr;
116
117 bool isnominal_booked = false;
118
119 int Start_Index = -1;
120 int End_Index = -1;
121
122 int Rebin_Index = 1;
123
125
126 void SortVariations();
127 void GetProfile(std::map<TString, Parameter> &m_par);
128 static NAGASH::StatusCode GetProfile_Thread(Sample *tsample, std::map<TString, Parameter> &m_par)
129 {
130 tsample->GetProfile(m_par);
132 }
133
134 private:
135 double GetProfileBinVariation(int i, double aim_sigma, Parameter *par);
136 };
137
138 std::map<TString, Sample> Sample_Map;
139
140 bool isdata_booked = false;
141 bool isgamma_booked = false;
142
143 int N_Samples = 0;
144
145 int Start_Index = -1;
146 int End_Index = -1;
147
148 int Rebin_Index = 1;
149
150 void SortVariations();
151 double GetLikelihood();
152 int GetNbins() { return Data.size(); }
153 static double GetLikelihood_Thread(Observable *tobs)
154 {
155 for (int i = 0; i < tobs->Profile.size(); i++)
156 {
157 double sum = 0;
158 for (auto &samp : tobs->Sample_Map)
159 sum = sum + samp.second.Profile[i];
160 tobs->Profile[i] = sum;
161 }
162 return tobs->GetLikelihood();
163 }
164 void GetProfile(std::map<TString, Parameter> &m_par);
165
166 private:
167 bool USE_POISSON = true;
168 };
169
170 class PLH_FCN : public ROOT::Minuit2::FCNBase
171 {
172 public:
173 PLH_FCN(std::shared_ptr<ThreadPool> tpool,
174 std::shared_ptr<MSGTool> _msg_,
175 std::map<TString, Parameter> *par_map,
176 std::map<TString, Observable> *obs_map);
177 // function value for negative log likelihood
178 double operator()(const std::vector<double> &) const override;
179 // error defination
180 double Up() const { return 0.5; }
181
182 std::shared_ptr<MSGTool> MSGUser() const { return msg; }
183 void Reset()
184 {
185 NCall = 0;
186 Max_Log_Likelihood = -999999;
187 }
188
189 private:
190 std::map<TString, Parameter> *Par_Map;
191 std::map<TString, Observable> *Obs_Map;
192
193 std::shared_ptr<ThreadPool> pool;
194 std::shared_ptr<MSGTool> msg;
195
196 inline static std::recursive_mutex PrintMutex = std::recursive_mutex();
197
198 mutable double Max_Log_Likelihood = -999999;
199 mutable int NCall = 0;
200 };
201
202 ProfileFitter(std::shared_ptr<MSGTool> msg, int nthread = 1);
203 void FixParameter(TString name, double val);
204 void ReleaseParameter(TString name);
205 void BookParameter(TString name, double init, double min, double max, ParameterType type);
206 void BookParameterOfInterest(TString name, double init, double min, double max);
207 void BookNuisanceParameter(TString name);
208 void BookNuisanceParameter(TString name, TString gname);
209 void BookNormalizationParameter(TString name, double init, double min, double max);
210
211 void BookObservableVariation(TString name, TString samplename, const std::vector<double> &vec, TString parname, double sigma);
212 void BookObservableVariationFromUnc(TString name, TString samplename, const std::vector<double> &vec, const std::vector<double> &vec_unc, TString parname);
213 void BookObservableData(TString name, const std::vector<double> &vec, const std::vector<double> &vec_stat);
214 void BookObservableNominal(TString name, TString samplename, const std::vector<double> &vec, const std::vector<double> &vec_stat);
215
216 void BookObservableVariationNominal(TString name, TString samplename, const std::vector<double> &vec, TString parname)
217 {
218 BookObservableVariation(name, samplename, vec, parname, 0);
219 }
220 void BookObservableVariationUp(TString name, TString samplename, const std::vector<double> &vec, TString parname)
221 {
222 BookObservableVariation(name, samplename, vec, parname, 1);
223 }
224 void BookObservableVariationDown(TString name, TString samplename, const std::vector<double> &vec, TString parname)
225 {
226 BookObservableVariation(name, samplename, vec, parname, -1);
227 }
228
229 void SetGammaPrefix(TString samplename, TString prefix);
230 void LinkNormalizationSample(TString name, TString samplename);
231
233
234 void SetSymmetrization(TString obsname, TString samplename, TString parname, bool need = true);
235 void SymmetrizeVariation(std::vector<double> &up, std::vector<double> &down, std::vector<double> &norm);
236
237 void SetSmooth(TString obsname, TString samplename, TString parname, int slevel);
238 void SmoothVariation(std::vector<double> &var, std::vector<double> &norm, int level);
239
240 void SetObservableRange(TString name, int start, int end);
241 void RebinObservable(TString name, int index);
242
243 Parameter *GetParameter(TString name);
244 TString GetParameterName(int index);
246 void SetParameterGroup(TString gname, TString parname);
247 // Call This Function to Fit
248 void Fit(FitMethod method);
249
250 std::map<TString, double> EstimateUnc(const std::vector<TString> &par_vec, FitMethod method, int toy_num);
251 std::map<TString, double> EstimateUnc(TString g_name, FitMethod method, int toy_num);
252 // std::map<TString, double> EstimateUncParallel(TString g_name, FitMethod method, int toy_num);
253
254 double GetChi2(const std::map<TString, double> &par_val);
255 double GetChi2();
256
257 private:
258 std::map<TString, Parameter> Par_Map;
259 std::map<TString, Observable> Obs_Map;
260 std::map<TString, std::vector<TString>> Gamma_Map;
261 std::map<TString, std::vector<TString>> Norm_Map;
262 std::map<TString, std::vector<TString>> ParGroup_Map;
263
264 std::shared_ptr<ThreadPool> pool = nullptr;
265 int NTHREAD = 1;
266
267 double MAX_NUISANCE_SIGMA = 3.0;
268
271
272 Observable *InitializeNewObservable(TString name);
273 void PrintInfo();
274 bool Check();
275 void Prepare(FitMethod method);
276
277 void FitPLH(); // Profile Likelihood (PLH)
278 void FitACS(); // Analytical Chi-square (ACS)
279
280 // Eigen Elements for ACS
281 Eigen::MatrixXd Gamma_Matrix;
282 Eigen::MatrixXd V_Matrix;
283 Eigen::MatrixXd Q_Matrix;
284 Eigen::MatrixXd S_Matrix;
285 Eigen::MatrixXd C_Matrix;
286 Eigen::MatrixXd H_Matrix;
287 Eigen::MatrixXd Y0_Matrix;
288 Eigen::MatrixXd Lambda_Matrix;
289 Eigen::MatrixXd Rho_Matrix;
290 Eigen::MatrixXd Epsilon_Matrix;
291
292 Eigen::MatrixXd POI_Shift;
293 Eigen::MatrixXd Nuisance_Shift;
294
295 Eigen::MatrixXd POI_Cov_Matrix;
296 Eigen::MatrixXd Nuisance_Cov_Matrix;
297
298 void PrintResult();
299 };
300
301 inline void ProfileFitter::FixParameter(TString name, double val)
302 {
303 Parameter *tpar = GetParameter(name);
304 tpar->Value = val;
305 tpar->isFixed = true;
306 }
307
308 inline void ProfileFitter::ReleaseParameter(TString name)
309 {
310 Parameter *tpar = GetParameter(name);
311 tpar->isFixed = false;
312 }
313
314 inline void ProfileFitter::BookNormalizationParameter(TString name, double init, double min, double max)
315 {
316 BookParameter(name, init, min, max, ParameterType::Normalization);
317 }
318
319 inline void ProfileFitter::BookParameterOfInterest(TString name, double init, double min, double max)
320 {
321 BookParameter(name, init, min, max, ParameterType::Interest);
322 }
323
328 inline void ProfileFitter::BookNuisanceParameter(TString name, TString gname)
329 {
331 SetParameterGroup(gname, name);
332 }
333
334 inline ProfileFitter::PLH_FCN::PLH_FCN(std::shared_ptr<ThreadPool> tpool,
335 std::shared_ptr<MSGTool> _msg_,
336 std::map<TString, Parameter> *par_map,
337 std::map<TString, Observable> *obs_map)
338 {
339 pool = tpool;
340 msg = _msg_;
341 Par_Map = par_map;
342 Obs_Map = obs_map;
343 }
344}
Some global definitions.
std::map< Parameter *, std::vector< double > > Variation_Nominal_Map
std::map< Parameter *, bool > NeedSymmetrization_Map
std::map< Parameter *, std::vector< double > > Variation_Sigma_Map
std::map< Parameter *, std::vector< std::vector< double > > > Variation_Map
std::map< Parameter *, int > SmoothLevel_Map
double GetProfileBinVariation(int i, double aim_sigma, Parameter *par)
std::map< Parameter *, std::vector< double > > Variation_Up_Map
std::map< Parameter *, std::vector< double > > Variation_Down_Map
void GetProfile(std::map< TString, Parameter > &m_par)
std::map< Parameter *, std::vector< std::shared_ptr< ProfileCache > > > Variation_Cache
static NAGASH::StatusCode GetProfile_Thread(Sample *tsample, std::map< TString, Parameter > &m_par)
std::vector< double > Data_Stat
std::map< TString, Sample > Sample_Map
static double GetLikelihood_Thread(Observable *tobs)
std::vector< double > Profile
void GetProfile(std::map< TString, Parameter > &m_par)
static std::recursive_mutex PrintMutex
std::shared_ptr< MSGTool > MSGUser() const
PLH_FCN(std::shared_ptr< ThreadPool > tpool, std::shared_ptr< MSGTool > _msg_, std::map< TString, Parameter > *par_map, std::map< TString, Observable > *obs_map)
std::shared_ptr< MSGTool > msg
std::map< TString, Parameter > * Par_Map
std::map< TString, Observable > * Obs_Map
std::shared_ptr< ThreadPool > pool
double operator()(const std::vector< double > &) const override
static double GetLikelihood_Thread(Parameter *tpar)
void SetStrategy(ExtrapStrategy str)
void SaveCache(const TString &name, double val)
std::map< TString, double > Num_Map
double GetCache(const TString &name)
Tool for conducting profile likelihood fit.
void BookObservableData(TString name, const std::vector< double > &vec, const std::vector< double > &vec_stat)
void BookObservableVariation(TString name, TString samplename, const std::vector< double > &vec, TString parname, double sigma)
void FixParameter(TString name, double val)
Eigen::MatrixXd Nuisance_Cov_Matrix
Eigen::MatrixXd V_Matrix
TString GetParameterName(int index)
void SetSymmetrization(TString obsname, TString samplename, TString parname, bool need=true)
Eigen::MatrixXd Q_Matrix
Parameter::ExtrapStrategy POI_DEFAULT_STRATEGY
void ReleaseParameter(TString name)
Eigen::MatrixXd Nuisance_Shift
void SetGammaPrefix(TString samplename, TString prefix)
void BookNuisanceParameter(TString name)
void SetParameterGroup(TString gname, TString parname)
Eigen::MatrixXd Y0_Matrix
std::map< TString, std::vector< TString > > Norm_Map
void BookObservableVariationNominal(TString name, TString samplename, const std::vector< double > &vec, TString parname)
Eigen::MatrixXd S_Matrix
Eigen::MatrixXd Epsilon_Matrix
void BookNormalizationParameter(TString name, double init, double min, double max)
void BookParameterOfInterest(TString name, double init, double min, double max)
void SetParameterStrategy(TString name, Parameter::ExtrapStrategy str)
void BookObservableNominal(TString name, TString samplename, const std::vector< double > &vec, const std::vector< double > &vec_stat)
void Prepare(FitMethod method)
@ AnalyticalChiSquare
Analytical method, described in https://arxiv.org/abs/2307.04007, very fast.
@ ProfileLikelihood
Traditional profile likelihood.
@ AnalyticalBoostedProfileLikelihood
use analytical method first, then run profile likelihood fit on top of it.
void BookObservableVariationFromUnc(TString name, TString samplename, const std::vector< double > &vec, const std::vector< double > &vec_unc, TString parname)
Observable * InitializeNewObservable(TString name)
Parameter * GetParameter(TString name)
void RebinObservable(TString name, int index)
Eigen::MatrixXd Lambda_Matrix
void BookParameter(TString name, double init, double min, double max, ParameterType type)
Eigen::MatrixXd POI_Shift
std::map< TString, Observable > Obs_Map
void LinkNormalizationSample(TString name, TString samplename)
std::map< TString, Parameter > Par_Map
void SymmetrizeVariation(std::vector< double > &up, std::vector< double > &down, std::vector< double > &norm)
int GetNParameters(ParameterType type=ParameterType::Unknown)
Eigen::MatrixXd C_Matrix
std::shared_ptr< ThreadPool > pool
void BookObservableVariationUp(TString name, TString samplename, const std::vector< double > &vec, TString parname)
void SmoothVariation(std::vector< double > &var, std::vector< double > &norm, int level)
void SetObservableRange(TString name, int start, int end)
void Fit(FitMethod method)
void BookObservableVariationDown(TString name, TString samplename, const std::vector< double > &vec, TString parname)
Eigen::MatrixXd Gamma_Matrix
std::map< TString, double > EstimateUnc(const std::vector< TString > &par_vec, FitMethod method, int toy_num)
Estimate uncertainty decomposition using toy method.
ParameterType
Type of the parameter.
@ StatGamma
Statistical Gamma, used to represent the statistical uncertainties.
@ Normalization
Normalization parameter.
std::map< TString, std::vector< TString > > ParGroup_Map
Eigen::MatrixXd H_Matrix
std::map< TString, std::vector< TString > > Gamma_Map
void SetSmooth(TString obsname, TString samplename, TString parname, int slevel)
Eigen::MatrixXd POI_Cov_Matrix
Parameter::ExtrapStrategy NUISANCE_DEFAULT_STRATEGY
Eigen::MatrixXd Rho_Matrix
Provide interface for all tools in NAGASH.
Definition Tool.h:72
std::shared_ptr< MSGTool > msg
Definition Tool.h:88
StatusCode
Definition Global.h:76