Hi Robert, I have added the two following inline functions: Double_t *TFormula::GetParameters() {return fParams;} Double_t *TF1::GetParErrors() {return fParErrors;} Rene Brun Robert Feuerbach wrote: > > On Tue, 6 Mar 2001, Stephen Bailey wrote: > > Hello. > > > > I have a histogram which is comprised of signal and background. > > I have a template histogram for the background and a function > > shape for the signal. I would like to fit the template histogram > > and the signal function to the data histogram to get their > > relative normalizations. > > > > Is there a way to do this easily in ROOT? Thanks. > > > > Stephen > > > > Hi Stephen, > > I'm actually doing the same thing -- fitting a TH1 to another TH1 + some > arbitrary function. > > I ended up creating a TF1 that accesses a C-function (fitfunc), and > fitfunc then looks up the histogram and function, and adds them together. > Unfortunately, you have to use some sort of global variable pointer to > point to the appropriate template histogram, since the permitted > parameters for fitfunc are rather tightly specified by the TF1 contructor > you need to use: > > TF1 TF1(const char* name, Double_t (*)(Double_t*, Double_t*) fcn, Double_t > xmin = 0, Double_t xmax = 1, Int_t npar = 0) > > To give you an idea of what I do, an excerpt of my code is below. It isn't > the prettiest code you'll find, but it does the job. > > Also, I'd like to petition for a > TF1::GetParErrors(Double_t *eparams) > method, parallel to > TF1::GetParameters(Double_t *params) > > Good luck, > Rob Feuerbach > > //--------------------------------------------------------- > Double_t linear_bck(Double_t *x, Double_t parms[]); > > Double_t mmfitfunc(Double_t *x, Double_t parms[]); > > // create a namespace to hold all the "global variables" you'll need > // to keep track of which template histogram you are using. > // I'm fitting to 2(lambda_hist and sigma0_hist) + bckgrnd function > > namespace MMWQTemplate { > TDirectory *directory; // directory template histograms are in > > TH1 *lambda_hist, *sigma0_hist; // template histos > Double_t (*backgrnd_func)(Double_t *x, Double_t parms[]); > Int_t nbck_params; > > TF1 *fitfunc=NULL; > TF1 *bckfunc=NULL; > Double_t xmin, xmax; > Double_t binsize; > > > void MMFitWQSetup(TDirectory *template_dir) { > // Setup some of the "global's" in this namespace > directory = template_dir; > > xmin = 1.05; xmax = 1.3; // fit over this range > > backgrnd_func = linear_bck; > nbck_params = 2; > > // define background function > if (!bckfunc) { > bckfunc = new TF1("bckfunc",backgrnd_func,xmin,xmax,nbck_params); > } > > // define total fit function > if (!fitfunc) { > fitfunc = new TF1("mmfitwq",mmfitfunc,xmin,xmax,2+nbck_params); > fitfunc->SetParNames("Lambda","Sigma0","Bck Cnts","Bck Slope"); > } > binsize = -1.; > } > > TH1 * GetHypeTemplate(TH1 * hist, int hype) { > char temp[30]; > int Wid, Qid; > > sscanf(hist->GetName(),"%[^0-9]%d_%d%s",temp,&Wid,&Qid,temp); > sprintf(temp,"WQ%d_%d_%dMM",hype,Wid,Qid); > return (TH1*)directory->Get(temp); > } > > void MMPrepareFitWQHist(TH1 *hist) { > // prepare to fit this histogram, get the template histograms setup, > // setup starting values for parameters > char temp[30]; > int Wid,Qid; > > // get appropriate template histograms : Lambda > lambda_hist = GetHypeTemplate(hist,0); > > // get appropriate template histograms : Sigma0 > sigma0_hist = GetHypeTemplate(hist,1); > > // setup initial parameters > Double_t parms[10]; > parms[0] = hist->Integral(hist->FindBin(1.09),hist->FindBin(1.15)); > parms[1] = hist->Integral(hist->FindBin(1.09),hist->FindBin(1.15)); > parms[2] = 10.; > parms[3] = 0.; > > fitfunc->SetParameters(parms); > > } > > } > > Double_t mmfitfunc(Double_t *x, Double_t parms[]) { > // parms are set up as: > // parms[0] = lambda scale factor > // parms[1] = sigma0 scale factor > // parms[2...] = background terms > > Double_t lambda_contrib=0., sigma0_contrib=0., back_contrib=0.; > TH1 *lambda_hist = MMWQTemplate::lambda_hist; > TH1 *sigma0_hist = MMWQTemplate::sigma0_hist; > > if (lambda_hist) { > Int_t bin = lambda_hist->FindBin(*x); > Double_t cont = lambda_hist->GetBinContent(bin); > lambda_contrib = parms[0]*cont; > } > if (sigma0_hist) { > Int_t bin = sigma0_hist->FindBin(*x); > Double_t cont = sigma0_hist->GetBinContent(bin); > sigma0_contrib = parms[1]*cont; > } > back_contrib = MMWQTemplate::backgrnd_func(x,&(parms[2])); > return lambda_contrib+sigma0_contrib+back_contrib; > } > > Double_t linear_bck(Double_t *x, Double_t parms[]) { > // 1rst parameter is always the area of the background (A) -- must be > // positive! > // 2nd parameter is the slope (b) > // f = a+b*x becomes A/d + b*(x-d/2) > Double_t d1 = MMWQTemplate::xmax - MMWQTemplate::xmin; > Double_t d2 = MMWQTemplate::xmax + MMWQTemplate::xmin; > static Double_t w = MMWQTemplate::binsize; > return parms[0]*w/(d1) + parms[1]*w*(*x - d2/2); > } > > // I can't get ROOT to interactively look inside the namespace, so > // some wrapper functions were necessary > > void MMFitWQSetup(TDirectory *template_dir) { > MMWQTemplate::MMFitWQSetup(template_dir); > } > > void MMPrepareFitWQHist(TH1 *hist) { > MMWQTemplate::MMFitWQHist(hist); > } > > // Then, to fit, you do: > > void fit_hist(TH1 *hist, TDirectory *template_dir) { > // example of how to fit the histogram "hist" > > // only have to do this Setup once > MMFitWQSetup(template_dir); > > // for each histogram: prepare by selecting the template histos > MMPrepareFitWQHist(hist); > > // do the fit > hist->Fit("mmfitwq","RQ"); > > Double_t parms[10]; > hist->GetFunction("mmfitwq")->GetParameters(parms); > > // process on the fit results.... > } > -- > /*************************************************** > * Robert Feuerbach feuerbac@ernest.phys.cmu.edu * > * CMU Physics Department (412) 268-2772 * > * Pittsburgh, PA 15213 FAX: (412) 681-0648 * > ***************************************************/
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:39 MET