/////////////////////////////////////////////////////////////////////////////
//
// EEezUtils
//
// Author: Jason C. Webb <jwebb@iucf.indiana.edu>
//
// Utility class to hold miscellaneous analysis functions, such as SMD
// fitting routines, etc...
//
// Implemened as a singleton. Retrieve a pointer to the only instance
// of this class using the call
//
// EEezUtils *util = EEezUtils::instance();
//
/////////////////////////////////////////////////////////////////////////////
#include "EEezUtils.h"
#include "eeSinglePeak.h"
#include "eeDoublePeak.h"
#include <TH1F.h>
#include <TH2F.h>
#include <TF1.h>
#include <iostream>
ClassImp(EEezUtils);
EEezUtils *EEezUtils::sInstance = 0;
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
EEezUtils::EEezUtils()
{
// Class Constructor.
//
// Use EEezUtils *util = EEezUtils::instance() to
// get a pointer to this class.
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
EEezUtils *EEezUtils::instance()
{
// Returns the single instance of this class.
sInstance = (sInstance != 0) ? sInstance : new EEezUtils();
return sInstance;
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
TF1 *EEezUtils::fitSmdSingleInit( TH1F *histo, Option_t *opts )
{
// Initializes fit function for the specifed histogram.
Int_t verbose = 0;
if ( TString(opts).Contains("V") ) verbose++;
//-- For each bin, sum with its neighbors and enter into new
//-- histogram at that point. We use this for an initial
//-- guess at the mean of the distribution. We also try
//-- to reject mip signatures by requiring 3/3 strips to be
//-- nonzero.
Int_t nbins = histo -> GetNbinsX();
TH1F *sum3 = (TH1F *)histo -> Clone("sum3");
for ( Int_t i = 2; i <= nbins-1; i++ ) {
Float_t sum = 0.;
Int_t count = 0;
for ( Int_t j = i-1; j<=i+1; j++ ) if ( histo->GetBinContent(j) > 1.0 ) count++;
if ( count > 2 )
for ( Int_t j = i-1; j<=i+1; j++ ) sum += histo -> GetBinContent(j);
sum3 -> SetBinContent(i,sum);
}
//-- Maximum bin is here
Int_t max3 = sum3 -> GetMaximumBin();
Float_t mean3 = sum3 -> GetBinLowEdge(max3) + 0.5;
if ( verbose ) Info("fitSmdSingleInit","max bin = %i mean = %f", max3, mean3);
//-- Starting values for mean
Float_t start_mean = mean3;
Float_t min_mean = start_mean - 4.5;
Float_t max_mean = start_mean + 4.5;
Int_t bin_mean = sum3 -> FindBin( start_mean );
//-- Note: for now, just start with a constant for the width
Float_t start_sigma = 0.84;
Float_t min_sigma = 0.65 * start_sigma;
Float_t max_sigma = 2.00 * start_sigma;
//-- Estimate the yield
Float_t start_yield = 1.5 * sum3 -> GetBinContent( bin_mean );
Float_t min_yield = 0.1 * start_yield;
Float_t max_yield = 2.5 * start_yield;
TF1 *fit = new TF1("eeSinglePeak", eeSinglePeak, 0, 288, 5 );
fit -> SetLineColor(2);
fit -> SetFillStyle(0);
fit -> SetParameter( 0, start_yield );
fit -> SetParameter( 1, start_mean );
fit -> SetParameter( 2, start_sigma );
fit -> FixParameter( 3, 0.2 );
fit -> FixParameter( 4, 3.5 );
fit -> SetParameter( 3, 0.2 );
fit -> SetParameter( 4, 3.5 );
fit -> SetParLimits( 0, min_yield, max_yield );
fit -> SetParLimits( 1, min_mean, max_mean );
fit -> SetParLimits( 2, min_sigma, max_sigma );
delete sum3; // Clean up after self
return fit;
}
//////////////////////////////////////////////////////////////////
TF1 *EEezUtils::fitSmdSingle( TH1F *histo, Option_t *opts, Float_t min, Float_t max )
{
// Fit histogram of SMD response to a single shower-shape
// function. The fit is stored with the histogram, and
// a pointer to the fit is returned (actually, a pointer
// to the first function stored in the histogram, which
// should always be this one... i.e. no "+" in the opts
// arguement!).
//-- Restrict the range of the histogram
histo -> GetXaxis() -> SetRangeUser(min,max);
//-- Initialize the fit function
TF1 *fit = fitSmdSingleInit( histo, opts );
//-- Perform the fit
histo -> Fit(fit,TString(opts)+"0QN");
//-- Restrict the range of the fit to +/- 3 sigma and refit
Float_t mean = fit -> GetParameter(1);
Float_t sigma = fit -> GetParameter(2);
fit -> SetRange(mean-5.0*sigma,mean+5.0*sigma);
histo -> Fit(fit,opts);
//-- Unzoom the histogram
histo -> GetXaxis() -> UnZoom();
//-- And return with a pointer to the fit. It looks like,
//-- as usual, the root documentation is incomplete, and
//-- the TF1 is copied into the histogram. So we delete
//-- our copy of this function and return a pointer to
//-- the first function in the histogram's function list.
return fit;
}
TF1 *EEezUtils::fitSmdDouble( TH1F *histo, Option_t *opts, Float_t min, Float_t max, TF1 *infit )
{
// Fit histogram of SMD response to a double shower-shape
// function. The fit is stored with the histogram, and
// a pointer to the fit is returned.
//-- Begin by fitting the histogram to a single shower-
//-- shape distribution.
TF1 *fit;
if ( infit == NULL ) {
//-- Initialize parameters automatically
TF1 *single = fitSmdSingle(histo,opts);
//-- Compute the residual histogram
TString name = histo -> GetName();
TH1F *hresid = (TH1F *)histo -> Clone(name+"_residual");
assert(single);
hresid -> Add(single,-1.0);
//-- Fit the residual histogram
TF1 *fresid = fitSmdSingle(hresid,opts);
//-- Now initialize the double-peak fit based on the
//-- two single-peak fits
fit = new TF1("eeDoublePeak", eeDoublePeak, 0, 288, 10 );
fit -> SetLineColor(2);
fit -> SetFillStyle(0);
for ( Int_t i = 0; i < 5; i++ ) {
fit -> SetParameter( i, single -> GetParameter(i) );
Double_t min, max;
single -> GetParLimits(i,min,max);
fit -> SetParLimits( i, min, max );
}
for ( Int_t i = 0; i < 5; i++ ) {
fit -> SetParameter( i+5, fresid -> GetParameter(i) );
Double_t min, max;
fresid -> GetParLimits(i,min,max);
fit -> SetParLimits(i+5,min,max);
}
}
else {
fit = infit;
}
//-- Perform the fit
histo -> Fit( fit, opts );
delete fit;
return (TF1 *)histo -> GetListOfFunctions() -> At(0);
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.