首先介绍一下ROOT中的数据储存方式,你可以用txt或者其他C++能用的方法存储或读取数据,但Ntuple和Tree是更高效更好用的方式。
Ntuple:类似数据表格,存取浮点数
Tree:存取多种类型的数据,ROOT中的所有数据类型
实际上Ntuple是Tree的一个简化情况。所以在这只简要介绍Tree。
1.Tree的写入
int Run, Event;
float x,y,z;
TFile *f = new TFile("test.root","recreate");
TTree *T = new TTree("T","tree");
T->Branch("Run",&Run,"Run/I");
T->Branch("Event",&Event,"Event/I");
T->Branch("x",&x,"x/F");
T->Branch("y",&y,"y/F");
T->Branch("z",&z,"z/F");
TRandom r;
for (Int_t i=0;i<10000;i++)
{
if (i < 5000) Run = 1;
else Run = 2;
Event = i;
x = r.Gaus(10,1);
y = r.Gaus(20,2);
z = r.Landau(2,1);
T->Fill();
}
T->Print();
T->Write();
delete f;

输出的结果
TFile:打开或生成一个root文件,你也可以打开其他格式的文件,请参照ROOT TFile::TFile,重要的是给定文件名和操作选项。在完成对文件的操作后,把文件delete,以免后续代码对文件的数据造成影响。当然,在delete之后,所有定义的直方图或者图形对象也会消失。
Option | Description |
---|---|
NEW or CREATE | Create a new file and open it for writing, if the file already exists the file is not opened. |
RECREATE | Create a new file, if the file already exists it will be overwritten. |
UPDATE | Open an existing file for writing. If no file exists, it is created. |
READ | Open an existing file for reading (default). |
NET | Used by derived remote file access classes, not a user callable option. |
WEB | Used by derived remote http access class, not a user callable option. |
Ttree的数据结构,可以先简单的考虑为:树(Tree)->枝(Branch)->叶(Leaf)的结构,每个树枝上有不同的数据结构。所以在填充数据之前需要先定义好Branch,通过定义的地址address对数据进行操作,leaflist是所有变量名称和类型的串联,变量名称和变量类型用斜线(/)分隔。
TBranch * TTree::Branch
(
const char * name,
void * address,
const char * leaflist,
Int_t bufsize = 32000
)
C
: a character string terminated by the 0 characterB
: an 8 bit signed integer (Char_t
)b
: an 8 bit unsigned integer (UChar_t
)S
: a 16 bit signed integer (Short_t
)s
: a 16 bit unsigned integer (UShort_t
)I
: a 32 bit signed integer (Int_t
)i
: a 32 bit unsigned integer (UInt_t
)F
: a 32 bit floating point (Float_t
)f
: a 24 bit floating point with truncated mantissa (Float16_t
)D
: a 64 bit floating point (Double_t
)d
: a 24 bit truncated floating point (Double32_t
)L
: a 64 bit signed integer (Long64_t
)l
: a 64 bit unsigned integer (ULong64_t
)G
: a long signed integer, stored as 64 bit (Long_t
)g
: a long unsigned integer, stored as 64 bit (ULong_t
)O
: [the lettero
, not a zero] a boolean (Bool_t
)
对Tree数据的简单展示,TTree::Print能显示出tree的数据结构,TTree::Scan能列出具体的数据。
数据的填充:TTree::Fill,填充所有的Branch(只想填充一个Branch的方法将在另一篇文章中介绍),TTree::Write,将tree写入打开的TFile文件。
2.Tree的读取和做图
以刚才创建的test.root为例,进行读取和制图。
TFile* f = TFile::Open("test.root","READ");
TTree *tree = 0;
f->GetObject("T",tree);
//tree->Print();
TCanvas *c = new TCanvas();
c->Divide(3,1);
TH1 *h1 = new TH1F("h1","x",100,5,15);
float arr;
tree->SetBranchAddress("x",&arr);
for(int i = 0; i<10000; i++)
{
tree->GetEntry(i);
h1->Fill(arr);
}
c->cd(1);
tree->Draw("x");
c->cd(2);
h1->Draw();
c->cd(3);
tree->Draw("x:y","z>4","colz");
c->Draw();
首先可以看到Tree中自带的一些画图功能,可以进行简单的数据展示。TTree::Draw()有许多丰富的功能,但很多时候还是需要把数据读取再进行处理,上面的代码给出了一个简单的例子。
TTree::SetBranchAddress,使用一个对象来指代Branch中的内容,在这里Branch中存储的是Float类型,所以定义Float变量arr指向x这个Branch。
TTree::GetEntry,读取第i个entry的所有Branch的所有数据,可以通过SetBranchStatus决定某个树枝能否被读取。