root icon indicating copy to clipboard operation
root copied to clipboard

TFileMerger behaviour when the directory structure contains repeated names

Open jln-m opened this issue 1 year ago • 0 comments

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

jln-m avatar Aug 07 '24 22:08 jln-m