root
root copied to clipboard
TFileMerger behaviour when the directory structure contains repeated names
Check duplicate issues.
- [X] Checked for duplicates
Description
For a ROOT file structured with top-level directories A and B, it seems that if B contains a subdirectory also named A the objects in that subdirectory may fail being properly merged when using hadd; instead the outcome is a simple copy of the object in the first source file...
The getDirectory() helper in TFilerMerger::MergeOne() indeed apparently favours a lookup based on the directory name and not the full path, which may not always pick the intended directory: https://github.com/root-project/root/blob/0aa2b6b8760b78dff2cffd873f955735fa1b0ef3/io/io/src/TFileMerger.cxx#L548
Reproducer
Save self-contained script below to mwe.cxx and execute with root -l -b -q mwe.cxx++
#include "TFileMerger.h"
#include "TFile.h"
#include "TH1D.h"
#include <iostream>
void createSrcFile(const char* name)
{
TFile f(name, "RECREATE");
f.mkdir("A", "");
f.mkdir("B/A", "");
f.mkdir("C/D/A", "");
f.cd("A");
TH1D h1("H1", "H1", 1, 0., 1.);
h1.SetBinContent(1, 1);
h1.Write();
f.cd("B/A");
TH1D h2("H2", "H2", 1, 0., 1.);
h2.SetBinContent(1, 10);
h2.Write();
f.cd("C/D/A");
TH1D h3("H3", "H3", 1, 0., 1.);
h3.SetBinContent(1, 100);
h3.Write();
f.Close();
}
void check(const char* filename, const char* deco)
{
TFile f(filename, "READ");
std::cout << deco
<< f.Get<TH1D>("A/H1")->GetBinContent(1)
<< " "
<< f.Get<TH1D>("B/A/H2")->GetBinContent(1)
<< " "
<< f.Get<TH1D>("C/D/A/H3")->GetBinContent(1)
<< std::endl;
f.Close();
}
void mwe()
{
createSrcFile("src1.root");
createSrcFile("src2.root");
TFileMerger mg;
mg.AddFile("src1.root", kFALSE);
mg.AddFile("src2.root", kFALSE);
mg.OutputFile("dest.root", kTRUE);
mg.Merge();
check("src1.root", " ");
check("src2.root", "+ ");
std::cout << "------------\n";
check("dest.root", "= ");
}
ROOT version
6.32.02
Installation method
lxplus native
Operating system
RHEL 9.4
Additional context
No response