homework2.1-代码

  • PPAC的信号处理:
    • 粗略挑出有效信号;
    • 去除pileup成分;
    • 实现径迹重构(PPAC选择策略);
    • 编译生成可执行文件,批量处理数据;

文件和目录的组织

主目录: ./tracking

  ./tracking 
      - main.cpp  - 主程序
      - Makefile -编译方法

  ./tracking/include/  
      - tracking.h   - MakeClass 生成的头文件
      - ana.h         - 用户分析头文件

  ./tracking/src/ 
      - tracking.C  -MakeClass生成的源文件
      - ana.cpp       用户分析源文件

ana.h文件

#ifndef ana_h
#define ana_h
//ROOT
#include <TH2.h>
//C++
#include <iostream>
//user
#include <tracking.h>  //由MakeClass生成,为了继承该函数

using namespace std;

class ana:public tracking   //从tracking.h中tracking的类中继承其成员变量和成员函数
{
public:
    Int_t run; //run numbe
    Int_t NumX;
    Int_t NumY;
    Int_t WhichX[5];
    Int_t WhichY[5];
    //Declaration by user
    Double_t xx[5],xz[5],yy[5],yz[5];//0-1A,1-1B,2-2A,3-2B,4-3.
    Double_t xxfit[5],yyfit[5];//3 x,y, 0-measured, 1- fitted.
    Double_t anode[5];//0-1A,1-1B,2-2A,3-2B,4-3
    Double_t dx[5],dy[5];//0-1A,1-1B,2-2A,3-2B,4-3
    Double_t tx,ty,tz;//target position
    Double_t kx,bx,ky,by;
    Double_t c2nx,c2ny;//chi2/ndf for xfit,yfit
    //构造函数:将传入的tree传递给tracking基类,完成初始化
    ana(Int_t run_number, TTree * tree):tracking(tree),run(run_number){}; //run = run_number
    virtual ~ana() {};
    virtual void     SetBranch(TTree *tree);
    virtual void     TrackInit();
    virtual void     SetTrace(TH2D *h,Double_t k,Double_t b,Int_t min,Int_t max);
    virtual void     Analysis(TTree *tree);//分析函数,作用等价于原Loop函数
    //Int_t NumX, NumY;//有效探测器数量:0-5
    //Int_t WhichX[NumX], WhichY[NumY];//有效探测器是谁(0-1A,1-1B,2-2A,3-2B,4-3)
};
#endif

ana.C文件

#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TFitResult.h>
#include <TGraph.h>
#include "ana.h"
using namespace std;

void ana::SetBranch(TTree *tree)
{
     //measured pos
     tree->Branch("xx",&xx,"xx[5]/D");//1A,1B,2A,2B,3->0,1,2,3,4,5
     tree->Branch("xz",&xz,"xz[5]/D");//1A,1B,2A,2B,3->0,1,2,3,4,5
     tree->Branch("yy",&yy,"yy[5]/D");//1A,1B,2A,2B,3->0,1,2,3,4,5
     tree->Branch("yz",&yz,"yz[5]/D");//1A,1B,2A,2B,3->0,1,2,3,4,5

     //xx,yy get by fitted for calulating the efficiency of PPAC
     //efficiency = the constants of detectted/that fitted
     tree->Branch("xxfit",&xxfit,"xxfit[5]/D");
     tree->Branch("yyfit",&yyfit,"yyfit[5]/D");

     //anode,coincident with xx and yy, respectively, for trigger events;
     tree->Branch("anode",&anode,"anode[5]/D");  

     //由触发的PPAC个数,以及具体哪个PPAC
     tree->Branch("NumX",&NumX,"NumX/I");
     tree->Branch("NumY",&NumY,"NumY/I"); 
     tree->Branch("WhichX",&WhichX,"WhichX[NumX]/I");
     tree->Branch("WhichY",&WhichY,"WhichY[NumY]/I"); 

     //difference between measured and calculated -for pos resolution.
     //dx = xx - xxfit
     tree->Branch("dx",&dx,"dx[5]/D");
     tree->Branch("dy",&dy,"dy[5]/D");

     //target x-y from fitted line at z=0;
     tree->Branch("tx",&tx,"tx/D");
     tree->Branch("ty",&ty,"ty/D");
     tree->Branch("tz",&tz,"tz/D");

     //ch2/ndf for linear fitting.
     tree->Branch("c2nx",&c2nx,"c2nx/D");
     tree->Branch("c2ny",&c2ny,"c2ny/D");

     //两种实验获取的触发
     tree->Branch("beamTrig",&beamTrig,"beamTrig/I");
     tree->Branch("must2Trig",&must2Trig,"must2Trig/I");

     //原始文件中的
     tree->Branch("targetX",&targetX,"targetX");
     tree->Branch("targetY",&targetY,"targetY"); 
}

