ROOT CERN指针类型不匹配求助:无法从ROOT文件生成直方图
问题:ROOT中vector类型分支无法生成直方图
初始错误信息
Error in TTree::SetBranchAddress: The pointer type given "Double_t" (8) does not correspond to the type needed "vector
" by the branch: mu_phi
运行脚本后画布仅显示条目数、均值等统计信息,所有直方图样式完全一致。尝试将Double_t替换为vector<float>后,出现新编译错误:
error: no matching member function for call to 'Fill'
muEta->Fill(mu_eta);/snap/root-framework/838/usr/local/include/TH1.h:219:21: note: candidate function not viable: no known conversion from 'vector<float>' to 'Double_t' (aka 'double') for 1st argument virtual Int_t Fill(Double_t x); ^ /snap/root-framework/838/usr/local/include/TH1.h:220:21: note: candidate function not viable: requires 2 arguments, but 1 was provided virtual Int_t Fill(Double_t x, Double_t w); ^ /snap/root-framework/838/usr/local/include/TH1.h:221:21: note: candidate function not viable: requires 2 arguments, but 1 was provided virtual Int_t Fill(const char *name, Double_t w);
原始脚本
void script(){ TFile *file = TFile::Open("output_data.root"); TTree* tree = (TTree*)file->Get("nominal"); TChain* fchain = new TChain("nominal"); fchain->Add("output_data.root"); Double_t mu_pt, mu_e, mu_eta, mu_phi; //set branches to variables tree->SetBranchAddress("mu_pt", &mu_pt); tree->SetBranchAddress("mu_e", &mu_e); tree->SetBranchAddress("mu_eta", &mu_eta); tree->SetBranchAddress("mu_phi", &mu_phi); TH1D *muPt = new TH1D("muPt", ";p_{T} [GeV/c];Events", 100, 0., 200.); TH1D *muEta = new TH1D("muEta", ";;#eta;Events", 50, -3, 3); TH1D *muE = new TH1D("muE", ";;Energy;Events", 50, 0, 200); TH1D *muPhi = new TH1D("muPhi", ";;#phi;Events", 50, -4, 4); TH1D *mass = new TH1D("mass", ";;mass;Events", 50, 0, 200); Long64_t nentries = fchain->GetEntries(); for (int i=0; i<nentries ; i++) { Long64_t ientry = fchain->LoadTree(i); if (ientry <0 ) break; fchain->GetEntry(i); muEta->Fill(mu_eta); muPt->Fill(mu_pt); muPhi->Fill(mu_phi); muE->Fill(mu_e); } cout << "entries = " << nentries << endl; TCanvas *c1 = new TCanvas("Eta","Eta",800 ,800); c1->cd(); muEta->Draw(); }
ROOT版本:6.26/10
解决方案
1. 正确绑定vector类型分支
分支mu_pt、mu_e、mu_eta、mu_phi均为vector<float>类型,需将变量声明为对应类型,同时删除冗余的TFile和TTree代码(直接用TChain即可):
#include <vector> // 必须包含vector头文件 vector<float> mu_pt, mu_e, mu_eta, mu_phi; // 绑定分支地址到vector变量 fchain->SetBranchAddress("mu_pt", &mu_pt); fchain->SetBranchAddress("mu_e", &mu_e); fchain->SetBranchAddress("mu_eta", &mu_eta); fchain->SetBranchAddress("mu_phi", &mu_phi);
2. 遍历vector填充直方图
TH1D::Fill()仅接受单个数值,需遍历vector中的每个元素完成填充(假设每个事件的四个vector长度一致,对应同一批粒子的属性):
for (int i=0; i<nentries ; i++) { Long64_t ientry = fchain->LoadTree(i); if (ientry <0 ) break; fchain->GetEntry(i); // 遍历每个粒子的属性填充直方图 for (size_t j=0; j<mu_eta.size(); j++) { muEta->Fill(mu_eta[j]); muPt->Fill(mu_pt[j]); muPhi->Fill(mu_phi[j]); muE->Fill(mu_e[j]); } }
3. 修正后的完整脚本
#include <vector> #include <iostream> using namespace std; void script(){ // 直接用TChain处理文件,无需额外TFile TChain* fchain = new TChain("nominal"); fchain->Add("output_data.root"); // 声明vector类型变量 vector<float> mu_pt, mu_e, mu_eta, mu_phi; // 绑定分支地址到vector变量 fchain->SetBranchAddress("mu_pt", &mu_pt); fchain->SetBranchAddress("mu_e", &mu_e); fchain->SetBranchAddress("mu_eta", &mu_eta); fchain->SetBranchAddress("mu_phi", &mu_phi); // 创建直方图,修正标题格式 TH1D *muPt = new TH1D("muPt", ";p_{T} [GeV/c];Events", 100, 0., 200.); TH1D *muEta = new TH1D("muEta", ";#eta;Events", 50, -3, 3); TH1D *muE = new TH1D("muE", ";Energy [GeV];Events", 50, 0, 200); TH1D *muPhi = new TH1D("muPhi", ";#phi;Events", 50, -4, 4); Long64_t nentries = fchain->GetEntries(); cout << "Total entries: " << nentries << endl; for (int i=0; i<nentries ; i++) { Long64_t ientry = fchain->LoadTree(i); if (ientry <0 ) break; fchain->GetEntry(i); // 遍历每个粒子的属性填充直方图 for (size_t j=0; j<mu_eta.size(); j++) { muEta->Fill(mu_eta[j]); muPt->Fill(mu_pt[j]); muPhi->Fill(mu_phi[j]); muE->Fill(mu_e[j]); } } // 绘制并设置直方图样式 TCanvas *c1 = new TCanvas("Eta","Eta",800 ,800); c1->cd(); muEta->SetLineColor(kBlue); // 设置线条颜色区分样式 muEta->Draw(); c1->SaveAs("mu_eta_hist.pdf"); // 可选保存为文件 // 绘制其他直方图 TCanvas *c2 = new TCanvas("Pt","Pt",800 ,800); c2->cd(); muPt->SetLineColor(kRed); muPt->Draw(); c2->SaveAs("mu_pt_hist.pdf"); }
关键说明
- 必须包含
<vector>头文件,否则无法识别vector类型 - 每个事件可能包含多个粒子,vector存储了同一事件内所有粒子的对应属性,需遍历填充
- 可通过
SetLineColor等方法设置直方图样式,避免所有图外观一致 TChain支持添加多个ROOT文件,后续扩展只需调用fchain->Add("xxx.root")
内容的提问来源于stack exchange,提问作者arrakis
相关产品推荐
相关产品推荐

