`hadd` reverses order of object cycles


I have a file with a few cycles for one object (RooFitResult). The latest one that was written has the largest cycle number as expected. However, when I run the file through hadd, the last-written object now has the smallest cycle number. Is there a way to preserve the order or only write the last cycle with hadd? This breaks the default behavior of reading the largest cycle.

ROOT 6.10/06, also tried 6.20/06


hadd ignores (since the default semantic is for cycles to be ‘backup’ copies) all but the highest cycles of each file. The cycles that might see on the output file are intermediary result (merge of a subset of the files).

However, it might be misunderstanding your description and maybe you can share a set of file reproducing the problem.

Right, I’m not trying to do anything different than use the highest cycle. You can reproduce the behavior like this (I just tried it in 6.22/06):

Dump this into test.C

void test(){
    TFile f("test.root","recreate");

    TNamed obj("first","first");



Processing test.C...
TFile**		test.root	
 TFile*		test.root	
  KEY: TNamed	first;3	Third
  KEY: TNamed	first;2	Second
  KEY: TNamed	first;1	first

Run hadd on the output file:
hadd test_merged.root test.root

Then list the contents of the ‘merged’ file and you see that the cycles have been reversed. This is troublesome because, as you pointed out, everything assumes the highest cycle is the newest and default one to use.

root [1] .ls
TFile**		test_merged.root	
 TFile*		test_merged.root	
  KEY: TNamed	first;3	first
  KEY: TNamed	first;2	Second
  KEY: TNamed	first;1	Third


I see. It is likely a bug that had copies anything but the “first;3” to the output … but indeed even more annoying that it does so in reserve order. … so there is a bug there … :frowning:

However, do you really intent (as is the case here) to merge “non-mergeable” objects. Example of merge-able object include TH1F and TTree. …

humm … right. … you mention RooFitResult, should those be mergeable? (If they are not mergeable they might need, also more distinct names so that you can distinguish which result comes from which files … independently of the cycle bug above). @jonas What do you think?

Just to be clear about my particular use case. I have a number of files that each ideally have one RooFitResult with a different name. I’m just using hadd to get them all into one root file easily. This works fine (except for this issue) as it’s not merging individual objects. I’d guess one cannot merge RooFitResult objects together. It just so happens that after re-running some code to fix errors individual files get multiple copies of these things.

I’ve worked around this for now by always reading in the cycle numbered 1 from the merged file, but it’s a bit error prone.

For what it’s worth, if I do the same test above with a TH1D, I do see the correct expected output in the merged file of a single TH1D which is the latest one I wrote.

TFile**		test_merged.root	
 TFile*		test_merged.root	
  KEY: TH1D	first;1	third


The “copy all the cycles” stems from this feature request: https://savannah.web.cern.ch/HEP_Applications/savroot/bugs/99015.html
which boils down to need to keep the cycle in case one does a multi-stage merge of files that contains “same-name-but-not-megeable” objects.

So now, I am left we need to fix the order … but it would also means (for better or worse) that you heuristic will be wrong with the fixed version of ROOT.

Hi, I don’t really know a thing about object cycles, but I can confirm that RooFitResult is not intended to be merge-able.

hadd has been fixed in the patch branches for upcoming 6.20/10, 6.22/10 and for the upcoming v6.24/00. (See `hadd` reverses order of object cycles · Issue #7676 · root-project/root · GitHub for links to the PRs)

Hi, that’s great! Thanks for the quick action.

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