Creating a THnSparse using RDataFrame

Sorry for bothering with the following topic again (on top of that during the low season).

The topic is related with the following unreplied post.

I thought I could circumvent this issue by manually filling a THnSparse object by retrieving the vectors from the RDataFrame using Take. But this translates into other issues. As I deduce from @mczurylo reply I have to try to do it using RDataFrame methods directly.

I can create without problems a THnD object, but I run into troubles when trying to do the same with a THnSparse. Do you have any insights on this topic?

root [0] auto hN = dSet->GetDataFrame().HistoND({"Name","Title", 3, {40,40,20}, {-20,-20,0}, {20,20,10}}, {"final_posX", "final_posY", "final_energy"});
root [1] THnD *hNd = new THnD(*hN)
(THnD *) 0x558661496410
root [2] THnSparseD *hSparse = new THnSparseD(*hN)
ROOT_prompt_2:1:27: error: no matching constructor for initialization of 'THnSparseD' (aka 'THnSparseT<TArrayD>')
THnSparseD *hSparse = new THnSparseD(*hN)
                          ^          ~~~
/programas/root/6.26.06/include/THnSparse.h:210:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'THnT<double>' to 'const THnSparseT<TArrayD>' for 1st argument
class THnSparseT: public THnSparse {
/programas/root/6.26.06/include/THnSparse.h:212:4: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
   THnSparseT() {}
/programas/root/6.26.06/include/THnSparse.h:213:4: note: candidate constructor not viable: requires at least 4 arguments, but 1 was provided
   THnSparseT(const char* name, const char* title, Int_t dim,

Thank you!

I hope @eguiraud or @vpadulan can help

Hi @Javier_Galan ,

the error correctly complains that you are trying to copy-construct a 'THnSparseD' (aka 'THnSparseT<TArrayD>') from a THnD, and there is no such copy-constructor available. See the THnSparseT docs here for the available constructors.

However, if you have already filled a THn you have already paid the corresponding memory allocation cost, so maybe you don’t have to then “compress” the THn in a THnSparse? Or, alternatively, if you really need to fill a THnSparse you should not go through a THn to do it because it probably defeats the purpose.

In case it’s useful: we have a tutorial that shows how to create a custom RDF action that fills a THn, you can probably adapt it to fill a THnSparse instead.

As a side note, it’s weird/worrying that Take+manual fill produces a different result than using RDF’s methods, that’s to be clarified.


Ok, I see the point with the memory allocation, I thought since both THn and THnSparse inherit from THnBase, calling HistoND would do it.

I was just wondering how to quickly create a THnSparse from RDataFrame. Thanks to the tutorial you provided I see that it is possible, but I am not ready to pay the price in my implementation. So, I think I will survive using just a THnD in my implementation.

I guess, once I have initialised a THnD I could just fill manually a new THnSparse in case I need? Filling only those bins with content different from zero and then delete the THnD.

Yes that’s an option.

We could also think of offering an RDF action that returns a THnSparse directly in the future, the only reason it’s not there is that there hasn’t been request for it. Feel free to open a feature request at Sign in to GitHub · GitHub .


1 Like

Yes, that would be great!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.