You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ROOT 6.24.06环境下如何逐个合并2800个.root文件以降低内存占用?

逐次合并ROOT文件以降低内存占用方案

针对ROOT 6.24.06版本,以下两种方案可实现逐个加载合并文件,大幅降低内存消耗:

一、Shell循环逐次合并

利用hadd命令每次仅合并当前输出文件与单个源文件,避免一次性加载所有文件。

基础版(文件名无空格)

SOURCE_DIRECTORY="/input_directory/"
OUTPUT_FILE="/output_directory/output.root"

# 复制第一个文件作为初始输出
first_file=$(ls "$SOURCE_DIRECTORY"/*.root | head -n 1)
cp "$first_file" "$OUTPUT_FILE"

# 循环合并剩余文件
for file in $(ls "$SOURCE_DIRECTORY"/*.root | tail -n +2); do
    hadd -f -k "$OUTPUT_FILE" "$OUTPUT_FILE" "$file"
done

鲁棒版(支持带空格的文件名)

SOURCE_DIRECTORY="/input_directory/"
OUTPUT_FILE="/output_directory/output.root"

# 获取第一个文件
first_file=$(find "$SOURCE_DIRECTORY" -maxdepth 1 -type f -name "*.root" | head -n 1)
cp "$first_file" "$OUTPUT_FILE"

# 循环处理剩余文件
find "$SOURCE_DIRECTORY" -maxdepth 1 -type f -name "*.root" | tail -n +2 | while read -r file; do
    hadd -f -k "$OUTPUT_FILE" "$OUTPUT_FILE" "$file"
done

参数说明:

  • -f: 强制覆盖已存在的输出文件
  • -k: 保留损坏文件(可选,根据实际需求添加)

二、ROOT宏脚本(C++)

通过ROOT的C++宏实现更灵活的逐次合并,适合需自定义逻辑的场景。

编写宏文件merge_files.C

#include <TFile.h>
#include <TChain.h>
#include <TSystem.h>
#include <vector>
#include <string>
#include <cstdio>

void merge_files(const char* input_dir, const char* output_file) {
    // 遍历目录获取所有ROOT文件
    std::vector<std::string> file_list;
    void* dir_handle = gSystem->OpenDirectory(input_dir);
    const char* entry;
    while ((entry = gSystem->GetDirEntry(dir_handle))) {
        std::string filename = entry;
        if (filename.find(".root") != std::string::npos && filename != "." && filename != "..") {
            file_list.push_back(std::string(input_dir) + "/" + filename);
        }
    }
    gSystem->FreeDirectory(dir_handle);

    if (file_list.empty()) {
        printf("Error: No ROOT files found in target directory.\n");
        return;
    }

    // 初始化输出文件(复制第一个文件的结构)
    TFile* out_file = TFile::Open(output_file, "RECREATE");
    TFile* first_in_file = TFile::Open(file_list[0].c_str());
    first_in_file->Copy(*out_file);
    delete first_in_file;
    out_file->Close();

    // 逐个合并剩余文件
    for (size_t i = 1; i < file_list.size(); ++i) {
        printf("Merging %zu/%zu: %s\n", i+1, file_list.size(), file_list[i].c_str());
        // 若已知树名,替换为TChain chain("your_tree_name")以提升效率
        TChain chain("");
        chain.Add(file_list[i].c_str());
        chain.Merge(output_file, "UPDATE");
    }

    printf("Merge finished successfully.\n");
}

运行宏

root -l -b -q 'merge_files.C("/input_directory/", "/output_directory/output.root")'

参数说明:

  • -l: 不显示ROOT启动界面
  • -b: 批处理模式运行
  • -q: 运行后退出ROOT

内容的提问来源于stack exchange,提问作者Krishna Neupane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:10:25