TTree::Draw() using class method vs. attribute

Hi all,

I am trying to use TTree:Draw to generate histograms from our experimental data. In this process I found an inconsistency when the draw selection string uses class methods vs. class attributes. I can reproduce this issue using the following short example scripts.

When drawing using the class attributes, the histogram is properly filled with the expected data. When drawing via the class methods the histogram has the correct number of entries, but all the entries are ‘0’.

tt.Draw("event.m_channels.m_data");  // <-- Histogram is correct
tt.Draw("event.channels().m_data");  // <-- Histogram is filled with zeros

I am using ROOT 5.26/00b, and can produce this problem on two platforms:

% uname -a
Linux pdsf4 2.6.18-194.11.3.el5.nersc_acct #1 SMP Wed Sep 1 10:56:10 PDT 2010 x86_64 x86_64 x86_64 GNU/Linux

and

$ uname -a
Darwin hahatonka 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386

The script testClasses.C define toy classes for use in this example:

#include <vector>

class Channel
{
public:
  Channel(){;}
  ~Channel(){;}
  std::vector<int>& data(){return m_data;}
public:
  std::vector<int> m_data;
};

class Event
{
public:
  Event(){;}
  ~Event();
  std::vector<Channel*>& channels(){return m_channels;}
public:
  std::vector<Channel*> m_channels;
};

Event::~Event()
{
  std::vector<Channel*>::iterator chanIter, chanEnd=m_channels.end();
  for(chanIter=m_channels.begin(); chanIter!=chanEnd; chanIter++){
    delete *chanIter;
    *chanIter=0;
  }
  m_channels.clear();
}

#ifdef __MAKECINT__
#pragma link C++ nestedclasses;
#pragma link C++ class std::vector<int>+;
#pragma link C++ class Channel+;
#pragma link C++ class std::vector<Channel*>+;
#pragma link C++ class Event+;
#endif

The file writeClasses.C fills a tree with class data:

{

gROOT->ProcessLine(".L testClasses.C+");

Event* event = 0;

TFile f("test.root","RECREATE");
TTree* tt = new TTree("tt","Test Tree");

tt->Branch("event","Event",&event);

for(int i=0;i<10;i++){
  event = new Event();
  for(int j=0;j<5;j++){
    Channel* channel = new Channel();
    for(int k=0;k<3;k++){
      channel.m_data.push_back(k);
    }
    event.m_channels.push_back(channel);
  }
  tt->Fill();
  delete event;
}

tt->Write();
f.Close();

}

The file readTree.C displays the problem:

{

 gROOT->ProcessLine(".L testClasses.C+");
 
 TFile f("test.root");
 TTree* tt = (TTree*)f.Get("tt");
 
 TCanvas c1;
 c1.Divide(0,2);
 c1.cd(1);
 tt.Draw("event.m_channels.m_data");
 c1.cd(2);
 tt.Draw("event.channels().m_data");
}

readTree.C (234 Bytes)
writeClasses.C (456 Bytes)
testClasses.C (742 Bytes)

Hi,

This is indeed a deficiency that I can reproduce. Can you please report this problem to savannah.cern.ch?

Thanks,
Philippe.

Thanks Philippe. I have posted this problem to savannah.cern.ch as bug #72398:

https://savannah.cern.ch/bugs/index.php?72398

Dan

Hi Dan,

This problem is fixed.

Thanks for reporting the issue.
Philippe.