Adding Classes in ACLiC

Hello,

I am trying to include some custom classes in a simulation in root.

I have tried to follow the recipe in the ROOT User’s guide (Adding a Class with ACLiC)

I have written the include file like

#include <iostream>
#include "TObject.h"

class TWaveFunction : public TObject {

protected:
	Int_t f_Nr;
	Int_t f_Nz;
	Int_t f_Size;
	Double_t* f_Re; //[f_Size]
	Double_t* f_Im; //[f_Size]
	Double_t f_d_rho;
	Double_t f_d_eta;
	
private:
	void Plot(Int_t );
	Double_t GetWFData(Int_t, Int_t, Int_t);
	
public:
	//creators
	TWaveFunction();
	TWaveFunction(Int_t, Int_t); 
	
	//destructor
	virtual ~TWaveFunction();

	//getters
	Double_t Nr() const {return f_Nr;}
	Double_t Nz() const {return f_Nz;}
	
	Double_t Re(Int_t j, Int_t k) {return f_Re[j*f_Nz+k];}
	Double_t Im(Int_t j, Int_t k) {return f_Im[j*f_Nz+k];}
	
	
	Double_t Abs2(Int_t j, Int_t k) {return Re(j,k)*Re(j,k)+Im(j,k)*Im(j,k) ;}
	
	Double_t Rho(Int_t j) { return  ((Double_t)j)*f_d_rho ;}
	Double_t Eta(Int_t k) { return  ((Double_t)(k - (f_Nz-1.)/2.0 )) *f_d_eta ;}
	
	//setters
	virtual void SetRe(Int_t j, Int_t k, Double_t in) {f_Re[j*f_Nz+k]=in;}
	virtual void SetIm(Int_t j, Int_t k, Double_t in) {f_Im[j*f_Nz+k]=in;}
	
	virtual void SetDRho(Double_t d_rho) {f_d_rho=d_rho;}
	virtual void SetDEta(Double_t d_eta) {f_d_eta=d_eta;}
	
	//plotters
	void PlotRe();
	void PlotIm();
	void PlotAbs2();
	
	ClassDef(TWaveFunction,1);
};

#if !defined(__CINT__)
	ClassImp(TWaveFunction);
#endif 

and the implementation like

[code]#include “TWaveFunction.h”
#include “TCanvas.h”
#include “TGraph2D.h”

ClassImp(TWaveFunction);

#define TWF_REAL 1
#define TWF_IMG 2
#define TWF_ABS2 3

TWaveFunction::TWaveFunction()
{
//default constructor
printf(“Use the other constructor!!\n”);
}

TWaveFunction::TWaveFunction(Int_t nr, Int_t nz)
{
//normal constructor
f_Nr=nr; f_Nz=nz;

f_Size=f_Nr*f_Nz;

f_Re = (Double_t*)calloc(f_Nr*f_Nz, sizeof(Double_t));
f_Im = (Double_t*)calloc(f_Nr*f_Nz, sizeof(Double_t));

}

TWaveFunction::~TWaveFunction()
{
free(f_Re);
free(f_Im);
}

void TWaveFunction::PlotRe()
{
Plot((Int_t)TWF_REAL);
}

void TWaveFunction::PlotIm()
{
Plot((Int_t)TWF_IMG);
}

void TWaveFunction::PlotAbs2()
{
Plot((Int_t)TWF_ABS2);
}

void TWaveFunction::Plot(Int_t type )
{
TCanvas* c = new TCanvas(“cWavefunction”, “cWavefunction”);

TGraph2D* graph = new TGraph2D(f_Nr*f_Nz);

for(Int_t j=0; j< f_Nz; j++) graph->SetPoint(j, Eta(j), 0., GetWFData(0,j,type)/Rho(0)*2.0);

for(Int_t i=1; i< f_Nr; i++)
{
	for(Int_t j=0; j< f_Nz; j++)
	{
		graph->SetPoint(i*f_Nz+j, Eta(j), Rho(i), GetWFData(i,j,type)/Rho(i) );
	}
}

graph->Draw("COLZ");

}

Double_t TWaveFunction::GetWFData(Int_t i, Int_t j, Int_t type )
{
switch(type)
{
case TWF_REAL:
return Re(i,j);
break;
case TWF_IMG:
return Im(i,j);
break;
case TWF_ABS2:
return Abs2(i,j);
break;
default:
printf(“Plot called with invalid command. This shouldn’t happen\n”);
return 0;
}
}
[/code]

In my main source file, I have

[code]#include “TMyParams.h”
#include “TWaveFunction.h”

#include “TMath.h”
#include “TGraph2D.h”
#include “TCanvas.h”
#include “TROOT.h”
#include “TClass.h”

#include “BECSim.h”

// Physical Constants
Double_t h = TMath::H();
Double_t hbar = TMath::Hbar();
Double_t pi = TMath::Pi();
Double_t amu = 1.66053886e-27;

TMyParams* par;

void InitialiseParams()
{
TMyParams* testPar = new TMyParams();
testPar->Set_wz(10.);
testPar->Set_wr(1000.);
testPar->Set_N (10000);
testPar->Set_nr(21);
testPar->Set_nz(101);
testPar->Set_M(87.*amu);
testPar->Set_dz(500.e-9);
testPar->Set_dr(100.e-9);
testPar->Set_dt(1.e-9);

par=testPar;

}

void BECSim(void)
{
if (!TClass::GetDict(“TWaveFunction”)) {
gROOT->ProcessLine(".L TWaveFunction.cpp++");
}

if (!TClass::GetDict("TMyParams")) {
	gROOT->ProcessLine(".L TMyParams.cpp++");
}

TWaveFunction* wf = ThomasFermi();



for(Int_t i=0; i<1e3; i++)
{
	
	//
}

}

TWaveFunction* ThomasFermi()
{
if(par==NULL) InitialiseParams();

TWaveFunction* tf = new TWaveFunction(par->Nr(), par->Nz());

Double_t pref, exppot;

tf->SetDRho(par->Dr()/par->Sl());
tf->SetDEta(par->Dz()/par->Sl());

for(Int_t i=0; i<par->Nr(); i++)
{
	pref = tf->Rho(i) * TMath::Power(par->E(), 0.125)/ TMath::Power(TMath::TwoPi(), 0.75);
	
	for(Int_t j=0; j<par->Nz(); j++)
	{
		exppot = TMath::Exp(-1.0*HarmonicPotentialScaled (tf->Rho(i), tf->Eta(j), par->E()) );
		
		tf->SetRe(i, j, pref*exppot*1.0);
		tf->SetIm(i, j, pref*exppot*0.0);
		
	}
}

return tf;

}

Double_t HarmonicPotentialScaled(Double_t rho, Double_t eta, Double_t E)
{
return 0.25* (rhorho + etaeta*E);
}
[/code]

but when I do

$ root -l root [0] .L BECSim.cpp++

I get

Info in <TUnixSystem::ACLiC>: creating shared library /home/ebutler/ccm/2013_03/BECSim/./BECSim_cpp.so In file included from /home/ebutler/ccm/2013_03/BECSim/BECSim_cpp_ACLiC_dict.h:34:0, from /home/ebutler/ccm/2013_03/BECSim/BECSim_cpp_ACLiC_dict.cxx:17: /home/ebutler/ccm/2013_03/BECSim/./BECSim.cpp: In function ‘void BECSim()’: /home/ebutler/ccm/2013_03/BECSim/./BECSim.cpp:47:17: warning: unused variable ‘wf’ [-Wunused-variable] /home/ebutler/ccm/2013_03/BECSim/BECSim_cpp_ACLiC_dict.o: In function `InitialiseParams()': BECSim_cpp_ACLiC_dict.cxx:(.text+0x16): undefined reference to `TMyParams::TMyParams()' /home/ebutler/ccm/2013_03/BECSim/BECSim_cpp_ACLiC_dict.o: In function `ThomasFermi()': BECSim_cpp_ACLiC_dict.cxx:(.text+0x2bd): undefined reference to `TWaveFunction::TWaveFunction(int, int)' /home/ebutler/ccm/2013_03/BECSim/BECSim_cpp_ACLiC_dict.o: In function `_GLOBAL__sub_I_BECSim_cpp_ACLiC_dict.cxx': BECSim_cpp_ACLiC_dict.cxx:(.text.startup+0x3e): undefined reference to `ROOT::GenerateInitInstance(TMyParams const*)' BECSim_cpp_ACLiC_dict.cxx:(.text.startup+0x5f): undefined reference to `ROOT::GenerateInitInstance(TWaveFunction const*)' collect2: ld returned 1 exit status Error in <ACLiC>: Compilation failed!

It reports the constructors as undefined.

I can run the code in CINT without compiling, but I really need it to run compiled eventually.

I’ve included the complete code in a tarball. Can anyone help me out?
files.tar.gz (2.33 KB)

Try an “interpreted” BECSim using: root [0] .x BECSim.cpp or: root [0] .L BECSim.cpp root [1] BECSim();
Try a “compiled” BECSim using (you MUST precompile TMyParams and TWaveFunction first): root [0] .L TMyParams.cpp++ root [1] .L TWaveFunction.cpp++ root [2] .x BECSim.cpp++ or: root [0] .L TMyParams.cpp++ root [1] .L TWaveFunction.cpp++ root [2] .L BECSim.cpp++ root [3] BECSim();
files.tar.gz (2.4 KB)

Okay, thanks. You made a lot of changes, I having a hard time seeing what the important ones are…
perhaps the ‘class …’ in the BECSim.cpp file?