Please read tips for efficient and successful posting and posting code
_ROOT Version:6.18.04
_Platform:Linux
_Compiler:g++
Hi ROOT community.
In a simple code I’m trying to simulate events and store them inside branches. The branches which refer to vectors of vectors/TLorentzVectors are not working (not even appearing in the ROOT file).
My source code:
#include <iostream>
#include <sstream>
#include "Pythia8/Pythia.h"
#include "TH1.h"
// ROOT, for interactive graphics.
#include "TVirtualPad.h"
//#include "TApplication.h"
// ROOT, for saving file.
#include "TFile.h"
#include "TTree.h"
#include "TLorentzVector.h"
#include "TROOT.h"
using namespace Pythia8;
TFile* file;
TTree* tree;
vector<TLorentzVector> p4;
vector<int>* id;
vector<vector<int> >* parents;
vector<vector<int> >* children;
float Q;
float Q2;
float aS;
float sHat;
float tHat;
float uHat;
float mHat;
//Everything inside main for now
//============================================================================
int main(int argc, char* argv[], TString name) {
//File setting
file = new TFile("ContactInteraction.root", "RECREATE");
//Tree setting
tree = new TTree("qqbar->qqbar","qqbar->qqbar");
p4 = new vector<TLorentzVector>;
id = new vector<int>;
parents = new vector<vector<int> >;
children = new vector<vector<int> >;
//Branch setting
tree->Branch("p4", &p4);
tree->Branch("id", &id);
tree->Branch("parents", &parents);
tree->Branch("children", &children);
tree->Branch("Q", &Q);
tree->Branch("Q2", &Q2);
tree->Branch("aS", &aS);
tree->Branch("sHat", &sHat);
tree->Branch("tHat", &tHat);
tree->Branch("uHat", &uHat);
tree->Branch("mHat", &mHat);
// Pythia stuff
Pythia pythia;
pythia.readString("ContactInteractions:QCqq2qq = on");
pythia.readString("ContactInteractions:Lambda = 2000.");
pythia.readString("ContactInteractions:etaLL = -1");
pythia.readString("ContactInteractions:etaRR = 0");
pythia.readString("ContactInteractions:etaLR = 0");
pythia.readString("PhaseSpace:pTHatMin = 20.");
pythia.readString("Beams:eCM = 14000.");
pythia.init();
// Begin event loop. Generate event; skip if generation aborted.
for (int iEvent = 0; iEvent < 100; ++iEvent) {
if (!pythia.next()) continue;
//Tree clearing
p4.clear();
id->clear();
for(int i=0 ; i<parents->size() ; ++i) parents->at(i).clear();
for(int i=0 ; i<children->size() ; ++i) children->at(i).clear();
parents->clear();
children->clear();
Q = -1;
Q2 = -1;
aS = -1;
sHat = -1;
tHat = -1;
uHat = -1;
mHat = -1;
pythia.process.list();
Q = pythia.info.QRen();
Q2 = pythia.info.Q2Ren();
aS = pythia.info.alphaS();
sHat = pythia.info.sHat();
tHat = pythia.info.tHat();
uHat = pythia.info.uHat();
mHat = pythia.info.mHat();
vector<int> vtmp;
for (int i = 0; i < pythia.process.size(); ++i)
{
TLorentzVector p;
p->SetPxPyPzE(pythia.process[i].px(),pythia.process[i].py(),pythia.process[i].pz(),pythia.process[i].e());
p4->push_back(p);
id->push_back(pythia.process[i].id());
int m1 = pythia.process[i].mother1();
int m2 = pythia.process[i].mother2();
int d1 = pythia.process[i].daughter1();
int d2 = pythia.process[i].daughter2();
parents->push_back(vtmp);
children->push_back(vtmp);
if(m1>=0) parents->at(i).push_back(pythia.process[m1].index());
if(m2>=0) parents->at(i).push_back(pythia.process[m2].index());
if(d1>=0) children->at(i).push_back(pythia.process[d1].index());
if(d2>=0) children->at(i).push_back(pythia.process[d2].index());
}
//Tree filling
file->cd();
tree->Fill();
}
//Tree writing
file->cd();
tree->Write();
pythia.stat();
return 0;
}
The code is built OK but upon running I get a segmentation violation and as mentioned above the branches named p4
, parents
and children
do not even appear inside the TTree
. All other branches seem fine. Help please!
First, I think it should be:
vector<TLorentzVector> *p4 = nullptr;
vector<int>* id = nullptr;
vector<vector<int> >* parents = nullptr;
vector<vector<int> >* children = nullptr;
Then, this code is wrong:
TLorentzVector p;
p->SetPxPyPzE(pythia.process[i].px(),pythia.process[i].py(),pythia.process[i].pz(),pythia.process[i].e());
p4->push_back(p);
It should be either something like this:
TLorentzVector *p = new TLoretzVector(pythia.process[i].px(),pythia.process[i].py(),pythia.process[i].pz(),pythia.process[i].e());
p4->push_back(p);
or something (most probably) like this:
TLorentzVector p;
p.SetPxPyPzE(pythia.process[i].px(),pythia.process[i].py(),pythia.process[i].pz(),pythia.process[i].e());
p4->push_back(p);
It is weird that your compiler doesn’t complain when compiling this code…
Thanks for the quick reply.
I’ve set the four vectors to nullptr and implemented
TLorentzVector p;
p.SetPxPyPzE(pythia.process[i].px(),pythia.process[i].py(),pythia.process[i].pz(),pythia.process[i].e());
p4->push_back(p);
Unfortunately, no change…
Just to clarify: the id
vector of integers works fine and appears inside the TTree
.
Can you post the traceback?
Sure:
*------- PYTHIA Error and Warning Messages Statistics ----------------------------------------------------------*
| |
| times message |
| |
| 1 Warning in StringFragmentation::fragmentToJunction: bad convergence junction rest frame |
| |
*------- End PYTHIA Error and Warning Messages Statistics ------------------------------------------------------*
*** Break *** segmentation violation
===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0 0x00007f932e326dba in __GI___wait4 (pid=732433, stat_loc=stat_loc
entry=0x7fff02ed4b18, options=options
entry=0, usage=usage
entry=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:27
#1 0x00007f932e326d7b in __GI___waitpid (pid=<optimized out>, stat_loc=stat_loc
entry=0x7fff02ed4b18, options=options
entry=0) at waitpid.c:38
#2 0x00007f932e2960e7 in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:172
#3 0x00007f932f682e63 in TUnixSystem::StackTrace() () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#4 0x00007f932f685854 in TUnixSystem::DispatchSignals(ESignals) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#5 <signal handler called>
#6 0x00007f932e2dbd01 in _int_malloc (av=av
entry=0x7f932e42cb80 <main_arena>, bytes=bytes
entry=72) at malloc.c:3671
#7 0x00007f932e2de2d4 in __GI___libc_malloc (bytes=72) at malloc.c:3058
#8 0x00007f932e649c29 in operator new(unsigned long) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#9 0x00007f932f585ae9 in TStorage::ObjectAlloc(unsigned long) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#10 0x00007f932f5dcbab in THashList::THashList(int, int) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#11 0x00007f932f645be8 in TListOfDataMembers::TListOfDataMembers(TClass*) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#12 0x00007f932f61c9bc in TClass::GetListOfDataMembers(bool) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#13 0x00007f932f62c0da in TClass::GetDataMember(char const*) const () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#14 0x00007f932f63020e in TBuildRealData::Inspect(TClass*, char const*, char const*, void const*, bool) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#15 0x00007f9329e3864a in TCling::InspectMembers(TMemberInspector&, void const*, TClass const*, bool) () from /home/rbrener/Programs/root_v6.18.04/lib/libCling.so
#16 0x00007f932f61eb58 in TClass::CallShowMembers(void const*, TMemberInspector&, bool) const () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#17 0x00007f932f62e05d in TClass::BuildRealData(void*, bool) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#18 0x00007f932ee40e55 in TBufferFile::WriteClassBuffer(TClass const*, void*) () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#19 0x00007f932f666396 in TStreamerSTL::Streamer(TBuffer&) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#20 0x00007f932ee400cc in TBufferFile::WriteObjectClass(void const*, TClass const*, bool) () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#21 0x00007f932ee47355 in TBufferIO::WriteObjectAny(void const*, TClass const*, bool) () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#22 0x00007f932f5ee86d in TObjArray::Streamer(TBuffer&) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#23 0x00007f932ee400cc in TBufferFile::WriteObjectClass(void const*, TClass const*, bool) () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#24 0x00007f932ee47243 in TBufferIO::WriteObjectAny(void const*, TClass const*, bool) () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#25 0x00007f932eef946a in TStreamerInfo::Streamer(TBuffer&) () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#26 0x00007f932ee400cc in TBufferFile::WriteObjectClass(void const*, TClass const*, bool) () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#27 0x00007f932ee47355 in TBufferIO::WriteObjectAny(void const*, TClass const*, bool) () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#28 0x00007f932f5e9b9f in TList::Streamer(TBuffer&) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#29 0x00007f932eed8309 in TKey::TKey(TObject const*, char const*, int, TDirectory*) () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#30 0x00007f932eea18c8 in TFile::WriteStreamerInfo() () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#31 0x00007f932eea0b54 in TFile::Close(char const*) () from /home/rbrener/Programs/root_v6.18.04/lib/libRIO.so.6.18
#32 0x00007f932f5223a1 in (anonymous namespace)::R__ListSlowClose(TList*) () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#33 0x00007f932f52302c in TROOT::CloseFiles() () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#34 0x00007f932f523742 in TROOT::EndOfProcessCleanups() () from /home/rbrener/Programs/root_v6.18.04/lib/libCore.so.6.18
#35 0x00007f932e28aa27 in __run_exit_handlers (status=0, listp=0x7f932e42c718 <__exit_funcs>, run_list_atexit=run_list_atexit
entry=true, run_dtors=run_dtors
entry=true) at exit.c:108
#36 0x00007f932e28abe0 in __GI_exit (status=<optimized out>) at exit.c:139
#37 0x00007f932e2680ba in __libc_start_main (main=0x5563939e06a0 <main>, argc=1, argv=0x7fff02ed8768, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff02ed8758) at ../csu/libc-start.c:342
#38 0x00005563939e19ae in _start ()
===========================================================
Another question: do you have any warning when you compile your code?
OK so I don’t see anything obviously wrong in your code (beside the p4.clear()
which is now probably p4->clear()
, otherwise the compiler would complain), but maybe @pcanal or @eguiraud can take another look and see something I didn’t… Or build your code in debug mode and start to debug it
Thanks again. Of course I’ve adapted on a par with the p4 pointer etc. BTW things like std::cout << p4->at(i).Pz() << std::endl;
produce expected outputs (looks fine)…
You’re welcome. So let’s see if @pcanal has another idea…
To add something that may be useful: even when removing all operations w.r.t. p4 and leaving only:
vector<TLorentzVector>* p4 = nullptr;
p4 = new vector<TLorentzVector>;
tree->Branch("p4", &p4);
the branch p4
isn’t created.
I know what’s going wrong. I’ll keep you in touch
When running your code, you should see those errors:
Error in <TTree::Branch>: The class requested (vector<TLorentzVector>) for the branch "p4" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (vector<TLorentzVector>) to avoid to write corrupted data.
Error in <TTree::Branch>: The class requested (vector<vector<int> >) for the branch "parents" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (vector<vector<int> >) to avoid to write corrupted data.
Error in <TTree::Branch>: The class requested (vector<vector<int> >) for the branch "children" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (vector<vector<int> >) to avoid to write corrupted data.
Meaning that you have to generate a dictionary for your collections. For example, add a LinkDef.h
file containing
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class std::vector<TLorentzVector>+;
#pragma link C++ class std::vector<std::vector<int>>+;
#pragma link C++ class std::vector<std::vector<int>>+;
#endif
And to prevent the crash, add
file->Close();
delete file;
at the end, before return 0;
BTW, here is the resulting root file: ContactInteraction.root (20.9 KB)
Hi! Thanks. I’ve added the file and correspondingly included i.e. #include "LinkDef.h"
. I’ve also made the changes you noted. The file you generated looks great! But unfortunately at my end there is no change. What may I be missing?
BTW I’ve also tried adding a line #pragma link C++ defined_in "LinkDef.h";
alas, without change.
Just to mention, you are right that I’m (still) seeing the error:
Error in <TTree::Branch>: The class requested (vector<TLorentzVector>) for the branch "p4" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (vector<TLorentzVector>) to avoid to write corrupted data.
Error in <TTree::Branch>: The class requested (vector<vector<int> >) for the branch "parents" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (vector<vector<int> >) to avoid to write corrupted data.
Error in <TTree::Branch>: The class requested (vector<vector<int> >) for the branch "children" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (vector<vector<int> >) to avoid to write corrupted data.
So now the problem is perhaps linking my code to the LinkDef.h header? I thought #include "LinkDef.h"
would be sufficient… I feel we’re nearly there — sorry if I’ve missed something obvious.
Well, sorry, I’ve not been clear enough. You have to generate a dictionary. To do so, you need to add two lines in your LinkDef.h
file:
#include <vector>
#include "TLorentzVector.h"
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class std::vector<TLorentzVector>+;
#pragma link C++ class std::vector<std::vector<int>>+;
#pragma link C++ class std::vector<std::vector<int>>+;
#endif
And then, if you use CMake, add
ROOT_GENERATE_DICTIONARY(MyDict LinkDef.h)
and add MyDict.cxx
in the list of source files in your CMakeLists.txt
Otherwise you can add this command in your makefile (or type it in the command line):
rootcling -f myDict.cxx LinkDef.h
and add myDict.cxx
in the list of source files
You can take a look at rootcling the cling dictionary generator documentation
BTW, here is my CMakeLists.txt
, if that can help:
# Check if cmake has the required version
CMAKE_MINIMUM_REQUIRED(VERSION 3.16.4 FATAL_ERROR)
set(PROJECT_NAME test_pythia8)
project(${PROJECT_NAME})
find_package(ROOT REQUIRED)
set(CMAKE_CXX_FLAGS "${ROOT_CXX_FLAGS}")
ROOT_GENERATE_DICTIONARY(${PROJECT_NAME}Dict LinkDef.h)
set(PYTHIA8 $ENV{PYTHIA8})
set(PYTHIA8_INCLUDE_DIR "${PYTHIA8}/include")
set(PYTHIA8_LIB_DIR "${PYTHIA8}/lib")
include(${ROOT_USE_FILE})
include_directories(${ROOT_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR} ${PYTHIA8_INCLUDE_DIR})
link_directories(${ROOT_LIBRARY_DIR} ${PYTHIA8_LIB_DIR})
add_executable(${PROJECT_NAME} ${PROJECT_NAME}.cxx ${PROJECT_NAME}Dict.cxx)
target_link_libraries(${PROJECT_NAME} ${ROOT_LIBRARIES} Pythia8.lib)
Thanks and sorry — I need to be completely unequivocal because there are many directories/files alike. To be clear:
- I’ve added the two lines to LinkDef.h
- CMake — I’m not sure whether I do use it. I can testify I’ve got a file
~/Programs/pythia8303/examples/Makefile
which has Pythia-related definitions. The only location I can think of where I’ve found a CMakeLists.txt
file is ~/Programs/root_v6.18.04/tutorials/CMakeLists.txt
and I’m unsure whether that’s the one I should edit.
- Source files — I’ve got a bunch of them here
~/Programs/pythia8303/src
relating to Pythia — is this the location I should add myDict.cxx
to?
Thanks again.