void ana::TrackInit()
{
    for(Int_t i=0;i<5;i++)
    {
          xx[i]=PPACF8[i][0];
          yy[i]=PPACF8[i][1];
          xz[i]=PPACF8[i][2];
          yz[i]=PPACF8[i][3];
          anode[i]=PPACF8[i][4];

          xxfit[i]= -999;
          yyfit[i]= -999;

          dx[i] = -999;
          dy[i] = -999;
          WhichX[i] = -1;
          WhichY[i] = -1;
    }

    tx=-999;
    ty=-999;
    tz=-999;
    kx=1.0;
    bx=0.0;
    ky=1.0;
    by=0.0;

    //PPAC-x挑出有效(X and anode)PPAC个数以及哪个PPAC
    //0->1A,1->1B,2->2A,3->2B,4->3
    NumX = 0;
    for (Int_t i=0;i<5;i++)
    {
      if (abs(xx[i])<100.&&anode[i]>-999)
    {
    WhichX[NumX] = i;
        NumX = NumX + 1;
    }
    }
    //排除NumX == 2时,均在PPAC1或均在PPAC2的情况
    if(NumX==2 && (WhichX[0]==1 && WhichX[1]==2)) NumX = -2;
    if(NumX==2 && (WhichX[0]==3 && WhichX[1]==4)) NumX = -2;

    //PPAC-Y挑出有效(Y and anode)PPAC个数以及哪个PPAC
    //0->1A,1->1B,2->2A,3->2B,4->3
    NumY = 0;
    for (Int_t i=0;i<5;i++)
    {
      if (abs(yy[i])<100.&&anode[i]>-999)
    {
    WhichY[NumY] = i;
        NumY = NumY + 1;
    }
    }
    //排除NumY == 2时,均在PPAC1或均在PPAC2的情况
    if(NumY==2 && (WhichY[0]==1 && WhichY[1]==2)) NumY = -2;
    if(NumY==2 && (WhichY[0]==3 && WhichY[1]==4)) NumY = -2;
}

void ana::SetTrace(TH2D *h,Double_t k,Double_t b,Int_t min,Int_t max)
{
  if(h==0) return;
  if(min>=max) return;

  for(int i=min;i<max;i++)
  {
    h->Fill(i,(Int_t)(i*k+b));
  }
}

