Illegal pointer type TClonesArray when using SetBranchAddres

When attempting to accress data from a banch of a TTree I get this error:

“Error in TTree::SetBranchAddress: The pointer type given (TClonesArray) does not correspond to the class needed (vectirreco::Muon) by the branch recoMuons_muons__RECO.obj
Error: illegal pointer to class object GetLeaf(”@size") 0x0 2446 muFilter.C:51:"

My code is thus and worked for the last TTree file I used it on (with a changing of variable names).

[code]#include “TROOT.h”
#include “TTree.h”
#include “TBranch.h”
#include “TFile.h”
#include “TH1.h”
#include “TH2.h”
#include “TF1.h”
#include “TStyle.h”
#include “TCanvas.h”
#include “TGraphErrors.h”
#include “TLorentzVector.h”
#include “TClonesArray.h”
#include “TLegend.h”
#include “TMemberInspector.h”
#include “TObjArray.h”
#include “TSeqCollection.h”
#include “TNamed.h”
#include
#include
#include <stdio.h>

TFile *f;
TTree *myTree;
TClonesArray *recoMuons_muons__RECO = new TClonesArray();
//TBrowser muFilter;

void muFilter() {

f = new TFile("~/private/scratch1/CMSSW_5_3_17/src/MyOutputFile.root");
myTree = (TTree*)f->Get("Events");
recoMuons_muons__RECO = 0;
myTree->SetBranchAddress("recoMuons_muons__RECO.obj", &recoMuons_muons__RECO);
			
int nEvents = myTree->GetEntries();
int PtCutoff = 0;
int goodEvents = 0;
int size = 0;
int type = 0;
TLorentzVector *Reco_mu = 0;

TH1D *MuSize = new TH1D("Mu Size","Mu Size",10,0,10);
MuSize->Sumw2();
TH2D *MuPt = new TH2D("Mu Pt","Mu Pt",1500,PtCutoff,150,1500,-3.2,3.2);
MuPt->Sumw2();
TH2D *MuPtType = new TH2D("Mu Pt Type","Mu Pt Type",1500,PtCutoff,150,1500,-3.2,3.2);
MuPtType->Sumw2();

for (Int_t i=0; i<nEvents; i++) {
	
	myTree->GetEntry(i);
	size = myTree->GetLeaf("@size")->GetValue(0);
	type = myTree->GetLeaf("type_")->GetValue(0);
	Reco_mu = (TLorentzVector *) recoMuons_muons__RECO->At(0);
					
	if (size>=2 && Reco_mu->Pt()>PtCutoff) {
			
		MuPt->Fill(Reco_mu->Pt(),Reco_mu->PseudoRapidity());
		MuSize->Fill(size);
		goodEvents++;
		
		if (type==0) {
			
			MuPtType->Fill(Reco_mu->Pt(),Reco_mu->PseudoRapidity());
		}
	}
}

//Plotting and Output

TCanvas *c1 = new TCanvas();
MuSize->Draw();
MuSize->SetMarkerStyle(20);
MuSize->GetXaxis()->SetTitle("Number of Muons");
MuSize->GetYaxis()->SetTitle("Number of Events");

TCanvas *c2 = new TCanvas();
MuPt->Draw();
MuPt->SetMarkerStyle(15);
MuPt->GetXaxis()->SetTitle("Muon Pt");
MuPt->GetYaxis()->SetTitle("Pseudo Rapidity");

TCanvas *c3 = new TCanvas();
MuPtType->Draw();
MuPtType->SetMarkerStyle(15);
MuPtType->GetXaxis()->SetTitle("Muon Pt");
MuPtType->GetYaxis()->SetTitle("Pseudo Rapidity");

}
[/code]

I am not sure why I am now getting this error that my TClonesArray and the branch are different object types when I wasn’t before. Doesn’t TClonesArray just clone the type of anything passed to it? I am quite lost as to why this isn’t working.

Thanks

I think we need at least the output of “myTree->Print();” (or maybe the “MyOutputFile.root”).

[quote]Doesn’t TClonesArray just clone the type of anything passed to it? I am quite lost as to why this isn’t working.[/quote]Yes, it does (as long as it inherits from TObject) … how did you ‘pass’ any type to your TClonesArray?

[quote]"Error in TTree::SetBranchAddress: The pointer type given (TClonesArray) does not correspond to the class needed (vectirreco::Muon) by the branch recoMuons_muons__RECO.obj
Error: illegal pointer to class object GetLeaf("@size") 0x0 2446 muFilter.C:51:"
…[/quote]The message is explicitly saying that the branch for that file contains objects of type “vectorreco::Muon” and this type is different from a TClonesArray. It might work however if you also make sure to initialize the TClonesArray to contain reco::Muon.

Cheers,
Philippe.

I thought setting the branch address and pointing it to the branch would also set the type to be the same. Apparently not. How do I set the type of my TClonesArray? (Can it have multiple types?)

Attached is the output of myTree->Print()
output.txt (323 KB)

Hi,

You can use TClonesArray *recoMuons_muons__RECO = new TClonesArray("vector<reco::Muon>");or (if you have the library for reco::Muons) you can usevector<reco::Muon> *recoMuons_muons__RECO = new vector<reco::Muon>();

Cheers,
Philippe.

Using TClonesArray *recoMuons_muons__RECO = new TClonesArray("vector<reco::Muon>") gave me the error Error in <TClonesArray::SetClass>: vector<reco::Muon> does not inherit from TObject Error in <TTree::SetBranchAddress>: The pointer type given (TClonesArray) does not correspond to the class needed (vector<reco::Muon>) by the branch: recoMuons_muons__RECO.obj Error: illegal pointer to class object GetLeaf("@size") 0x0 2446 muFilter.C:51: *** Interpreter error recovered ***

It looks like vectorreco::Muon inherits from reco::Candidate(cmssdt.cern.ch/SDT/doxygen/CMSS … 1Muon.html).

Does this mean that TClonesArray cannot clone objects of the type vectorreco::Muon (and anything else that inherits from reco::Candidate)?

On the plus side when I use vector<reco::Muon> *recoMuons_muons__RECO = new vector<reco::Muon>() the error disappears and I am left with only Error: illegal pointer to class object GetLeaf("@size") 0x0 2446 muFilter.C:52: *** Interpreter error recovered *** which is a slightly different issue.

TClonesArray *recoMuons_muons__RECO = new TClonesArray("vector<reco::Muon>")humm, I made a typographical error and meant to write: TClonesArray *recoMuons_muons__RECO = new TClonesArray("reco::Muon")and then I forgot to mention that only classes inheriting from TObject can be used in a TClonesArray.

[quote]why I am now getting this error that my TClonesArray and the branch are different object types when I wasn’t before[/quote]You must have been trying to read very different branch with a different setup.

Error: illegal pointer to class object GetLeaf("@size") 0x0 2446 muFilter.C:52: *** Interpreter error recovered ***Indeed, there is no branch ‘@size’ which is solely a notation that TTreeFormula (and thus TTree::Draw) knows about and overlay in you case to the value of recoMuons_muons__RECO->size();

Cheers,
Philippe.

Creating and setting my branch address with:

[code]TFile *f;
TTree myTree();
vectorreco::Muon *recoMuons_muons__RECO = new vectorreco::Muon();

void muFilter() {

f = new TFile("~/private/scratch1/CMSSW_5_3_17/src/MyOutputFile.root");
myTree = (TTree*)f->Get("Events");
recoMuons_muons__RECO = 0;
myTree->SetBranchAddress("recoMuons_muons__RECO.obj", &recoMuons_muons__RECO);

}
[/code]

Then trying to access anything from recoMuons_muons__RECO e.g.

bool booltest();
booltest = recoMuons_muons__RECO->isMuon();
cout << booltest;

or

int size = 0;
size = recoMuons_muons__RECO->size();

or

TObjArray *test();
test = (TObjArray*)recoMuons_muons__RECO->GetListOfLeaves();

all return

Error: illegal pointer to class object recoMuons_muons__RECO 0x0 4623  muFilter.C:56:
Warning: Automatic variable booltest is allocated muFilter.C:56:
Error: Undeclared variable booltest muFilter.C:56:
*** Interpreter error recovered ***

When I run the code

	if (recoMuons_muons__RECO == NULL) {
		cout << "NULL";
	}

it tells me that indeed recoMuons_muons__RECO is NULL, therefore the SetBranchAddress I used isn’t working.

When printing out the names of all the branches contained in myTree the one I am looking for is called “recoMuons_muons__RECO.” not “recoMuons_muons__RECO.obj” however when I attempted to SetBranchAddress to this branch I get

Error in <TTree::SetBranchAddress>: The pointer type given (vector<reco::Muon>) does not correspond to the class needed (edm::Wrapper<vector<reco::Muon> >) by the branch: recoMuons_muons__RECO.

Changing my declared variable to an edm::Wrapper<vectorreco::Muon> then it does not return NULL, however I cannot seem to find the API for edm::Wraooer<vectorreco::Muon> to see what commands are useable (trying to use ->isMuon(), a public member function of Muon it tells me that I cannot call Wrapper<vectorreco::Muon>::isMuon() in the curerct scope, meaning (I think) that isMuon() is not a function of Wrapper<vectorreco::Muon>).

Hi,

Indeed I had yet another problem in the proposed code. Since the object you are addressing is not the top level object but an inner/nested object, you would actually need to pass the address of the object rather than a pointer to it.vector<reco::Muon> *recoMuons_muons__RECO = new vector<reco::Muon>(); ... myTree->SetBranchAddress("recoMuons_muons__RECO.obj", recoMuons_muons__RECO);

[quote]edm::Wrapper<vectorreco::Muon> then it does not return NULL, however I cannot seem to find the API for edm::Wraooer<vectorreco::Muon>[/quote]edm::Wrapper is a CMSSW class, please refer to its documentation.

Cheers,
Philippe.

That’s my problem right now. I am having difficulty finding the documentation for this. Do you happen to know where it is located?

Thanks

Hi

I am also having the same kind of error while running my code .Error in TTree::SetBranchAddress: The pointer type given (TLorentzVector) does not correspond to the class needed (TObjArray) by the branch: reco_6gvect.
How to sort it out?

Thank you.