Write to stream method for RooDataSets (and RooArgLists)

Greetings, everybody.

I ran into a small but annoying problem. In my analysis, I do an intermediate step where I save events after pre-selection using RooDataSet::write method; as they’re quite large and I don’t want to create unnecessary TTrees.

This works fine. However, if I get a lot of events, and want to save the event number, writing the event number with default precision is not enough.

I looked through the documentation, and found no way to access the precision of the ofstream in RooFit write methods. Is there a solution that doesn’t involve overloading write to stream methods?

Hello @achernov,

You should be able to hack it. There is RooMsgService::log, which returns the ostream it is writing to. This gets called by the messaging macros such as oocoutX. This will do the trick:

> oocoutW((TObject*)nullptr,Generation) << "Test" << std::endl;
[#0] WARNING:Generation -- Test

Add your favourite stream modifiers. Just make sure that the message stream you are calling is the one that does the logging. The stream number is printed at the beginning of the line.

You might have to adjust the W for warning to Error or Fatal, and you might have to adjust the message topic MsgTopic as well.

Thank you, I’ll try this today on the plane.

Perhaps my original message wasn’t clear

The method I’m talking about is the ‘write’ method of RooDataSet class:

https://root.cern.ch/doc/master/classRooDataSet.html#a8509d09ba494fdab351c07cd41c463ff

As one can see, the ofs object exists only in the scope of the function, and ceases to exist once it delivers a return, unless I am horribly mistaken - as it is not one of its’ argument, I can’t think of a way to access it.

And, as such, solution proposed by @StephanH isn’t going to work.

Hi @achernov,

Now I understand what the problem is. How about this:
I write a RooDataSet::write that takes an ostream as argument. You supply whatever stream you want, with the desired precision, and the dataset is written using this stream?

That is precisely what I meant by overloading a function.

Workaround isn’t particularly hard, but, since I am almost certainly not a first person to encounter the need to access properties of a stream in some interfaces, that modification should probably be merged.

Hello @achernov,

a fix has been merged into the master branch of root. If you are interested, you can test this tomorrow on lxplus7.cern.ch, when the ROOT nightlies have been built.

Set up the ROOT nightly like this:

source /cvmfs/sft.cern.ch/lcg/views/LCG_94/x86_64-centos7-gcc8-opt/setup.sh
source /cvmfs/sft.cern.ch/lcg/views/dev3/latest/x86_64-centos7-gcc8-opt/bin/thisroot.sh

Of course, you can also use other versions that you find in /cvmfs/sft.cern.ch/lcg/views/dev3/latest/

Thank you, I will try this tomorrow.

The nightly build works, I can now set up precision according to my data.

I guess the discussion can be closed now.

This change will be released in root 6.16.