总结:将新的参数存入root,并且保留原有参量

新root代码

//将下列代码保存到readTree.cc
//在ROOT环境下 .x readTree.cc

//TH1D *hTOF;//如果将hTOF定义写在函数体内 hTOF->Draw()将不会显示
//TH1D *ntof;
void readTree_xi()
{
// 1.打开文件,得到TTree指针
  TFile *ipf=new TFile("tree.root");//打开ROOT文件
  if (ipf->IsZombie()) {
   cout << "Error opening file" << endl;
   exit(-1);
  }
  ipf->cd();
  TTree *tree=(TTree*)ipf->Get("tree");//得到名字为“tree”的TTree指针

//2. 声明tree的Branch变量

  Double_t x;
  Double_t e;
  int pid;
  Double_t tof, ctof;
  Double_t tu, td;
  Double_t qu, qd;

//3. 将变量指向对应Branch的地址
  tree->SetBranchAddress("ctof",&ctof);//将ROOT文件内tree内名为"ctof"的branch的数据的指针指向ctof的变量。
  tree->SetBranchAddress("tof",&tof);  
  tree->SetBranchAddress("pid",&pid);
  tree->SetBranchAddress("tu",&tu);   
  tree->SetBranchAddress("td",&td);
  tree->SetBranchAddress("qu",&qu);   
  tree->SetBranchAddress("qd",&qd);
  tree->SetBranchAddress("e",&e);
  tree->SetBranchAddress("x",&x);



  //Histogram
 // hTOF=new TH1D("hTOF","Time of flight", 1000,0,100);
  // ntof = new TH1D("ntof","ntof",100,0,20);
  //将新数据写入新的ROOT文件 -对应的代码用 ////标出
  //// //calibration parameters
  //// Double_t a,b;
  //// ... ... ...
  //// //new tree parameters
  Double_t tx,qx,ce,ntof;
  //// ... ... ...    
   TFile *opf=new TFile("tree2.root","recreate");
   opf->cd();
   TTree *opt=new TTree("tree","tree");

   //tree中数据指向变量指针
   //继承原有tree.root数据
   opt->Branch("x",&x,"x/D");
   opt->Branch("e",&e,"e/D");
   opt->Branch("tu",&tu,"tu/D");
   opt->Branch("td",&td,"td/D");
   opt->Branch("qu",&qu,"qu/D");
   opt->Branch("qd",&qd,"qd/D");
   opt->Branch("pid",&pid,"pid/D");
   opt->Branch("tof",&tof,"tof/D");
   opt->Branch("ctof",&ctof,"ctof/D");

   //tree中填加新的变量
   opt->Branch("tx",&tx,"tx/D");
   opt->Branch("qx",&qx,"qx/D");
   opt->Branch("ce",&ce,"ce/D");
   opt->Branch("ntof",&ntof,"ntof/D");
  // TH1D *ntof = new TH1D("ntof","ntof",200,0,20);
  //// ... ... ...


  //4. 逐事件读取tree的branch数据
  Long64_t nentries=tree->GetEntries();//得到tree的事件总数
  for(Long64_t jentry=0; jentry<nentries; jentry++) {//对事件进行遍历
    tree->GetEntry(jentry);//将第jentry个事件数据填入对应变量(步骤3.中指向的变量),每次变量值会变成当前事件对应的数据。
    ////hTOF->Fill(ctof);
    //// // calculate new parameters
     tx = 3.742*(td-tu-14.915);
     qx = 190.4*(log(qu/qd)+0.003);
     Double_t d=TMath::Sqrt(502.5*502.5+tx*tx);
     ntof=(ctof-26.2096)/d*100.;
    // Double_t corr_ctof=(ctof-26.2096)/d*100.;
    // ntof->Fill(corr_ctof);
     if(pid == 1)
    {
    //ce = (939.56563*100.*100.)/(2.*30.*30.*corr_ctof*corr_ctof);
    ce = (939.56563*100.*100.)/(2.*30.*30.*ntof*ntof);
    }
    //// ... ... ...

     opt->Fill();//fill new parameter to TTree* opt

    if(jentry%1000==0) cout<<"process "<<jentry<<" of "<<nentries<<endl;
  }

  //hTOF->Draw();
  ipf->Close();
  opt->Write();
  opf->Close();
}

打开新root

