Undefined reference to TTree


I am note sure is this a ROOT question or c++ but i need help as i am a beginner.

I was trying to make a macro (Goodevent.C) that draw histograms and it is linked to .C and .h files which i made them through tree->MakeClass("") in root session.

i need to know what is missing as i always have the error below and this macro worked with me fine before and i didn’t changed anything recently. i really need to understand what it means by undefined reference and what i should do then.

below is the macro as well.



[melsawy@lxplus052 test]$ root -l
root [0] .L Goodevent.C+
Info in <TUnixSystem::ACLiC>: creating shared library /afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/./Goodevent_C.so
In file included from /afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/Goodevent_C_ACLiC_dict.h:34,
                 from /afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/Goodevent_C_ACLiC_dict.cxx:17:
/afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/Goodevent_C_ACLiC_dict.o: In function `Goodevent()':
/afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/./Goodevent.C:64: undefined reference to `Ntuple1::Ntuple1(TTree*)'
/afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/./Goodevent.C:65: undefined reference to `Ntuple2_Track::Ntuple2_Track(TTree*)'
/afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/./Goodevent.C:99: undefined reference to `Ntuple1::GetEntry(long long)'
/afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/./Goodevent.C:100: undefined reference to `Ntuple2_Track::GetEntry(long long)'
/afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/./Goodevent.C:352: undefined reference to `Ntuple2_Track::~Ntuple2_Track()'
/afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/./Goodevent.C:352: undefined reference to `Ntuple1::~Ntuple1()'
/afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/./Goodevent.C:352: undefined reference to `Ntuple2_Track::~Ntuple2_Track()'
/afs/cern.ch/user/m/melsawy/private/track_Ntuple/CMSSW_8_0_13/src/MonopoleAnalysis/NtupleAnalyzer/test/./Goodevent.C:352: undefined reference to `Ntuple1::~Ntuple1()'

#include "Ntuple1.h"
#include "Ntuple2_Track.h"
#include <iostream>
#include "TChain.h"
#include "TROOT.h"
#include "TH1F.h"
#include "TFile.h"
#include "TH2F.h"
#include "TMath.h"
#include "TH1D.h"
#include "TH2D.h"
#include <vector>

using namespace std;

//here i put my function then i call it inside the main loop below

bool isPassHLT(vector <int> HLT_nb, vector <string> HLT_name, vector <bool> HLT_isaccept){ 
	int nbMatch = 0;
	for(unsigned i=0; i<HLT_nb.size(); i++){
		if( (HLT_name.at(i) == "HLT_Photon175_v4" ||HLT_name.at(i) == "HLT_Photon165_HE10_v4" ) && HLT_isaccept.at(i) == 1 ) {
			//cout<<"triggerName = "<<triggerName<<endl;
	if(nbMatch>0) {
		return true;
	else return false;

float delR(float eta1,float phi1,float eta2,float phi2){
	float mpi=3.14;
	float dp=std::abs(phi1-phi2);
	if (dp>mpi) dp-=float(2*mpi);
	return sqrt((eta1-eta2)*(eta1-eta2) + dp*dp);

int Goodevent()

	//i put here the name of the .C file with +g to load this macro 
	//i get Mai.C and Mai.h from tree->MakeClass("Mai")


	//i open my tree with tchian if i want to open many files with the same tree
	// between bracket i put the name of the tree in the root file

	TChain *ch1=new TChain("tree");
	TChain *ch2=new TChain("MplTrackSets");


	//I put the class name and make a pointer (an) to my tree
	Ntuple1 an(ch1);
	Ntuple2_Track bn(ch2);

	//declare nentries in the tree

	long int nentries=an.fChain->GetEntries();
	long int mentries=bn.fChain->GetEntries();

	//  cout<<"Events"<<nentries<<endl;
	//return 0;

	//write histograms to this output

	TFile *output = new TFile("Combined_trees_march2017.root","recreate");

	//starting define my histograms 

	TH1F* hist_f51_= new TH1F("hist_f51","",100,0,1.2);
	TH1F* hist_f15_= new TH1F("hist_f15","",100,0,1.2);
	TH2F* h2_NbHits_NbSatHits_ = new TH2F("Sat_Tot","",100,0.0,30.0,100,0.0,1.0);
	TH1D* dedxSig_=new TH1D("dedxSig","",100,0.0,30.0);
	// TH2D* result_=new TH2D("result","",100,0.0,1.0,100,0.0,30.0); 
	//TH1F* h_NbFireHLT = new TH1F("NbFireHLT", "NbFireHLT",30,0.0,30.0);
	//TH1F* h1_ptBeforeTrigger_  = new TH1F("ptBeforeTrigger","",50,0.0,2000.0);
	//TH1F* h1_ptAfterTrigger_   = new TH1F("ptAfterTrigger","",50,0.0,2000.0);
	TH2D* result2=new TH2D("result2","",100,0.0,1.0,100,0.0,30);
	TH1F* DeDx_=new TH1F("DeDx","",100,0.0,500.0);

	// my main loop in the analysis , main loop 

	for (long int i=0;i<nentries; i++)

		//i print out the Event no i am working on

                cout<<"Number of Tracks 1st tree are:"<<an.Track_NTracks->size()<<endl;
		cout<<"Number of Cluster is"<<an.SC_EB_egClean_size->size()<<endl;

		cout<<"Number of Tracks 2nd tree are:"<<bn.RZPar2->size()<<endl;

		//		cout<<"Event of the first tree"<<an.event_evtNo<<endl;
		//cout<<"Event of the track combiner tree"<<bn.event_evtNo<<endl;
		//cout<<"The Run No. is: "<<an.event_runNo<<endl;
                //cout<<"The Run No. is: "<<bn.event_runNo<<endl;

		std::vector<int> SC_index;
		std::vector<int> Track_index;
		std::vector<int> MonoTrack_index;

		// i can call new functions here

		bool HLT = isPassHLT(*an.HLT_nb, *an.HLT_name, *an.HLT_isaccept);

		bool isGoodEvent=false;
		bool isGoodEvent_SC=0;
		bool isGoodEvent_Track=0;


		for (unsigned int m=0; m < an.SC_EB_egClean_size->size();m++)

		  //		  cout<<"No. of SC:"<<m<<endl;

			for (unsigned int j=0;j<an.Track_NTracks->size();j++)

				float Delta= delR(an.Track_Eta->at(j), an.Track_Phi0->at(j), an.SC_EB_egClean_eta->at(m), an.SC_EB_egClean_phi->at(m));                                              
				if (an.SC_EB_egClean_E->at(m) > 50.0 && Delta < 0.5) {

					//now i have to store the vents that passed in the SC_index

					//					cout<<"SC_index is : "<<m<<endl;
                                        //cout<<"Track_index is : "<<j<<endl;

					//			cout<<"good sc"<<endl; 

		for (unsigned h=0; h<bn.RZPar2->size(); h++)
			if (bn.RZPar0->at(h)<10 && bn.RZPar1->at(h)< 999 && bn.RZPar2->at(h)< 0.005)

				//	cout<<"MonoTrack_index is : "<<h<<endl;

				//cout<<"good track"<<endl;

		if (HLT && isGoodEvent_SC == true  && isGoodEvent_Track == true)
		  	cout<<"The Event is Good"<<endl;

		//else continue;
		//		cout<<"The size of the index"<<SC_index.size()<<endl;
                //cout<<"The size of the index"<<Track_index.size()<<endl;
                //cout<<"The size of the index"<<MonoTrack_index.size()<<endl;

		//const unsigned nTracks = Mono_Track.size();

		for (unsigned int v=0; v < bn.RZPar2->size() ; v++){

		  // if Ndof <= 3 continue

		  if ( bn.NdofRZ->at(v) <= 3 ) continue;

		  // Calculate expected Eta, Phi for trackwhich is extrpolated to ecal
		  const double EcalR = 129.0;

		  float ThisZ = bn.RZPar0->at(v) + EcalR*bn.RZPar1->at(v) + EcalR*EcalR*bn.RZPar2->at(v);

		  float ThisEta = TMath::ASinH(ThisZ / EcalR);

		  float ThisPhi = bn.XYPar0->at(v) - TMath::ASin((EcalR*EcalR-bn.XYPar0->at(v)*bn.XYPar2->at(v))/(2*EcalR*(bn.XYPar2->at(v)-bn.XYPar0->at(v))));

		  float MinDR = 999;

		  int BestEBCluster=-1;

		    // BestEECluster=-1;

		    const unsigned nEBclusters = an.SC_EE_egClean_size->size();

		  for(unsigned int s=0; s < nEBclusters; s++){

		    float ThisDR = delR(an.SC_EE_egClean_eta->at(s), an.SC_EE_egClean_phi->at(s),ThisEta,ThisPhi);

		    if(ThisDR < MinDR){

		      MinDR = ThisDR;

		      BestEBCluster = s;

		      //    cout<<"the best SC is : "<<s<<endl;



		//    delR(*an.Track_Eta, *an.Track_Phi0, *an.SC_EB_egClean_eta, *an.SC_EB_egClean_phi);

		//    cout<<"Entries no:"<<nentries<<endl;

		//loop inside the main loop 

		for (unsigned int n=0; n<bn.RZPar2->size(); n++)


		for (unsigned int k=0;k<an.SC_EB_egClean_size->size();k++)

			// if (an.SC_EB_egClean_frac51->at(k)>0.95){
			// }

		//loop inside loop

		for (unsigned int j=0;j<an.Track_NTracks->size();j++)

			float num = an.Track_HitSatStrips->at(j);
			float den = an.Track_HitTotStrips->at(j);

			for (unsigned int m=0; m<an.SC_EB_egClean_size->size(); m++){

				// here i assign DELTA To store the result of the delR function 

				float Delta= delR(an.Track_Eta->at(j), an.Track_Phi0->at(j), an.SC_EB_egClean_eta->at(m), an.SC_EB_egClean_phi->at(m));

				if (Delta < 0.5 & an.SC_EB_egClean_E->at(m) > 50.0)


					const float dedxSig=(sqrt(-(TMath::Log(TMath::BinomialI(0.07,an.Track_HitTotStrips->at(j),an.Track_HitSatStrips->at(j))))));

					float f51=an.SC_EB_egClean_frac51->at(m);




		//      h2_NbHits_NbSatHits_->Fill((an.Track_HitSatStrips->at(j)/an.Track_HitTotStrips->at(j)),an.Track_HitTotStrips->at(j));

		//cout<<"Track_NTracks->size() is"<<an.Track_NTracks->size()<<endl;

		//cout<<"Track_HitTotStrips->size() is"<<an.Track_HitTotStrips->size()<<endl;

		//cout<<"Track_HitSatStrips->size() is"<<an.Track_HitSatStrips->size()<<endl;
		//      cout<<"Num is:"<<num<<endl;
		//cout<<"Den is:"<<den<<endl;



	h2_NbHits_NbSatHits_->SetXTitle("No. of Strips");
	h2_NbHits_NbSatHits_->SetYTitle("Fraction of Saturated Strips");

	//dedxSig_->SetXtitle("dEdX Significance");

	return 0;

Your Ntuple1 has a source file, right? You need to load that (e.g. .L Ntuple1.cxx+ before loading your code that depends on it.


Yes Ntuple1 and Ntuple2_Track have source files … so i should load them first…

what about gROOT->LoadMacro("…C+g")

this line means to load the source file while i am loading this macro , right?



With v6/cling, the script is now compiled (just-in-time) using an interactive incremental compiler (cling based on clang).

In particular this means that all symbols must be resolved before any execution of functions inside the script can be executed (this is simplified in a lot of case thanks to the shared-library auto-loading feature we have).

In practice this means that you need to run the LoadMacro calls before loading the goodEvent.C file.


PS. Alternatively you can #Include those files in a lot of case (even with the + if you are interpreting).

thx , i will give it a try.


This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.