DAS  3.0
Das Analysis System
ResponseFit

Description

Performs a double-sided Crystal-Ball fit of the given response step by step. Three methods are provided to fit the gaussian core and each of the power- law tails.

+ Inheritance diagram for ResponseFit:
+ Collaboration diagram for ResponseFit:

Public Types

enum  {
  N = 0, MU, SIGMA, KL,
  NL, KR, NR, NPARS
}
 
enum  Status { failed = 0b0000, core = 0b0001, LHStail = 0b0010, RHStail = 0b0100 }
 

Public Member Functions

 ResponseFit (const unique_ptr< TH1 > &h, ostream &cout)
 
void gausCore ()
 
void SSCB ()
 
void DSCB ()
 
bool good () const override
 

Private Member Functions

void Write (const char *) override
 

Additional Inherited Members

- Public Attributes inherited from AbstractFit
const std::unique_ptr< TH1 > & h
 
std::uint32_t status
 
std::ostream & cout
 
double * p
 
double * e
 
std::unique_ptr< TF1 > f
 
std::optional< double > chi2ndf
 
std::optional< double > chi2ndfErr
 
std::pair< float, float > interval
 
- Protected Member Functions inherited from AbstractFit
 AbstractFit (const unique_ptr< TH1 > &h, ostream &cout, int npars)
 
virtual ~AbstractFit ()
 
void fit (std::pair< float, float >, const char *)
 

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
MU 
SIGMA 
KL 
NL 
KR 
NR 
NPARS 
111  {
112  N = 0,
113  MU, SIGMA,
114  KL, NL, KR, NR,
115  NPARS
116  };

◆ Status

enum Status
Enumerator
failed 
core 
LHStail 
RHStail 
118  {
119  failed = 0b0000,
120  core = 0b0001,
121  LHStail = 0b0010,
122  RHStail = 0b0100,
123  };

Constructor & Destructor Documentation

◆ ResponseFit()

ResponseFit ( const unique_ptr< TH1 > &  h,
ostream &  cout 
)
inline

Preparing for fit, setting ranges. Assuming response is centered around 1

Todo:
tune range?
128  :
130  {
131  // Calculate 1st & 2nd derivatives of the log(h)
132  unique_ptr<TH1> logd = DerivativeFivePointStencil(h, safelog), // 1st derivative of log(h)
133  logdd = DerivativeFivePointStencil(logd ); // 2nd derivative of log(h)
134  logd->Smooth();
135  logd->Write("logd");
136  logdd->Write("logdd");
137 
138  double mu = h->GetMean(),
139  sigma = h->GetStdDev();
140 
141  float rmin = 0.65, rmax = 1.5;
142  interval = findDLogExtrema(logd, mu, {rmin,rmax});
143 
144  // Initial estimate on the tail parameters
145  static auto LHS = make_unique<TF1>("tail", "[0]*exp( [1]*x)", 0., rmin),
146  RHS = make_unique<TF1>("tail", "[0]*exp(-[1]*x)", rmax, 2.);
147  h->Fit(LHS.get(), "N0QR");
148  h->Fit(RHS.get(), "N0QR");
149 
150  f = make_unique<TF1>("f", DAS::DoubleCrystalBall::Distribution(),
151  interval.first, interval.second, NPARS);
152  p[N ] = 1.; e[N ] = 0.001;
153  p[MU ] = mu; e[MU ] = h->GetMeanError();
154  p[SIGMA] = sigma; e[SIGMA] = h->GetStdDevError();
155  p[KL ] = interval.first; e[KL ] = sigma;
156  p[NL ] = LHS->GetParameter(1); e[NL ] = LHS->GetParError(1);
157  p[KR ] = interval.second; e[KR ] = sigma;
158  p[NR ] = RHS->GetParameter(1); e[NR ] = RHS->GetParError(1);
159  f->SetParameters(p);
160  f->SetParErrors (e);
161 
162  f->SetParName(N , "N" );
163  f->SetParName(MU , "#mu" );
164  f->SetParName(SIGMA, "#sigma");
165  f->SetParName(KL , "k_{L}" );
166  f->SetParName(NL , "N_{L}" );
167  f->SetParName(KR , "k_{R}" );
168  f->SetParName(NR , "N_{R}" );
169 
170  f->SetNpx(2000); // Increase points used to draw TF1 object when saving
171 
172  // The Integral of a DSCB function using the DSCB parameters from fit.
173  auto IDSCB = make_unique<TF1>("DSCB_Integral", DAS::DoubleCrystalBall::Integral(), 0., 2., NPARS-1);
174  IDSCB->SetParameters(p);
175  IDSCB->SetLineColor(f->GetLineColor());
176  IDSCB->SetLineStyle(f->GetLineStyle());
177 
178  IDSCB->Write("DSCB_Integral");
179  }

