I then go to my linux terminal and input: root -l .L MyEvent.h+ .L tree_example8.C
but i encounter a warning here, given by:
/home/amensaywho/ROOT_Tutorial/MyEvent.h:25:3: warning: ambiguous expansion of macro 'ClassDef' [-Wambiguous-macro]
ClassDef(MyEvent,1)
^
/home/amensaywho/root/include/Rtypes.h:337:9: note: expanding this definition of 'ClassDef'
#define ClassDef(name,id) \
^
input_line_4:22:9: note: other definition of 'ClassDef'
#define ClassDef(name, id) \
^
the code for tree_example8.C is:
//Example of Tree using MyEvent Class
#include "MyEvent.h"
void tree_example8() {
TFile *f = new TFile("myfile_example8.root", "RECREATE");
TTree *T = new TTree("T","tree with class");
TRandom r;
Float_t px,py,pt;
MyEvent *event = new MyEvent();
T->Branch("Event", "MyEvent", &event);
for (Int_t i = 0; i < 10000; i++) {
r.Rannor(px,py);
pt = std::sqrt(px*px + py*py);
event->setPx(px);
event->setPy(py);
event->setPt(pt);
T->Fill();
}
f->Write();
f->Close();
}
Can someone point out what I’m missing? I’ve read the manual and documentation but I’m kinda new to programming in general so the jargon is a bit beyond me…
welcome to the ROOT forum!
In order to execute your macro you should run .x tree_example8.C
I tried your code and it runs fine for me. Could you please retry executing with .x?
I can not reproduce the problem with the code you provided. So there might be something odd with your ROOT installation. Let check a few things. On the shell prompt execute this following commands and give the output:
I see. We were asked to run .L MyEvent_h.so everytime we quit root and wanted to run a macro that used the Event Class defined by MyEvent.h. Is that redundant as well?
Related question: running another macro, given below, returns the error: Error in <TTree::Branch>: The class requested (vector<MyEvent>) for the branch "Events" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (vector<MyEvent>) to avoid to write corrupted data.
tree_example10.C:
//Tree with vector<MyEvent> as branch
#include <vector>
#include "MyEvent.h"
void tree_example10() {
TFile *f = new TFile("myfile_example10.root", "RECREATE");
TTree *T = new TTree("T","tree with vector");
TRandom r;
std::vector<MyEvent> *events = new std::vector<MyEvent>();
T->Branch("Events", "std::vector<MyEvent>", &events);
for (Int_t i = 0; i < 1000; i++) {
//clean vectors for each event
events->clear();
//Fill vectors for each event
Float_t px, py;
Int_t np = (Int_t)(r.Rndm()*10);
for(Int_t j = 0; j < np; j++){
r.Rannor(px, py);
Float_t pt = std::sqrt(px*px + py*py);
MyEvent event;
event.setPx(px);
event.setPy(py);
event.setPt(pt);
events->push_back(event);
}
T->Fill();
}
f->Write();
f->Close();
delete events;
}
The header file for MyEvent.h is same as above. How do I resolve this? Would be great if someone could explain the error as well
It all look consistent, so I am not sure why you are seeing this problem :(.
Related question: running another macro, given below, returns the error: Error in <TTree::Branch>: The class requested (vector<MyEvent>) for the branch "Events" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (vector<MyEvent>) to avoid to write corrupted data.
When storing a ‘standalone’ vector you need to explicitly request the dictionary for it.
Add to your MyEvent.h:
#ifdef __ROOTCLING__
#pragma link C++ class std::vector<MyEvent>+;
#endif
Huh, so I have to add said lines for every Event Class I define (if i want to use said class in a vector)? Are there ways where I don’t have to explicitly request the dictionary for the vector?
Yes. When you use the syntax .L ...+ one of the implicit operation is to add the equivalent of the pragma link line for the classes declared in the the file. In addition when generating the dictionary for a class, the system will also automatically generate the dictionary for any collection it uses. So if you add to your MyEvent.h the class:
class EventHolder {
std::vector<Event> f1;
std::list<Event> f2;
};
the dictionaries for std::vector<Event> and std::list<Event> will be automatically generated.