void ana::Analysis(TTree *tree)
{
   TH2D *htf8xz=new TH2D("htf8xz","xz trace by ppac",2200,-2000,200,300,-150,150);
   TH2D* htf8yz=new TH2D("htf8yz","yz trace by ppac",2200,-2000,200,300,-150,150);

   SetBranch(tree);

   if (fChain == 0) return;
   Long64_t nentries = fChain->GetEntriesFast();
   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      nb = fChain->GetEntry(jentry);   nbytes += nb;

      TrackInit();

      //PPAC-X多于两个PPAC触发
      if(NumX > 1)
      {
        //fit x-z trajectory
        TFitResultPtr r;
    auto * grx = new TGraph;
    //传件拟合图像,与NumX有关
        for(Int_t i = 0;i<NumX;i++)
    {
          grx->SetPoint(i,xz[WhichX[i]],xx[WhichX[i]]);
    }
    //创建一次项拟合函数
        TF1 *fx=new TF1("fx","pol1",-2000,0);
        //fit option: Q: Quiet mode (minimum printing); 
        //            S: The result of the fit is returned in the TFitResultPtr .
        //拟合grx并将结果传递给r
    r=grx->Fit(fx,"SQ");
    //由拟合曲线得到5个PPAC的拟合位置
    //曲线确定,有xz即有xxfit值,故与NumX无关
        for(Int_t i = 0;i<5;i++)
    {
          xxfit[i]=fx->Eval(xz[i]);
    }
    //由拟合曲线推出零点,即靶的位置
        kx = fx->GetParameter(1);
    bx = fx->GetParameter(0);
    tx = bx/(1+kx);
    tz = -tx;
    //画径迹图
        SetTrace(htf8xz,kx,bx,-1800,0);
        //得到有效事件实验值与拟合值的差,与NumX有关,有触发的PPAC赋予新值,无触发的PPAC为初始值-999
    for(int i=0;i<NumX;i++) 
    {
      dx[WhichX[i]]=xx[WhichX[i]]-fx->Eval(xz[WhichX[i]]);
        }
    c2nx=r->Chi2()/r->Ndf();//对于任何程序的自动拟合,原则上都要输出拟合误差进行评估
        delete grx;
        delete fx;
      }

      //PPAC-X多于两个PPAC触发
      if(NumY > 1)
      {
        //fit y-z trajectory
        TFitResultPtr r;
    auto * gry = new TGraph;
    //传件拟合图像,与NumY有关
        for(Int_t i = 0;i<NumY;i++)
    {
          gry->SetPoint(i,yz[WhichY[i]],yy[WhichY[i]]);
    }
    //创建一次项拟合函数
        TF1 *fy=new TF1("fy","pol1",-2000,0);
        //fit option: Q: Quiet mode (minimum printing); 
        //            S: The result of the fit is returned in the TFitResultPtr .
        //拟合grx并将结果传递给r
    r=gry->Fit(fy,"SQ");
    //由拟合曲线得到5个PPAC的拟合位置
    //曲线确定,有xz即有xxfit值,故与NumX无关
        for(Int_t i = 0;i<5;i++)
    {
          yyfit[i]=fy->Eval(yz[i]);
    }
    //由拟合曲线推出零点,即靶的位置
        ky = fy->GetParameter(1);
    by = fy->GetParameter(0);
    ty = ky * tz + by;
    //画径迹图
        SetTrace(htf8yz,ky,by,-1800,0);
        //得到有效事件实验值与拟合值的差,与NumY有关,有触发的PPAC赋予新值,无触发的PPAC为初始值-999
    for(int i=0;i<NumY;i++) 
    {
      dy[WhichY[i]]=yy[WhichY[i]]-fy->Eval(yz[WhichY[i]]);
        }
    c2ny=r->Chi2()/r->Ndf();//对于任何程序的自动拟合,原则上都要输出拟合误差进行评估
        delete gry;
        delete fy;
      }

      tree->Fill();
      if(jentry%10000==0) cout<<"processing "<<jentry<<endl;

   }
   htf8xz->Write();
   htf8yz->Write();
   tree->Write();
}

Main.cpp文件

#include <iostream>
#include <sstream>
#include <TFile.h>
#include <TTree.h>
#include <TString.h>
#include "ana.h"
using namespace std;

int main(int argc, char** argv)
{
   if(argc !=2) {
       cout<<"Usage: ./"<<argv[0]<<" run_number "<<endl;
       return -1;
   }
   int run_number = atoi(argv[1]);
   TString InputPath, OutputPath, infile, outfile;  
    InputPath = "../";
    OutputPath = "./";
    infile.Form("%sf8ppac%03d.root", InputPath.Data(), run_number);
    //outfile.Form("%shomework%03d.root", OutputPath.Data(), run_number);
    outfile.Form("%shomework2.1.root", OutputPath.Data());
    //input
    TFile *ipf = new TFile(infile);
    if(!ipf->IsOpen()) {
        cout<<"Cannot open input file: "<<infile<<endl;
        return -1;
    }
    TTree *ipt = (TTree*)ipf->Get("tree");

    //output
    TFile *opf = new TFile(outfile,"RECREATE");
    TTree *opt = new TTree("tree","ppac tracking");

    //注意与method1中main.cpp文件的不同哦!!!
    ana *tk=new ana(run_number,ipt);//自己新编写的分析类函数,此处不再是tracking类;
    tk->Analysis(opt);//自己编写的分析函数,等价MakeClass生产.C文件的Loop函数;

    //
    ipf->Close();
    opf->Close();
    return 1;        
}
In [1]:
!jupyter nbconvert homework2.1_Code --to html
[NbConvertApp] Converting notebook homework2.1_Code.ipynb to html


[NbConvertApp] Writing 339841 bytes to homework2.1_Code.html