Performance enhancing drug

Hi,

Tree::Draw can help you with that :slight_smile:. Do something like:mytree->SetEstimate(end_index-begin_index); mytree->Draw("X","","goff",end_index,begin_index); XX = mytree->GetV1(); // returns an array of double

Cheers,
Philippe.

Hi Philippe,
Thanks for your hint.
I used your bit of code in order to generate a pointer to an entire column, like that

tree.Draw("t","","goff",N,0) df_t=tree.GetV1()

Now, type (df_t) is given as
<type ‘buffer’>

I know that this is a c pointer to my data, but I was not able to find out how to cast that thing to a scipy array without looping over it. Is that not possible using ctypes?
Maybe there is a simple way I did not find…

One more observation:

using the following code

[code]tree.Draw(“t”,"",“goff”,N,0)
df_t=tree.GetV1()

tree.Draw(“X”,"",“goff”,N,0)
df_X=tree.GetV1()[/code]

will result in df_t and df_X containing the exact same data (that of X, so apparaently the GetV1 function gives back a kind of pointer which is the same for every call… ) Is that supposed to be that way?

Thanks, Bjoern

You must copy the array returned by tree.GetV1(). This array is refilled by each call to tree.Draw().

Rene

Yes, I figured that much.
I was just astonished because the C++ equivalent does not do the same thing.
In python, I solved the problem with


tree.Draw("t","","goff",N,0)
df_t=tree.GetV1()
t=copy.deepcopy(scipy.frombuffer(buffer=df_t,dtype='double',count=N))

tree.Draw("X","","goff",N,0)
df_X=tree.GetV1();
X=copy.deepcopy(scipy.frombuffer(buffer=df_X,dtype='double',count=N))
  
tree.Draw("Xa","","goff",N,0)
df_Xa=tree.GetV1();
Xa=copy.deepcopy(scipy.frombuffer(buffer=df_Xa,dtype='double',count=N))

It is necessary to perform the copy.deepcopy operation AND to perform this operation directly after the call to Draw()

In C++,
the following does the trick:

Double_t * t_persistent = new Double_t [nentries] ; Double_t * X_persistent = new Double_t [nentries] ; Double_t * Xa_persistent = new Double_t [nentries] ; t1->Draw("t","","goff",nentries,0); t = t1->GetV1(); // returns an array of double t1->Draw("X","","goff",nentries,0); X = t1->GetV1(); // returns an array of double t1->Draw("Xa","","goff",nentries,0); Xa = t1->GetV1(); // returns an array of double for (int i=1;i<nentries;i++) { t_persistent[i]=t[i]; X_persistent[i]=X[i]; Xa_persistent[i]=Xa[i]; }
In the C++ case, the “copy” operation takes place in the loop; here, it is seemingly not necessary to perfom the copy operation directly after the call to Draw(). This difference confuses me.

I am now down to approximately 1/2 the speed of C++ using my python approach. This is already quite good. One final step would be to swig the whole reading application and then map it back on a scipy array. I wrote the swig application which returns a
<Swig Object of type ‘Double_t *’ at 0x2ac741fdd010>
I am now hoping that someone has a nice and simple solution to map this thing onto a scipy array, as my previous solution (which worked with the
<type ‘buffer’> object and scipy.frombuffer) does not work anymore…

Cheers,
Philippe

Bjoern,

[quote]<Swig Object of type ‘Double_t *’ at 0x2ac741fdd010>
I am now hoping that someone has a nice and simple solution to map this thing onto a scipy array[/quote]
likely both scipy and Swig allow conversion from and to CObjects, so I’d search for that to find a way of casting one into the other.

Cheers,
Wim