2.5 实验数据处理过程¶

基于ROOT的实验数据处理步骤可分成两个阶段。

第一阶段¶

第一阶段主要涉及数据格式转换以及初步整理。 1

原始数据(raw data)¶

  • 实验过程中由前端数据获取系统产生的二进制数据流保存到硬盘形成原始文件。 原始数据的格式是由获取系统编写者定义的,原始数据通常由一系列的数据块(data block)组成,每个数据块内包含来自不同插件的数据,每个插件的数据(数据单元)除了包含各个通道记录的探测器的幅度值之外还包含通道地址、是否超界等状态描述字。为了使后续程序识别不同插件的数据,每个数据单元前后都有特定的标识。

解码(decoding or unpacking):¶

  • 解码程序读取数据中的每个插件的特定标识,并按照对应的方法进行解码, 随后按照实验中每个探测器信号和插件的对应表, 将上述数据转换成每个事件中探测器的测量值,这个过程称之为mapping。这个阶段的数据包含有实验的全部信息,一般称为 原始ROOT文件。

事件重构(event building):¶

  • 根据探测器之间的时间关系,重新组织事件结构。具体做法见第5章。

原始ROOT文件后续处理步骤¶

1. 原始变量连续化¶

  • ADC,TDC等插件记录的道值(channels)为整数值(分立值: 1,2,3,4. ..), 在进行刻度之前需要把分立值进行连续化。具体做法是对每次测量值上加入[0,1) 之间的随机数,这种方法称为 Dithering。注意上述操作并没有破坏原有信息,原有信息可通过取整的方法恢复。
In [1]:
TRandom3 *r = new TRandom3(0);
Int_t ival; 
Double_t val; 

TFile *opf = new TFile("cal.root","recreate");
TTree *tree = new TTree("tree","tree");

tree->Branch("ival", &ival, "ival/I"); //raw ADC value
tree->Branch("val", &val, "val/D");    //with dithering

for(int i=0; i<50000; i++) {
   ival = (int) r->Uniform(0,100);
   val = ival + r->Uniform(0,1);//连续化
   tree->Fill();
}
tree->Write();
opf->Close();
In [2]:
TFile *ipf = new TFile("cal.root");
TTree *tree = (TTree *)ipf->Get("tree");
In [3]:
tree->Draw("ival>>hraw(100,0,100)");
TH1D *hraw = (TH1D *)gROOT->FindObject("hraw");
hraw->SetMinimum(0);
c1->Draw();
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1

刻度ADC参数¶

  • bin的数目与ADC整数范围不一致时出现锯齿结构
In [4]:
tree->Draw("0.4*ival>>hcraw(40,0,40)");
TH1D *hcraw = (TH1D *)gROOT->FindObject("hcraw");
hcraw->SetMinimum(0);
c1->Draw();

刻度连续化ADC参数¶

  • 无锯齿
In [5]:
tree->Draw("0.4*val>>hval(40,0,40)");
TH1D *hval = (TH1D *)gROOT->FindObject("hval");
hval->SetMinimum(0);
c1->Draw();

2. 选择变量有效值区间¶

  • 检查每一个实验参数的完整性,选择合适的变量计算方法。

    • case 1: 实验中PPAC的四个位置路时间信号正常而阳极信号不正常时(信号接触或后端电子学有问题),为了尽可能有效利用实验数据,在位置信号的计算中不要求阳极信号条件。
    • case 2: 中子探测器实验中,如果左侧的q$_l$值记录不正常,可根据时间信号t$_l$,t$_r$和右侧q$_r$值,重建沉积能量Q$_0$值.
  • 只对有效值范围内的数据进行刻度,对有效值范围外的数据(如pedal以下或超界数据)设定与刻度值有明显区别的特定数值(如-1)。

3. 将每个文件中的参数存到histogram中¶

  • 后续处理过程中,除了将每个文件的事件以TTree格式存在ROOT文件(如run001.root)外,将常用信息以histogram的格式存储在其他root文件(如hist001.root)。这样可以快速查看感兴趣的参数。
    • 直接在Tree结构中查看每个参数的分布是非常耗时的。

常用信息包括:

  • ADC,TDC的每路的原始能谱和时间谱,以及用hit格式存储的同类型探测器的信号分布(见3.2节)。
  • 探测器之间的关联如$\Delta E$-E, TOF-$\Delta E$等信号。

