CbmRoot
Loading...
Searching...
No Matches
PairAnalysisSignalExt.h
Go to the documentation of this file.
1/* Copyright (C) 2015-2016 Justus-Liebig-Universitaet Giessen, Giessen
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Julian Book [committer] */
4
5#ifndef PAIRANALYSISSIGNALEXT_H
6#define PAIRANALYSISSIGNALEXT_H
7
8//#############################################################
9//# #
10//# Class PairAnalysisSignalExt #
11//# Authors: #
12//# Julian Book, Uni Ffm / Julian.Book@cern.ch #
13//# #
14//#############################################################
15
16
17#include <TF1.h>
18#include <TH1F.h>
19#include <TMath.h>
20#include <TNamed.h>
21#include <TVectorD.h>
22
23#include "PairAnalysis.h"
25
26class TObjArray;
27class TPaveText;
28
30
31public:
46
48 {
65 PairAnalysisSignalExt(const char* name, const char* title);
66
68
70 // signal
71
72 void SetMCSignalShape(TH1F* hist)
73 {
74 fgHistSimPM = hist;
75 fHistSignalMC = hist;
76 }
77 void SetIntegralRange(Double_t min, Double_t max)
78 {
79 fIntMin = min;
80 fIntMax = max;
81 }
82 void SetPlotRange(Double_t min, Double_t max)
83 {
84 fPlotMin = min;
85 fPlotMax = max;
86 }
87 void SetRebin(Int_t factor) { fRebin = factor; }
88 void SetStatRebin(Double_t stat) { fRebinStat = stat; }
89 void SetRebin(TArrayD* limits) { fBinLimits = limits; }
90 void SetRebin(TVectorD* limits) { fBinLimits = new TArrayD(limits->GetNrows() - 1, limits->GetMatrixArray()); }
92 {
93 fPeakMethod = method;
94 fExtrFunc = sigF;
95 }
96 void SetMixingCorrection(Bool_t mixcorr = kTRUE) { fMixingCorr = mixcorr; }
97
98 // background
99
100 void SetMethod(EBackgroundMethod method) { fMethod = method; }
101 void SetNTrackRotations(Int_t iterations) { fNiterTR = iterations; }
102 void SetScaleBackgroundTo(EScalingMethod method, Double_t intMin, Double_t intMax, Double_t intMin2 = 0.,
103 Double_t intMax2 = 0.)
104 {
105 fSclMethod = method;
106 fScaleMin = intMin;
107 fScaleMax = intMax;
108 fScaleMin2 = intMin2;
109 fScaleMax2 = intMax2;
110 }
111 void SetCocktailContribution(TObjArray* arr, Bool_t subtract = kTRUE)
112 {
113 fArrCocktail = arr;
114 fCocktailSubtr = subtract;
115 }
116
117 // Getter
118
119 Bool_t IsCocktailSubtracted() const { return fCocktailSubtr; }
120 Double_t GetIntegralMin() const { return fIntMin; }
121 Double_t GetIntegralMax() const { return fIntMax; }
122 Int_t GetRebin() const { return fRebin; }
123 TArrayD* GetRebinLimits() const { return fBinLimits; }
126 Double_t GetScaleMin() const { return fScaleMin; }
127 Double_t GetScaleMax() const { return fScaleMax; }
128 Double_t GetScaleMin2() const { return fScaleMin2; }
129 Double_t GetScaleMax2() const { return fScaleMax2; }
130
131 // values of results
132
133 Double_t GetScaleFactor() const { return fScaleFactor; }
134 const TVectorD& GetValues() const { return fValues; }
135 const TVectorD& GetErrors() const { return fErrors; }
136 Double_t GetSignal() const { return fValues(0); }
137 Double_t GetSignalError() const { return fErrors(0); }
138 Double_t GetBackground() const { return fValues(1); }
139 Double_t GetBackgroundError() const { return fErrors(1); }
140 Double_t GetSignificance() const { return fValues(2); }
141 Double_t GetSignificanceError() const { return fErrors(2); }
142 Double_t GetSB() const { return fValues(3); }
143 Double_t GetSBError() const { return fErrors(3); }
144 Double_t GetMass() const { return fValues(4); }
145 Double_t GetMassError() const { return fErrors(4); }
146 Double_t GetMassWidth() const { return fValues(5); }
147 Double_t GetMassWidthError() const { return fErrors(5); }
148 Double_t GetMatchChi2NDF() const { return fValues(6); }
149 Double_t GetMatchChi2NDFError() const { return fErrors(6); }
150 static const char* GetValueName(Int_t i) { return (i >= 0 && i < 7) ? fgkValueNames[i] : ""; }
151
152 // objects
153
154 TH1* GetMCSignalShape() const { return fHistSignalMC; }
155 TH1* GetSignalHistogram() const { return fHistSignal; }
156 TH1* GetSoverBHistogram() const { return fHistSB; }
157 TH1* GetSignificanceHistogram() const { return fHistSgn; }
159 TH1* GetUnlikeSignHistogram() const { return fHistDataPM; }
160 TH1* GetCocktailHistogram() const { return fHistCocktail; }
161 TH1* GetRfactorHistogram() const { return fHistRfactor; }
162 TObject* GetPeakShape() const { return fgPeakShape; }
163
164
165 TObject* DescribePeakShape(ESignalExtractionMethod method = kMCFitted, Bool_t replaceValErr = kFALSE,
166 TH1F* mcShape = 0x0);
167 TPaveText* DrawStats(Double_t x1 = 0., Double_t y1 = 0., Double_t x2 = 0., Double_t y2 = 0.,
168 TString opt = "pRnbsSmrc");
169 Double_t ScaleHistograms(TH1* histRaw, TH1* histBackground, Double_t intMin, Double_t intMax);
170 Double_t ScaleHistograms(TH1* histRaw, TH1* histBackground, Double_t intMin, Double_t intMax, Double_t intMin2,
171 Double_t intMax2);
172
173 static TH1* MergeObjects(TH1* obj1, TH1* obj2, Double_t val = +1.);
174 void Print(Option_t* option = "") const;
175
184 //virtual void Process(TObjArray * const /*arrhist*/) = 0;
185 void Process(TObjArray* const arrhist);
186 void ProcessLS(); // like-sign method
187 void ProcessEM(); // event mixing method
188 void ProcessTR(); // track rotation method
189 void ProcessCocktail(); // cocktail method
190
191 void Draw(const Option_t* option = "");
192
193 TObject* FindObject(TObjArray* arrhist, PairAnalysis::EPairType type) const;
194 TObject* FindObjectByTitle(TObjArray* arrhist, TString ref);
195
196 // implemented to remove warnings
197 TObject* FindObject(const char*) const
198 {
199 TObject* bla = new TObject();
200 return bla;
201 }
202 TObject* FindObject(const TObject*) const
203 {
204 TObject* bla = new TObject();
205 return bla;
206 }
207
208protected:
209 TObjArray* fArrHists = NULL; // array of input histograms
210 TObjArray* fArrCocktail = NULL; // array of cocktail histograms
211 TH1* fHistSignal = NULL; // histogram of pure signal
212 TH1* fHistSB = NULL; // histogram of signal to bgrd
213 TH1* fHistSgn = NULL; // histogram of significance
214 TH1* fHistBackground = NULL; // histogram of background (fitted=0, like-sign=1, event mixing=2)
215 TH1* fHistCocktail = NULL; // histogram of cocktail
216 TH1* fHistDataPM = NULL; // histogram of selected +- pair candidates
217 TH1* fHistDataPP = NULL; // histogram of selected ++ pair candidates
218 TH1* fHistDataMM = NULL; // histogram of selected -- pair candidates
219 TH1* fHistDataME = NULL; // histogram of selected +- pair candidates from mixed event
220 TH1* fHistRfactor = NULL; // histogram of R factors
221 TH1* fHistSignalMC = NULL; // histogram of signal MC shape
222
223 TH1* fHistMixPM = NULL; // histogram of selected +- pair candidates
224 TH1* fHistMixPP = NULL; // histogram of selected ++ pair candidates
225 TH1* fHistMixMM = NULL; // histogram of selected -- pair candidates
226 TH1* fHistMixMP = NULL; // histogram of selected +- pair candidates
227 TH1* fHistDataTR = NULL; // histogram of selected +- pair candidates
228
229 TVectorD fValues; // values
230 TVectorD fErrors; // value errors
231
232 Double_t fIntMin = 0.; // signal extraction range min
233 Double_t fIntMax = 0.; // signal extraction range max
234 Double_t fPlotMin = 0.; // plot range lowest inv. mass
235 Double_t fPlotMax = 0.; // plot range highest inv. mass
236
237 Int_t fRebin = 1; // histogram rebin factor
238 Double_t fRebinStat = 1.; // rebin until bins have max. stat. error
239 TArrayD* fBinLimits = NULL; // bin limits from stat. rebinning
240
241 void ScaleBackground();
242 EBackgroundMethod fMethod = kLikeSign; // method for background substraction
243 EScalingMethod fSclMethod = kSclToRaw; // method for background normalization
244 Double_t fScaleMin = 0.; // min for scaling
245 Double_t fScaleMax = 0.; // max for scaling
246 Double_t fScaleMin2 = 0.; // min2 for scaling
247 Double_t fScaleMax2 = 0.; // max2 for scaling
248 Int_t fNiterTR = 1; // track rotation scale factor according to number of rotations
249 Double_t fScaleFactor = 1.; // scale factor of histogram scaling
250 Bool_t fMixingCorr = kFALSE; // switch for bin by bin correction with R factor
251 Bool_t fCocktailSubtr = kFALSE; // switch for cocktail subtraction
252
253 PairAnalysisFunction* fExtrFunc = NULL; // signal extraction function
254 ESignalExtractionMethod fPeakMethod = kBinCounting; // method for peak description and signal extraction
255 static TObject* fgPeakShape; // histogram or function used to describe the extracted signal
256 Bool_t fPeakIsTF1 = kFALSE; // flag
257
258 Bool_t fProcessed = kFALSE; // flag
259 static TH1F* fgHistSimPM; // simulated peak shape
260
261 void FillSignificance(TH1* hfill, TObject* signal, TH1* hbgrd);
262 void SetSignificanceAndSOB(); // calculate the significance and S/B
263 void SetFWHM(); // calculate the fwhm
264
265 static const char* fgkValueNames[7]; //value names
266 static const char* fgkBackgroundMethodNames[11]; // background estimator names
267
270
271 ClassDef(PairAnalysisSignalExt, 3) // Class for signal extraction
272};
273
274inline TObject* PairAnalysisSignalExt::FindObject(TObjArray* arrhist, PairAnalysis::EPairType type) const
275{
276 //
277 // shortcut to find a certain pair type object in array
278 //
279
280 // return ( arrhist->FindObject(Form("Pair.%s",PairAnalysis::PairClassName(type))) );
281 TString ref = Form("Pair.%s", PairAnalysis::PairClassName(static_cast<Int_t>(type)));
282 for (Int_t i = 0; i < arrhist->GetEntriesFast(); i++) {
283 if (!ref.CompareTo(arrhist->UncheckedAt(i)->GetTitle())) return arrhist->UncheckedAt(i);
284 }
285 return 0x0;
286}
287
288inline TObject* PairAnalysisSignalExt::FindObjectByTitle(TObjArray* arrhist, TString ref)
289{
290 //
291 // shortcut to find a certain pair type object in array
292 //
293 if (!arrhist) return 0x0;
294 // return ( arrhist->FindObject(Form("Pair.%s",PairAnalysis::PairClassName(type))) );
295 // TString ref=Form("Pair.%s",PairAnalysis::PairClassName(type));
296 for (Int_t i = 0; i < arrhist->GetEntriesFast(); i++) {
297 if (!ref.CompareTo(arrhist->UncheckedAt(i)->GetTitle())) { return arrhist->UncheckedAt(i); }
298 }
299 return 0x0;
300}
301
303{
304 //
305 // Calculate S/B and significance
306 //
307
308 // Signal/Background
309 fValues(3) = (fValues(1) > 0 ? fValues(0) / fValues(1) : 0);
310 Float_t epsSig = (fValues(0) > 0 ? fErrors(0) / fValues(0) : 0);
311 Float_t epsBknd = (fValues(1) > 0 ? fErrors(1) / fValues(1) : 0);
312 fErrors(3) = fValues(3) * TMath::Sqrt(epsSig * epsSig + epsBknd * epsBknd);
313 // Significance
314 fValues(2) = ((fValues(0) + fValues(1)) > 0 ? fValues(0) / TMath::Sqrt(fValues(0) + fValues(1)) : 0);
315 Float_t s = (fValues(0) > 0 ? fValues(0) : 0);
316 Float_t b = fValues(1);
317 Float_t se = fErrors(0);
318 Float_t be = fErrors(1);
319 // fErrors(2) = ((s+b)>0 ? TMath::Sqrt((s*(s+2*b)*(s+2*b)+b*s*s)/(4*TMath::Power(s+b,3))) : 0); // old implementation
320 fErrors(2) =
321 ((s + b) > 0 ? fValues(2) * TMath::Sqrt(be * be + TMath::Power(se * (s + 2 * b) / s, 2)) / 2 / (s + b) : 0);
322}
323
325{
326 //
327 // calculate the full width at half maximum (fwhm)
328 //
329
330 if (!fgPeakShape) return;
331
332 // case for TF1
333 if (fgPeakShape->IsA() == TF1::Class()) {
334 TF1* fit = (TF1*) fgPeakShape->Clone("fit");
335 TF1* pfit = (TF1*) fit->Clone("pfit");
336 TF1* mfit = (TF1*) fit->Clone("mfit");
337 for (Int_t i = 0; i < fit->GetNpar(); i++) {
338 pfit->SetParameter(i, fit->GetParameter(i) + fit->GetParError(i));
339 mfit->SetParameter(i, fit->GetParameter(i) - fit->GetParError(i));
340 }
341 Double_t maxX = fit->GetMaximumX();
342 Double_t maxY = fit->GetHistogram()->GetMaximum();
343 Double_t xAxMin = fit->GetXmin();
344 Double_t xAxMax = fit->GetXmax();
345 // fwhms
346 Double_t fwhmMin = fit->GetX(.5 * maxY, xAxMin, maxX);
347 Double_t fwhmMax = fit->GetX(.5 * maxY, maxX, xAxMax);
348 Double_t pfwhmMin = pfit->GetX(.5 * maxY, xAxMin, maxX);
349 Double_t pfwhmMax = pfit->GetX(.5 * maxY, maxX, xAxMax);
350 Double_t mfwhmMin = mfit->GetX(.5 * maxY, xAxMin, maxX);
351 Double_t mfwhmMax = mfit->GetX(.5 * maxY, maxX, xAxMax);
352 Double_t pError = TMath::Abs((fwhmMax - fwhmMin) - (pfwhmMax - pfwhmMin));
353 Double_t mError = TMath::Abs((fwhmMax - fwhmMin) - (mfwhmMax - mfwhmMin));
354 fValues(5) = (fwhmMax - fwhmMin);
355 fErrors(5) = (pError >= mError ? pError : mError);
356 delete fit;
357 delete pfit;
358 delete mfit;
359 }
360 else if (fgPeakShape->IsA() == TH1F::Class()) {
361 // th1 calculation
362 TH1F* hist = (TH1F*) fgPeakShape->Clone("hist");
363 Int_t bin1 = hist->FindFirstBinAbove(hist->GetMaximum() / 2);
364 Int_t bin2 = hist->FindLastBinAbove(hist->GetMaximum() / 2);
365 fValues(5) = hist->GetBinCenter(bin2) - hist->GetBinCenter(bin1);
366 fErrors(5) = 0.0; // not defined
367 delete hist;
368 }
369}
370
371inline void PairAnalysisSignalExt::FillSignificance(TH1* hfill, TObject* signal, TH1* hbgrd)
372{
377
378
379 /* hfill->Reset("CEIS"); */
380 hfill->SetYTitle(GetValueName(2));
381
382 Double_t s = 0.;
383 Double_t b = 0.;
384 Double_t se = 0.;
385 Double_t be = 0.;
386 for (Int_t i = 1; i <= hfill->GetNbinsX(); i++) {
387
388 if (signal->IsA() == TF1::Class()) s = static_cast<TF1*>(signal)->Eval(hfill->GetBinCenter(i));
389 else {
390 s = static_cast<TH1*>(signal)->GetBinContent(i);
391 se = static_cast<TH1*>(signal)->GetBinError(i);
392 }
393
394 b = hbgrd->GetBinContent(i);
395 be = hbgrd->GetBinError(i);
396
397 Double_t sgn = ((s + b) > 0. ? s / TMath::Sqrt(s + b) : 0.);
398 // printf("s %.3e b %.3e \t s/b: %.3e sgn %.3e \n",s,b,s/b,sgn);
399 hfill->SetBinContent(i, sgn);
400 hfill->SetBinError(
401 i, ((s + b) > 0. ? sgn * TMath::Sqrt(be * be + TMath::Power(se * (s + 2 * b) / s, 2)) / 2 / (s + b) : 0));
402 }
403}
404
405
406#endif
friend fscal max(fscal x, fscal y)
friend fscal sgn(fscal x)
friend fscal min(fscal x, fscal y)
ESignalExtractionMethod fPeakMethod
void SetNTrackRotations(Int_t iterations)
void Print(Option_t *option="") const
const TVectorD & GetErrors() const
static const char * GetValueName(Int_t i)
TArrayD * GetRebinLimits() const
void Process(TObjArray *const arrhist)
void SetMixingCorrection(Bool_t mixcorr=kTRUE)
void Draw(const Option_t *option="")
PairAnalysisSignalExt & operator=(const PairAnalysisSignalExt &c)
EBackgroundMethod GetMethod() const
void SetMethod(EBackgroundMethod method)
Double_t GetMassWidthError() const
Double_t ScaleHistograms(TH1 *histRaw, TH1 *histBackground, Double_t intMin, Double_t intMax)
ESignalExtractionMethod GetExtractionMethod() const
void SetMCSignalShape(TH1F *hist)
TObject * FindObject(const char *) const
Double_t GetSignificanceError() const
void SetRebin(TVectorD *limits)
void SetRebin(Int_t factor)
void SetExtractionMethod(ESignalExtractionMethod method, PairAnalysisFunction *sigF=0x0)
TPaveText * DrawStats(Double_t x1=0., Double_t y1=0., Double_t x2=0., Double_t y2=0., TString opt="pRnbsSmrc")
PairAnalysisFunction * fExtrFunc
TObject * FindObject(const TObject *) const
void SetRebin(TArrayD *limits)
void SetIntegralRange(Double_t min, Double_t max)
static const char * fgkValueNames[7]
void SetPlotRange(Double_t min, Double_t max)
void SetScaleBackgroundTo(EScalingMethod method, Double_t intMin, Double_t intMax, Double_t intMin2=0., Double_t intMax2=0.)
void SetCocktailContribution(TObjArray *arr, Bool_t subtract=kTRUE)
TObject * FindObject(TObjArray *arrhist, PairAnalysis::EPairType type) const
void FillSignificance(TH1 *hfill, TObject *signal, TH1 *hbgrd)
const TVectorD & GetValues() const
static TH1 * MergeObjects(TH1 *obj1, TH1 *obj2, Double_t val=+1.)
TObject * FindObjectByTitle(TObjArray *arrhist, TString ref)
static const char * fgkBackgroundMethodNames[11]
Double_t GetMatchChi2NDFError() const
TObject * DescribePeakShape(ESignalExtractionMethod method=kMCFitted, Bool_t replaceValErr=kFALSE, TH1F *mcShape=0x0)
Double_t GetBackgroundError() const
void SetStatRebin(Double_t stat)
static const char * PairClassName(Int_t i)