Member Function Documentation

◆ DSCB()

void DSCB ( )

Crystal-Ball fit with tail on the RHS

The fit performance is scanned for all possible RHS boundaries.

244 {
245  f->SetParLimits(N, min(0.9,p[N]), max(1.1,p[N]));
246  if ((status & Status::LHStail) == Status::LHStail)
247  f->SetParLimits(KL, p[KL]-0.5*p[SIGMA], p[KL]+0.5*p[SIGMA]);
248  else {
249  f->FixParameter(KL, p[KL]);
250  f->FixParameter(NL, p[NL]);
251  }
252 
253  auto lastChi2ndf = chi2ndf;
254  float L = interval.first;
255  int BinL = h->FindBin(L);
256  for (int BinR = h->FindBin(interval.second); BinR <= h->GetNbinsX(); ++BinR) {
257  if (h->GetBinContent(BinR) == 0) continue;
258  if (BinR - BinL < f->GetNumberFreeParameters()) continue; // Fit range should include more bins than the number of params we want to fit
259  float R = h->GetBinLowEdge(BinR+1);
260  if (R <= p[MU]) continue; // if true, range doesnt make sense, skip fit
261 
262  f->SetParLimits(KR, p[MU], R);
263  f->SetParLimits(NR, 1.001, min(1e3,p[NR]*2));
264  fit({L, R}, __func__); // Fit response distribution in given range
265  }
266 
267  if (!chi2ndf || *chi2ndf == *lastChi2ndf) return;
268  status |= Status::RHStail;
269  Write(__func__);
270 }

◆ gausCore()

void gausCore ( )

Get Gaussian core parameters.

194 {
195  f->SetParLimits(N , 0.9, 1.1);
196  f->SetParLimits(MU , p[MU]-0.5*p[SIGMA], p[MU]+0.5*p[SIGMA]);
197  f->SetParLimits(SIGMA, 0.5*p[SIGMA], 2*p[SIGMA]);
198  f->FixParameter(KL, p[KL]);
199  f->FixParameter(NL, p[NL]);
200  f->FixParameter(KR, p[KR]);
201  f->FixParameter(NR, p[NR]);
202 
203  fit(interval, __func__);
204 
205  if (!chi2ndf) return;
206  status |= Status::core;
207  Write(__func__);
208 }

◆ good()

bool good ( ) const
inlineoverridevirtual

Reimplemented from AbstractFit.

185 { return AbstractFit::good() && *chi2ndf < 1000; }

◆ SSCB()

void SSCB ( )

Crystal-Ball fit with tail on the LHS

The fit performance is scanned for all possible LHS boundaries.

215 {
216  f->SetParLimits(N , min(0.9,p[N]), max(1.1,p[N]));
217  f->SetParLimits(MU , p[MU]-0.1*p[SIGMA], p[MU]+0.1*p[SIGMA]);
218  f->SetParLimits(SIGMA, 0.5*p[SIGMA], 1.5*p[SIGMA]);
219 
220  auto lastChi2ndf = chi2ndf;
221  float R = interval.second;
222  int BinR = h->FindBin(R);
223  for (int BinL = h->FindBin(interval.first); BinL > 0; --BinL) {
224  if (h->GetBinContent(BinL) == 0) continue;
225  if (BinR - BinL < f->GetNumberFreeParameters()) continue; // Fit range should include more bins than the number of params we want to fit
226  float L = h->GetBinLowEdge(BinL);
227  if (L >= p[MU]) continue; // if true, range doesnt make sense, skip fit
228 
229  f->SetParLimits(KL, L, p[MU]);
230  f->SetParLimits(NL, 1.001, min(1e3,p[NL]*2));
231  fit({L, R}, __func__); // Fit response distribution in given range
232  }
233 
234  if (!chi2ndf || *chi2ndf >= *lastChi2ndf) return;
235  status |= Status::LHStail;
236  Write(__func__);
237 }

◆ Write()

void Write ( const char *  name)
overrideprivatevirtual

Write best current estimate in current directory.

Four color codes are used to categorize fits on their final state (after all 3 fits are performed):

  • Red for a failed fit (all fit stages failed, or fit quality did not pass some criteria, e.g., chi2/ndf)
  • Magenta a successful Gaussian core fit (fits at stage 2 and 3 failed)
  • Orange a successful SSCB fit (stage 1 fit could either succeed or fail, and stage 3 failed)
  • Green a successful DSCB fit (stage 1 and 2 fits could have either failed or succeded)

Reimplemented from AbstractFit.

282 {
283  bool goodCore = (status & Status::core ) == Status::core ;
284  bool goodLHS = (status & Status::LHStail) == Status::LHStail;
285  bool goodRHS = (status & Status::RHStail) == Status::RHStail;
286  if (goodLHS && goodRHS) f->SetLineColor(kGreen+1);
287  else if (goodLHS xor goodRHS) f->SetLineColor(kOrange+1);
288  else if (goodCore ) f->SetLineColor(kMagenta+1);
289  else f->SetLineColor(kRed+1);
290 
292 
293  auto dlog = make_unique<TF1>("DLog", DAS::DoubleCrystalBall::DLog(), 0., 2., NPARS-1);
294  dlog->SetParameters(p);
295  dlog->SetLineColor(f->GetLineColor());
296  dlog->SetLineStyle(f->GetLineStyle());
297 
298  static TString dlogName = "DLog";
299  dlog->Write(dlogName + name);
300 }

The documentation for this struct was generated from the following file:
DAS::JetEnergy::findDLogExtrema
pair< float, float > findDLogExtrema(const unique_ptr< TH1 > &DLog, const double mu, const pair< float, float > Range)
Definition: fitJetResponse.cc:76
DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.name
name
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:48
DAS::DoubleCrystalBall::Integral
Definition: DoubleCrystalBall.h:93
DAS::JetEnergy::AbstractFit::fit
void fit(std::pair< float, float >, const char *)
Definition: fit.h:98
DAS::JetEnergy::ResponseFit::failed
@ failed
Definition: fitJetResponse.cc:119
DerivativeFivePointStencil
unique_ptr< TH1 > DerivativeFivePointStencil(const unique_ptr< TH1 > &h, double(*f)(double)=id)
Definition: resolution.h:49
DAS::JetEnergy::ResponseFit::MU
@ MU
Definition: fitJetResponse.cc:113
DAS::JetEnergy::ResponseFit::NL
@ NL
Definition: fitJetResponse.cc:114
DAS::JetEnergy::ResponseFit::Write
void Write(const char *) override
Definition: fitJetResponse.cc:281
DAS::JetEnergy::AbstractFit::Write
virtual void Write(const char *name)
Write the function to the current TDirectory.
Definition: fit.h:65
DAS::DoubleCrystalBall::Distribution
Definition: DoubleCrystalBall.h:83
DAS::JetEnergy::ResponseFit::N
@ N
Definition: fitJetResponse.cc:112
DAS::JetEnergy::AbstractFit::interval
std::pair< float, float > interval
best fit range
Definition: fit.h:32
DAS::JetEnergy::ResponseFit::core
@ core
Definition: fitJetResponse.cc:120
DAS::JetEnergy::AbstractFit::cout
std::ostream & cout
output stream, can be overwritten to reduce I/O
Definition: fit.h:25
DAS::JetEnergy::ResponseFit::LHStail
@ LHStail
Definition: fitJetResponse.cc:121
DAS::JetEnergy::ResponseFit::NR
@ NR
Definition: fitJetResponse.cc:114
DAS::JetEnergy::AbstractFit::good
virtual bool good() const
Definition: fit.h:34
DAS::JetEnergy::AbstractFit::chi2ndf
std::optional< double > chi2ndf
Definition: fit.h:31
DAS::JetEnergy::AbstractFit::e
double * e
uncertainties on best parameter estimates
Definition: fit.h:28
DAS::JetEnergy::ResponseFit::SIGMA
@ SIGMA
Definition: fitJetResponse.cc:113
DAS::JetEnergy::AbstractFit::AbstractFit
AbstractFit(const unique_ptr< TH1 > &h, ostream &cout, int npars)
Definition: fit.h:38
DAS::JetEnergy::AbstractFit::status
std::uint32_t status
a bit-field to be used in daughter classes
Definition: fit.h:24
DAS::DoubleCrystalBall::DLog
Definition: DoubleCrystalBall.h:106
DAS::JetEnergy::ResponseFit::KR
@ KR
Definition: fitJetResponse.cc:114
DAS::JetEnergy::AbstractFit::h
const std::unique_ptr< TH1 > & h
histogram ready to be fitted
Definition: fit.h:23
DAS::JetEnergy::ResponseFit::NPARS
@ NPARS
Definition: fitJetResponse.cc:115
DAS::JetEnergy::ResponseFit::RHStail
@ RHStail
Definition: fitJetResponse.cc:122
DAS::JetEnergy::ResponseFit::KL
@ KL
Definition: fitJetResponse.cc:114
DAS::JetEnergy::AbstractFit::p
double * p
best parameter estimation
Definition: fit.h:27
safelog
double safelog(double x)
Definition: resolution.h:19
DAS::JetEnergy::AbstractFit::f
std::unique_ptr< TF1 > f
Starting by passing Gaussian range.
Definition: fit.h:30