In [1]:
%jsroot on
In [2]:
TFile *ipf=new TFile("tree2.root");//打开ROOT文件
  if (ipf->IsZombie()) {
   cout << "Error opening file" << endl;
   exit(-1);
  }
  ipf->cd();
  TTree *tree=(TTree*)ipf->Get("tree");//得到名字为“tree”的TTree指针

比较$t_x$与$x$差值随$x$的变化关系

In [3]:
TCanvas *c1= new TCanvas;
tree->Draw("x:tx-x>>(100,-20,20,500,-120,120)","", "colz");
c1->Draw();

查看$t_x$零点位置

In [4]:
tree->Draw("tx-x>>dtx(100,-20,20)");
dtx->Fit("gaus");
c1->Draw();
 FCN=29.6002 FROM MIGRAD    STATUS=CONVERGED      55 CALLS          56 TOTAL
                     EDM=7.49999e-11    STRATEGY= 1      ERROR MATRIX ACCURATE 
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     7.05708e+03   2.73290e+01   6.02862e-02  -2.56523e-08
   2  Mean        -6.37052e-02   7.15069e-03   1.93143e-05   1.70480e-03
   3  Sigma        2.26060e+00   5.05301e-03   1.64290e-06  -1.91495e-03

比较$Q_x$与$x$差值随$x$的变化关系

In [5]:
tree->Draw("x:qx-x>>(100,-50,50,150,-150,150)","", "colz");
c1->Draw();

查看$Q_x$零点位置

In [6]:
tree->Draw("qx-x>>dqx(100,-50,50)");
dqx->Fit("gaus");
c1->Draw();
 FCN=106.157 FROM MIGRAD    STATUS=CONVERGED      61 CALLS          62 TOTAL
                     EDM=6.60089e-13    STRATEGY= 1      ERROR MATRIX ACCURATE 
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     3.47028e+03   1.34241e+01   5.54977e-02  -8.41926e-08
   2  Mean         5.62783e-01   3.63659e-02   1.83729e-04   3.27700e-06
   3  Sigma        1.14843e+01   2.55769e-02   3.06334e-06  -1.78863e-03
  • $t_x$与$q_x$比较发现,$t_x$刻度效果更好,主要体现:
    • 微分法寻找边界位置时,$t_x$更窄更准确;
    • 两者与$x$的差值,$t_x$弥散更小;
    • 虽然二者都可以通过调节拟合范围、分bin等方法使得线性以及零点更准,但二者综合来开,$t_x$零点更精确;

利用$\gamma$对ctof绝对刻度,并将飞行距离归一到100 cm得到$ntof$,查看ntof与$t_x$关联

In [7]:
tree->Draw("ntof:tx>>(240,-120,120,75,2.5,4)","pid==0","colz");
c1->Draw();

ntof与模拟所得的tof(同样归一到100 cm)对比

In [8]:
tree->Draw("ntof>>hntof(200,0, 20)");
tree->Draw("tof*100./TMath::Sqrt(502.5*502.5+tx*tx)>>htof(200,0,20)");
hntof->Draw();
htof->SetLineColor(2);
htof->Draw("same");
c1->SetLogy();
c1->Draw();
  • ntof的$\gamma$飞行时间比tof所得的峰位更宽,原因是,计算ctof时加入了探测器的时间分辨;

由得到的ntof计算中子能量$ce$

In [9]:
tree->Draw("ce>>hce(500,10, 200)");
hce->Fit("gaus");
c1->SetLogy(0);
c1->Draw();
 FCN=361.017 FROM MIGRAD    STATUS=CONVERGED      58 CALLS          59 TOTAL
                     EDM=1.37274e-07    STRATEGY= 1      ERROR MATRIX ACCURATE 
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     4.98203e+02   2.31529e+00   1.75373e-02   1.18802e-04
   2  Mean         1.00458e+02   8.05189e-02   7.48010e-04  -5.82688e-03
   3  Sigma        2.12028e+01   5.72996e-02   6.79754e-06   2.54976e-01
  • 模拟输入量:$E_n = 100 MeV$,$FWHM = 50 MeV$;
  • 数据处理结果:$E_{mean}=100.41 MeV$,$sigma = 21.1484 , FWHM = 2.355* sigma= 49.80 MeV$,与模拟结果基本对应。
In [10]:
ipf->Close();//关闭root文件
In [12]:
!jupyter nbconvert homework1.1-sum --to html
[NbConvertApp] Converting notebook homework1.1-sum.ipynb to html


[NbConvertApp] Writing 473451 bytes to homework1.1-sum.html


In [ ]: