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)