Reflex dictionary generation and TTree Branch

Hi,

I’m trying to fill the branch of a tree w/
std::vector
where MyClass was generated via Reflex.

The class is accessible in ROOT, but the code cashes when doing
tree->Fill()

However, filling a TBranch of MyClass (ie w/o the std::vector) works.

Most likely I don’t have what’s needed in either
selection.xml
MyPackageDict.h

Is there any documentation somewhere about how to use Reflex ?
I’e been shooting in the dark making those files.

Below are some code snippets.
I’m using Root 5.18 with ATLAS Athena software.

Any help welcome.

Cheers
-Anyes

selection.xml

<lcgdict>

  <class name="MyClassContainer" id="954DE958-66C0-4BF5-8AE4-2BC13B60C671"/> 
  <class name="MyClass"/> 
  <class name="std::vector<MyClass*>" />
  <class name="std::vector<MyClass*>::const_iterator" />
  <class name="std::vector<MyClass*>::iterator" />
  <class name="std::vector<MyClass>" />
  <class name="std::vector<MyClass>::const_iterator" />
  <class name="std::vector<MyClass>::iterator" />

  <class name="MyOtherClass"/> 

</lcgdict>

MyPackageDict

[code]
#ifndef MYPACKAGE_MYPACKAGEDICT_H
#define MYPACKAGE_MYPACKAGEDICT_H
#include “MyPackage/MyClass.h”
#include “MyPackage/MyOtherClass.h”
#include “MyPackage/MyClassContainers.h”
#include “MyPackage/MyPackageInterface.h”

namespace dummy_MyPackage{

MyOtherClass t m_dummy_OtherClass;

std::vector m_dummy_MyClass;
std::vector::const_iterator m_dummy_MyClass_cstIter;
std::vector::iterator m_dummy_MyClass_Iter;
std::vector<MyClass*> m_dummy_MyClassPtr;
std::vector<MyClass*>::const_iterator m_dummy_TMyClassPtr_cstIter;
std::vector<MyClass*>::iterator m_dummy_MyClassPtr_Iter;

}

#endif[/code]

In ROOT
I load the lib via

  gSystem->Load("libCintex");
  Cintex::Cintex::Enable();
  gSystem->Load("libPhysics");
  gSystem->Load("libMyPackage");
  gSystem->Load("libMyPackageDict");

Then to make the tree

  TFile* fP = new TFile("test.root","recreate");
  TTree* tree = new TTree("MyTree","MyTree");
  fP->cd();

  std::vector<MyClass>* _myClassA = new std::vector<MyClass>();
  TBranch* bMyClassA =  tree->Branch("mA",&_myClassA, 32000, 99 );

  for(int iEntries=1; iEntries<nMax; iEntries++){ //evt loop
  /* Fill the array */

  tree->Fill(); //Crashes here (see below)
  }
  ...

#0  0x30343036 in ?? ()
#1  0x0056cc24 in TClass::Streamer () from /Atlas/Athena/LCGCMT/LCGCMT_54g/InstallArea/i686-slc4-gcc34-opt/lib/libCore.so
#2  0x0774bcb1 in TBufferFile::WriteFastArray () from /Atlas/Athena/sw/lcg/external/root/5.18.00d/slc4_ia32_gcc34/root/lib/libRIO.so
#3  0x077c24cc in TStreamerInfo::WriteBufferAux<TVirtualCollectionProxy> () from /Atlas/Athena/sw/lcg/external/root/5.18.00d/slc4_ia32_gcc34/root/lib/libRIO.so
#4  0x077c20f0 in TStreamerInfo::WriteBufferSTL () from /Atlas/Athena/sw/lcg/external/root/5.18.00d/slc4_ia32_gcc34/root/lib/libRIO.so
#5  0x0166628c in TBranchElement::FillLeaves () from /Atlas/Athena/sw/lcg/external/root/5.18.00d/slc4_ia32_gcc34/root/lib/libTree.so
#6  0x0166117d in TBranch::Fill () from /Atlas/Athena/sw/lcg/external/root/5.18.00d/slc4_ia32_gcc34/root/lib/libTree.so
#7  0x01665dde in TBranchElement::Fill () from /Atlas/Athena/sw/lcg/external/root/5.18.00d/slc4_ia32_gcc34/root/lib/libTree.so
#8  0x01665dfc in TBranchElement::Fill () from /Atlas/Athena/sw/lcg/external/root/5.18.00d/slc4_ia32_gcc34/root/lib/libTree.so
#9  0x016a3108 in TTree::Fill () from /Atlas/Athena/sw/lcg/external/root/5.18.00d/slc4_ia32_gcc34/root/lib/libTree.so

Hi,

sorry for the late reply - it was hanging out unsubmitted in a tab for a day :-/

Could you try in your selection.xml:

(you’re welcome to remove all the other vector<MyClass…> statements.)

Let me know.

Cheers, Axel.

Axel,

the problems were in the definition of MyClass and I for one wouldn’t mind you view on those documented here …

  1. At first, the class was derived from TObject, which of course was handled with a CINT dictionary. The change was made to not derive from it.

  2. One of the data members was a TLorentzVector. What worked was to create a Reflex dictionary for it and making sure that it would be loaded first. Likely better, and chosen in the end, was to set the splitlevel to 1 (instead of the default 99).

As a final, not yet solved problem (but that isn’t a stopper: indexing can be used), the iterators on the vector don’t work. There is a scoping problem in CINT, but beyond that, operator!= and operator== appeared missing. Funnily enough, the iteration did work in python (which is using the iterator protocol underneath, although it should move silently to indexing if the first fails in a non-fatal way).

Thanks,
Wim

Hi,

Thanks Wim for summarizing the set of issues.
I also would like to understand those.

I did try Axel suggestion, but this does not do anything, split level 1 was still required.

Cheers
-a

Hi,

could you please post a stand-alone example, containing all necessary headers? Note that support for TObject-derived classes was added to genreflex about a month ago, so you might get better results with the head. Nevertheless, the issue you report looks a bit more intricate, so I expect that there are more things going wrong…

Cheers, Axel.

[quote]1) At first, the class was derived from TObject, which of course was handled with a CINT dictionary. The change was made to not derive from it. [/quote]Until a month ago when Axel added support for TObject to genreflex, this would explicitly lead to all the part only in a reflex dictionary to be ignored by the I/O.

[quote]What worked was to create a Reflex dictionary for it and making sure that it would be loaded first. [/quote]Some older version of Cintex (I think) used to ignore the member with a CINT dictionary …

Cheers,
Philippe.