以目录结构存储不同类型的histogram

  • 文件中的histograms可以很方便用TBrowser查看

root -l mg18.root

root[0] new TBrowser
- 在左侧栏中双击文件名,在Draw Option栏中填入“colz”等绘图选项。


将histogram存入不同目录:¶

  • 用TDirectoryFile 创建目录结构
    • 在文件根目录下创建目录:
fout->cd();//fout为文件指针
  TDirectoryFile *dir1= new TDirectoryFile("dir1","dir1");
  TDirectoryFile *dir2= new TDirectoryFile("dir2","dir2");
  • 在目录下创建子目录
dir1->cd();//fout为文件指针
  TDirectoryFile *dir1sub= new TDirectoryFile("dir1sub","dir1sub");
  • 创建目录完成后,分别在各目录下 (包括直接在fout文件中) 声明要存储的对象,并分配内存空间(new)
    • 可以在目录结构中存储的对象不限于TH,TGraph,TTree 等都可以。
TH1I *h0,*h1,*h2,*h1sub;
    fout->cd();    h0=new TH1I();
    dir1->cd();    h1=new TH1I();
    dir2->cd();    h2=new TH1I();
    dir1sub->cd(); h1sub=new TH1I();
  • Fill histograms
h0->Fill();
   ...
  • 在当最后写入文件时,所有对象会自动存储在对应的目录下!
fout->Write();
  • 形成如下目录结构

1

代码示例¶

In [6]:
TFile *fout = new TFile("test1.root","recreate");
In [7]:
fout->cd();
//dir1 and dir2 are the top level directories in the root file
TDirectoryFile *dir1 = new TDirectoryFile("dir1","dir1");
TDirectoryFile *dir2 = new TDirectoryFile("dir2","dir2");

//create a sub-directory under dir1
dir1->cd();
TDirectoryFile *dir1sub = new TDirectoryFile("dir1sub","dir1sub");
In [8]:
//create histograms under each directory
TH1I *h0, *h1, *h2, *h1sub;
fout->cd();
h0 = new TH1I("h0","h0",100,-3,3);

dir1->cd();
h1 = new TH1I("h1","h1",100,-3,3);

dir1sub->cd();
h1sub = new TH1I("h1sub","h1sub",100,-3,3);

dir2->cd();
h2 = new TH1I("h2","h2",100,-3,3);
In [9]:
//fill histograms
h0->FillRandom("gaus",10000);
h1->FillRandom("gaus",10000);
h1sub->FillRandom("gaus",10000);
h2->FillRandom("gaus",10000);
In [10]:
//write to the file
fout->Write();
fout->Close();

Read hist from the file¶

  • root环境直接读取(见上图)
root -l test1.root
>new TBrowser

在左边树形目录结构中找到文件,鼠标点击进入目录结构,点击相应hist

  • 代码读取
In [11]:
TFile *fin=new TFile("test1.root");
In [12]:
fin->ls();
TFile**		test1.root	
 TFile*		test1.root	
  KEY: TDirectoryFile	dir1;1	dir1
  KEY: TDirectoryFile	dir2;1	dir2
  KEY: TH1I	h0;1	h0
In [13]:
TH1I* h0a=(TH1I*) fin->Get("h0");
TH1I* h1a=(TH1I*) fin->Get("dir1/h1");
TH1I* h2a=(TH1I*) fin->Get("dir2/h2");
TH1I* h1suba=(TH1I*) fin->Get("dir1/dir1sub/h1sub");
In [14]:
h1suba->Draw();
c1->Draw();

4. 实验参数一致性检验 ¶

  • 实验过程中由于探测器工作条件的变化(温度,噪声等)以及电子学参数的漂移,实验参数可能会随着时间变化。

  • 在进行刻度和实验条件选取(cut)之前,必须确认参数是否随时间变化,并进行相应的修正。

  • 观察实验参数随时间的变化:

    • 文件内的变化: 参数值随着事件编号(Event Number)或timestamp的变化。
    • 整个实验期间的变化:参数值随着文件编号的变化。

下图显示某次实验中TDC值、位置探测器分辨、效率等参数随着文件号的变化。 3

第二阶段¶

第二阶段 包括实验物理量提取,物理分析等过程。 每个过程都涉及信息的整理和压缩,文件大小逐步减小,在内存中读入的时间越来越快。 2