Re: Calling a function from a script

From: daniel cussol <cussol_at_ccimap.in2p3.fr>
Date: Mon, 03 Oct 2005 09:35:43 +0200


Roger Mason a écrit :

>Hello,
>
>I have defined a set of functions in fitFunction2.C:
>
>#include "Riostream.h"
>#include "TH1.h"
>#include "TF1.h"
>#include "TLegend.h"
>#include "TCanvas.h"
>#include "TMath.h"
>
>// Background function
>Double_t background(Double_t *x, Double_t *par) {
> // order must be defined externally in the calling routine
> Double_t sum = 0;
> for (int i = 0; i < order+1; i++){
> sum = sum + par[i]*pow(x[0],i);
> }
> return sum;
>}
>
>// Sum of lorentzians
>Double_t lpeaks(Double_t *x, Double_t *par) {
> Double_t result = 0.0;
> for (Int_t p=0;p<nlpeaks;p++) {// nlpeaks must be defined in calling routine
> Double_t location = par[2*p];
> Double_t scale = par[2*p+1];
> result += TMath::CauchyDist(x[0],location,scale);
> }
> return result;
>}
>
>// Sum of gaussians
>Double_t gpeaks(Double_t *x, Double_t *par) {
> Double_t result = 0.0;
> for (Int_t p=0;p<ngpeaks;p++) {// ngpeaks must be defined in calling routine
> Double_t norm = par[3*p];
> Double_t mean = par[3*p+1];
> Double_t sigma = par[3*p+2];
> result += norm*TMath::Gaus(x[0],mean,sigma);
> }
> return result;
>}
>
>// Sum of background and peak functions
>Double_t fitFunction2(Double_t *x, Double_t *par) {
>
> Double_t gsum = gpeaks(x[0],&par);// Gaussians first
> Double_t lsum = lpeaks(x[0],&par[3*ngpeaks]);// Lorentzian parms start right after gaussian parms
> Double_t bgd = background(x[0],&par[3*ngpeaks+2*nlpeaks]);// backgrund parms last
>
> return Double_t result = gsum + lsum + bgd;
>}
>
>I use this un-named script to set up variables:
>
>{
>gROOT->Reset();
>
>Int_t ngpeaks=3;
>Int_t nlpeaks=3;
>Int_t order=2;
>
>TF1* g1 = new TF1("g1",gpeaks,-100,100,3*ngpeaks);
>TF1* l1 = new TF1("l1",lpeaks,-100,100,2*nlpeaks);
>TF1* b1 = new TF1("b1",background,-100,100,order);
>
>const Double_t g1parms[3*ngpeaks] = {10,-35,15,20,2,40,50,50,10};
>const Double_t l1parms[2*nlpeaks] = {-50,100,1,20,55,100};
>const Double_t b1parms[order] = {0,10};
>
>Int_t tparms = 3*ngpeaks+2*nlpeaks+order;
>Double_t totalparms[tparms];
>
>
>g1->SetParameters(g1parms);
>l1->SetParameters(l1parms);
>b1->SetParameters(b1parms);
>
>for (Int_t i = 0; i < 3*ngpeaks; i++) {
> totalparms[i] = g1parms[i];
>}
>for (Int_t i = 3*ngpeaks; i < 3*ngpeaks+2*nlpeaks; i++) {
> totalparms[i] = l1parms[i-3*ngpeaks];
>}
>for (Int_t i = 3*ngpeaks+2*nlpeaks; i < tparms; i++) {
> totalparms[i] = b1parms[i-(3*ngpeaks+2*nlpeaks)];
>}
>
>
>TF1* total = new TF1("total",fitFunction2,-100,100,tparms);
>total->SetParameters(totalparms);
>
>}
>
>On the command line I do:
>
>root [0] .L fitFunction2.C
>.L fitFunction2.C
>root [1] .x tmp.C
>.x tmp.C
>root [2] total->Draw()
>total->Draw()
><TCanvas::MakeDefCanvas>: created default TCanvas with name c1
>Warning: Automatic variable Double_tresult is allocated FILE:fitFunction2.C LINE:52
>
> *** Break *** segmentation violation
> Generating stack trace...
> 0xffffe420 in <unknown function>
> 0xb76a814d in G__getitem + 0x54c from
> /usr/local/root/lib/libCint.so.5.02
>
>[snip]
>
> 0xb76a6aac in G__getexpr + 0x8392 from /usr/local/root/lib/libCint.so.5.02
> 0x08048e5d in main + 0x71 from /usr/local/bin/root.exe
> 0xb6ac3439 in __libc_start_main + 0xa9 from /lib/libc.so.6
> 0x08048d51 in TApplicationImp::ShowMembers(TMemberInspector&, char*) + 0x3d from /usr/local/bin/root.exe
>Root > Function gpeaks() busy flag cleared
>Function fitFunction2() busy flag cleared
>Error: Function gpeaks(x[0],&par) is not defined in current scope FILE:fitFunction2.C LINE:48
>Possible candidates are...
>filename line:size busy function type and name
>fitFunction2.C 33:10 0 public: Double_t gpeaks(Double_t* x,Double_t* par);
>
>What have I done wrong?
>
>Thanks for any help,
>
>Roger
>
>
>

Hi Roger,
 The prblem is in the way you call your user-defined function. The system waits a pointer to a Double _t as a first argument of gpeaks, lpeaks and background, but you give a Double_t when you call them. Additionnaly, the second argument in your call og gpeks is also incorrect. So you should replace the following lines in fitFunction2:

  Double_t gsum = gpeaks(x[0],&par);// Gaussians first
  Double_t lsum = lpeaks(x[0],&par[3*ngpeaks]);// Lorentzian 
  Double_t bgd = background(x[0],&par[3*ngpeaks+2*nlpeaks]);// backgrund 

by

  Double_t gsum = gpeaks(x,par);// Gaussians first
  Double_t lsum = lpeaks(x,&par[3*ngpeaks]);// Lorentzian 
  Double_t bgd = background(x,&par[3*ngpeaks+2*nlpeaks]);// backgrund 

or, if you prefer to use references:

  Double_t gsum = gpeaks(&x[0],&par[0]);// Gaussians firs
  Double_t lsum = lpeaks(&x[0],&par[3*ngpeaks]);// Lorentzian 
  Double_t bgd = background(&x[0],&par[3*ngpeaks+2*nlpeaks]);// backgrund 

When you have an array, the type of variable you give to a function depends on the way you give it. Here is an exemple:

Double_t dum[10];
dum is a Double_t*
dum[0] is a Double_t
&dum[5] is a Double_t* which points to the 6th element of the array.

I hope this helps

-- 
Daniel 

LPC Caen IN2P3/ENSICAEN/Universite de Caen
Boulevard du Marechal Juin
14050 CAEN CEDEX

e-mail : cussol_at_in2p3.fr
Tel    : +33-(0)2-31-45-29-73
FAX    : +33-(0)2-31-45-25-49
Received on Mon Oct 03 2005 - 09:45:50 MEST

This archive was generated by hypermail 2.2.0 : Tue Jan 02 2007 - 14:45:12 MET