5 #include "RooRealVar.h"
6 #include "RooWorkspace.h"
7 #include "RooGaussModel.h"
8 #include "RooArgList.h"
10 #include "RooDataSet.h"
11 #include "RooDataHist.h"
12 #include "RooAddPdf.h"
13 #include "RooGaussian.h"
14 #include "RooMsgService.h"
26 using namespace RooFit;
43 double tlow , thigh ,
tpeak , nhits , meanToT , sigmaToT , max_ToT ;
45 int n_bins_right , n_bins_left , n_bins_before_peak , n_bins_afterpulse , max_n_bins_baseline , min_n_bins_baseline ,
n_sigma_peak , n_sigma_before_peak ;
47 double fit_region_min , fit_region_max , fit_range_min , fit_range_max , landau_m_min , landau_m_max ,
landau_s_min , landau_s_max , gaus_m_min , gaus_m_max , gaus_s_min , gaus_s_max , l_g_ratio_min , l_g_ratio_max , KS_threshold;
80 n_bins_before_peak(2) ,
81 n_bins_afterpulse (10),
82 max_n_bins_baseline (50),
83 min_n_bins_baseline (10),
85 n_sigma_before_peak (4) ,
86 fit_region_min (20.0),
87 fit_region_max (20.0) ,
89 fit_range_max (15.0) ,
104 saturated_hit (false) ,
105 saturated_tot (false) ,
124 if (analyzed ==
true){
143 TRandom3* r =
new TRandom3() ;
147 double high_x = h->GetBinCenter(h->GetNbinsX() - 1) ;
149 int nentries = h->Integral(1 , h->GetNbinsX() - 1) ;
151 if (h->GetBinCenter(1)>=0){
153 low_x = h->GetBinCenter(1) ;
157 TH1D* u = (TH1D*)h->Clone(
"uniform") ;
161 for (
int i = 0 ; i<nentries ; i++){
163 u->Fill(r->Uniform(low_x, high_x));
167 double proba = h->KolmogorovTest(u) ;
186 htime_full = time_vs_tot->ProjectionX(time_vs_tot->GetName() , 1 , time_vs_tot->GetNbinsY());
188 htime_full->SetDirectory(0) ;
200 if (analyzed ==
true) return ;
202 computeBaseline(htime_full) ;
204 int peakbin = htime_full->GetMaximumBin() ;
206 double height = htime_full->GetBinContent(peakbin) ;
208 int leftbin = peakbin - n_bins_left ;
210 int rightbin = peakbin + n_bins_right ;
212 tpeak = htime_full->GetBinCenter(peakbin) ;
214 tlow = htime_full->GetBinCenter(leftbin) ;
216 thigh = htime_full->GetBinCenter(rightbin) ;
218 htime_peak = (TH1D*)htime_full->Clone();
220 for (
int i=0 ; i<htime_peak->GetNbinsX() ; i++){
222 if (i<leftbin || i>rightbin){
224 htime_peak->SetBinContent(i,0);
230 htime_peak->SetName((std::string(
"htime_")+htime_peak->GetName()).c_str());
232 htime_peak->SetDirectory(0) ;
234 tot_peak = (TH1D*)time_vs_tot->ProjectionY((std::string(
"ToT_") + time_vs_tot->GetName()).c_str() , leftbin , rightbin) ;
236 tot_peak->SetDirectory(0);
238 meanToT = tot_peak->GetMean() ;
240 if (meanToT > max_ToT){
242 saturated_tot = true ;
246 sigmaToT = tot_peak->GetStdDev() ;
248 double p_KS = Kolmogorov_Smirnov_uniform(htime_full) ;
250 if (baseline.first==0 && baseline.second==0) weak = true ;
252 if (p_KS > KS_threshold) weak = true ;
254 if (height < (baseline.first + n_sigma_peak * baseline.second)) weak = true ;
256 for (
int i = 1 ; i<=n_bins_before_peak ; i++){
258 if (htime_full->GetBinContent(peakbin - n_bins_before_peak) < (baseline.first + n_sigma_before_peak * baseline.second)) weak = true ;
262 if (weak ==
false && htime_full->GetBinContent(peakbin + n_bins_afterpulse) == 0) saturated_hit =
true ;
264 if (weak ==
false && saturated_hit ==
false) is_good = true ;
266 nhits = htime_peak->Integral() ;
287 for (
int i=1 ; i<max_n_bins_baseline + 1 ; i++){
289 if(h->GetBinContent(i) > 0 ){
291 sum += h->GetBinContent(i);
293 bins.push_back(h->GetBinContent(i));
301 if(N < min_n_bins_baseline){
309 for (
int i=1 ; i<max_n_bins_baseline + 1 ; i++){
311 if(h->GetBinContent(h->GetNbinsX() - i)>0){
313 sum += h->GetBinContent(h->GetNbinsX() - i);
315 bins.push_back(h->GetBinContent(h->GetNbinsX() - i));
325 if(N < min_n_bins_baseline){
329 baseline.second = 0 ;
335 double bg_mean = sum/N ;
337 baseline.first = bg_mean ;
341 for (
int i=0 ; i<N ; i++){
343 sdev += pow((bins[i] - bg_mean) , 2) ;
347 baseline.second = sqrt(sdev/N);
357 if (fitted==
true) return ;
359 if (analyzed==
false) analyzeFast() ;
361 w.SetName((std::string(
"W_") + htime_full->GetName()).c_str());
363 double tpeak = htime_full->GetBinCenter(htime_full->GetMaximumBin()) ;
365 RooRealVar x(
"time" ,
"hit time" , tpeak - fit_region_min , tpeak + fit_region_max) ;
367 RooRealVar ml(
"mean landau" ,
"mean landau" , tpeak - landau_m_min , tpeak + landau_m_max);
369 RooRealVar sl(
"sigma landau" ,
"sigma landau" , landau_s_min , landau_s_max);
371 RooLandau L1(
"L1" ,
"Main_Landau" , x , ml , sl) ;
373 RooRealVar mg(
"mean Gauss" ,
"mean Gauss" , tpeak - gaus_m_min , tpeak + gaus_m_max);
375 RooRealVar sg(
"sigma Gauss" ,
"sigma Gauss" , gaus_s_min , gaus_s_max);
377 RooGaussian
G1(
"G1" ,
"Main_Gaussian" , x , mg , sg) ;
379 RooRealVar
c1(
"c1" ,
"c1" , l_g_ratio_min , l_g_ratio_max);
381 RooAddPdf M(
"Model" ,
"Model" , RooArgList(G1,L1) , RooArgList(c1));
385 RooDataHist Data (
"data" ,
"data" , *w.var(
"time") , Import(*htime_full));
387 w.pdf(
"Model")->fitTo(Data , Range(tpeak - fit_range_min , tpeak + fit_range_max) , RooFit::PrintLevel(-1000) , RooFit::PrintEvalErrors(-1000)) ;
389 RooRealVar Tmin (
"tmin" ,
"tmin" , tpeak - fit_range_min) ;
391 RooRealVar Tmax (
"tmax" ,
"tmax" , tpeak + fit_range_max) ;
393 RooRealVar Tpeak (
"tpeak" ,
"tpeak" , tpeak) ;
395 RooRealVar Mpv(
"mpv" ,
"mpv" , Tmin.getVal()) ;
397 RooRealVar Diff(
"peak-mpv" ,
"peak-mpv" , Tpeak.getVal() - Tmin.getVal()) ;
399 double max_pdfval = 0 ;
401 RooRealVar *var = (RooRealVar*)w.function(
"Model")->getObservables(RooArgSet(*w.var(
"time")))->first();
403 for(
double x = Tmin.getVal() ; x<Tmax.getVal() ; x+=0.1){
407 double pdfval = w.function(
"Model")->getVal(RooArgSet(*var)) ;
409 if (pdfval>max_pdfval){
411 max_pdfval = pdfval ;
465 return saturated_hit ;
595 return time_vs_tot->GetName();
bool IsGood()
Check if the peak is good.
NBPulse(TH2D *h)
Constructor.
string getName()
Get name of the hit time vs ToT histogram.
TH2D * gettime_vs_tot()
Get the hit time vs ToT distribution.
Analyzes the signal of a nanobeacon in a PMT.
void computeBaseline(TH1 *h)
Computes baseline of the hit time distribution measured by the PMT.
RooWorkspace getWorkspace()
Get all the information from the fit.
double getMeanToT()
Get the mean of the ToT distribution of the hits produced by the nanobeacon.
NBPulse()
Default constructor.
void fit()
Fits the hit nanobeacon signal to a model composed by a Landau and a Gauss functions.
void initialize()
Leaves the pulse ready for analysis by projecting the time vs ToT distribution to the time axis and m...
void analyzeFast()
Performs a fast analysis of the hit time distribution.
Double_t G1(const Double_t x)
Integral of method g1.
TH1D * gettot_peak()
Get the hit time distribution.
double Kolmogorov_Smirnov_uniform(TH1D *h)
Performs a Kolmogorov-Smirnov compatibility test between the hit time distribution and a uniform dist...
TH1D * getHtime_full()
Get the hit time distribution.
bool IsFitted()
Check if the peak is fitted.
bool IsWeak()
Check if the hit time distribution is weak.
TCanvas * c1
Global variables to handle mouse events.
TH1D * gettime_peak()
Get the hit time distribution.
pair< double, double > baseline
double getPeakTime()
Get the arrival time of the nanobeacon pulse.
bool IsSaturatedHit()
Check if the hit time distribution is saturated.
double getSigmaToT()
Get the standard deviation of the ToT distribution of the hits produced by the nanobeacon.