主目录: ./tracking
./tracking
- main.cpp - 主程序
- Makefile -编译方法
./tracking/include/
- tracking.h (*.h, *.hh) - 头文件
./tracking/src/
- tracking.C(*.cc, *.cpp) -源文件
#include <iostream>
#include <TFile.h>
#include <TTree.h>
#include <TString.h>
#include "tracking.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("%sout%03d.root", OutputPath.Data(), run_number);
//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");
//
tracking *tk=new tracking(ipt);//当traking构造函数中传入的ipt已存在时,构造函数内部的tree指针就指向ipt
tk->Loop(opt);
//
ipf->Close();
opf->Close();
return 1;
}
修改tracking.h
按照上述原则应将原tracking.h目录下的成员函数的具体实现部分挪至src/tracking.cpp文件内,但tracking.h中部分成员函数的实现是MakeClass自动生成的,$\color{red}{为了尽量少修改自动生成的代码,不改动原traking.h的代码}$。
//////////////////////////////////////////////////////////
// This class has been automatically generated on
// Wed Mar 11 09:58:39 2020 by ROOT version 6.18/04
// from TTree tree/tree
// found on file: f8ppac001.root
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// This class has been automatically generated on
// Wed Mar 11 09:58:39 2020 by ROOT version 6.18/04
// from TTree tree/tree
// found on file: f8ppac001.root
//////////////////////////////////////////////////////////
#ifndef tracking_h
#define tracking_h
#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include <TH2.h>
// Header file for the classes stored in the TTree if any.
class tracking {
public :
TTree *fChain; //!pointer to the analyzed TTree or TChain
Int_t fCurrent; //!current Tree number in a TChain
// Fixed size dimensions of array or collections stored in the TTree if any.
// Declaration of leaf types
Float_t PPACF8[5][5];
Float_t F8PPACRawData[5][5];
Int_t beamTrig;
Int_t must2Trig;
Float_t targetX,targetY;
//by user
Double_t xx[3],xz[3],yy[3],yz[3];//1A,2A,3
Double_t xx2b[2],yy2b[2],xz2b,yz2b;//2B x,y, 0-measured, 1- fitted.
Double_t dx[3],dy[3];//residual
Double_t tx,ty;//target position
Double_t c2nx,c2ny;//chi2/ndf for xfit,yfit
// List of branches
TBranch *b_PPACF8; //!
TBranch *b_F8PPACRawData; //!
TBranch *b_beamTrig; //!
TBranch *b_must2Trig; //!
TBranch *b_targetX; //!
TBranch *b_targetY; //!
tracking(TTree *tree=0);
virtual ~tracking();
virtual Int_t Cut(Long64_t entry);
virtual Int_t GetEntry(Long64_t entry);
virtual Long64_t LoadTree(Long64_t entry);
virtual void Init(TTree *tree);
virtual void Loop(TTree *tree);
virtual void SetOutBranch(TTree *tree);//by user
virtual void TrackInit();//by user
virtual void SetTrace(TH2D *h,Double_t k,Double_t b,Int_t min,Int_t max);
virtual Bool_t Notify();
virtual void Show(Long64_t entry = -1);
};
#endif
#ifdef tracking_cxx
tracking::tracking(TTree *tree) : fChain(0)
{
// if parameter tree is not specified (or zero), connect the file
// used to generate this class and read the Tree.
if (tree == 0) {
TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("f8ppac001.root");
if (!f || !f->IsOpen()) {
f = new TFile("f8ppac001.root");
}
f->GetObject("tree",tree);
}
Init(tree);
}
tracking::~tracking()
{
if (!fChain) return;
delete fChain->GetCurrentFile();
}
Int_t tracking::GetEntry(Long64_t entry)
{
// Read contents of entry.
if (!fChain) return 0;
return fChain->GetEntry(entry);
}
Long64_t tracking::LoadTree(Long64_t entry)
{
// Set the environment to read one entry
if (!fChain) return -5;
Long64_t centry = fChain->LoadTree(entry);
if (centry < 0) return centry;
if (fChain->GetTreeNumber() != fCurrent) {
fCurrent = fChain->GetTreeNumber();
Notify();
}
return centry;
}
void tracking::Init(TTree *tree)
{
// The Init() function is called when the selector needs to initialize
// a new tree or chain. Typically here the branch addresses and branch
// pointers of the tree will be set.
// It is normally not necessary to make changes to the generated
// code, but the routine can be extended by the user if needed.
// Init() will be called many times when running on PROOF
// (once per file to be processed).
// Set branch addresses and branch pointers
if (!tree) return;
fChain = tree;
fCurrent = -1;
fChain->SetMakeClass(1);
fChain->SetBranchAddress("PPACF8", PPACF8, &b_PPACF8);
fChain->SetBranchAddress("F8PPACRawData", F8PPACRawData, &b_F8PPACRawData);
fChain->SetBranchAddress("beamTrig", &beamTrig, &b_beamTrig);
fChain->SetBranchAddress("must2Trig", &must2Trig, &b_must2Trig);
fChain->SetBranchAddress("targetX",&targetX,&b_targetX);
fChain->SetBranchAddress("targetY",&targetY,&b_targetY);
Notify();
}
Bool_t tracking::Notify()
{
// The Notify() function is called when a new file is opened. This
// can be either for a new TTree in a TChain or when when a new TTree
// is started when using PROOF. It is normally not necessary to make changes
// to the generated code, but the routine can be extended by the
// user if needed. The return value is currently not used.
return kTRUE;
}
void tracking::Show(Long64_t entry)
{
// Print contents of entry.
// If entry is not specified, print current entry
if (!fChain) return;
fChain->Show(entry);
}
Int_t tracking::Cut(Long64_t entry)
{
// This function may be called from Loop.
// returns 1 if entry is accepted.
// returns -1 otherwise.
return 1;
}
#endif // #ifdef tracking_cxx
修改tracking.C目录
#define tracking_cxx
#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TFitResult.h>
#include <TGraph.h>
#include "tracking.h"
using namespace std;
void tracking::SetBranch(TTree *tree)
{
//measured pos
tree->Branch("xx",&xx,"xx[3]/D");//1A,2A,3
tree->Branch("xz",&xz,"xz[3]/D");
tree->Branch("yy",&yy,"yy[3]/D");
tree->Branch("yz",&yz,"yz[3]/D");
//difference between measured and calculated -for pos resolution.
tree->Branch("dx",&dx,"dx[3]/D");
tree->Branch("dy",&dy,"dy[3]/D");
//for efficiency calculation -2B
tree->Branch("p2bx",&p2bx,"p2bx/D");
tree->Branch("p2by",&p2by,"p2by/D");
//target x-y
tree->Branch("tx",&tx,"tx/D");
tree->Branch("ty",&ty,"ty/D");
//ch2/ndf for linear fitting.
tree->Branch("c2nx",&c2nx,"c2nx/D");
tree->Branch("c2ny",&c2ny,"c2ny/D");
}
void tracking::TrackInit()
{
tx=-999;
ty=-999;
//1A
xx[0]=PPACF8[0][0];
yy[0]=PPACF8[0][1];
xz[0]=PPACF8[0][2];
yz[0]=PPACF8[0][3];
//2A
xx[1]=PPACF8[2][0];
yy[1]=PPACF8[2][1];
xz[1]=PPACF8[2][2];
yz[1]=PPACF8[2][3];
//3
xx[2]=PPACF8[4][0];
yy[2]=PPACF8[4][1];
xz[2]=PPACF8[4][2];
yz[2]=PPACF8[4][3];
//2B
p2bx=PPACF8[3][0];
p2by=PPACF8[3][1];
}
void tracking::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 tracking::Loop(TTree *tree)
{
TH2D *htf8x=new TH2D("htf8x","x trace by ppac",2200,-2000,200,300,-150,150);
TH2D *htf8y=new TH2D("htf8y","y trace by ppac",2200,-2000,200,300,-150,150);
TH2D *htar=new TH2D("htar","distribution on target",100,-50,50,100,-50,50);
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();
bool b1a=xx[0]>-999 && yy[0]>-999;
bool b2a=xx[1]>-999 && yy[1]>-999;
bool b3=xx[2]>-999 && yy[2]>-999;
if(!b1a || !b2a || !b3) continue;
//fit x-z trajectory
TFitResultPtr r;
TGraph *grx=new TGraph(3,xz,xx);
TF1 *fx=new TF1("fx","pol1",-2000,0);
r=grx->Fit(fx,"SQ");
tx=fx->Eval(0);
SetTrace(htf8x,fx->GetParameter(1),fx->GetParameter(0),-1800,0);
for(int i=0;i<3;i++) dx[i]=xx[i]-fx->Eval(xz[i]);
c2nx=r->Chi2()/r->Ndf();
delete grx;
delete fx;
//fit y-z trajectory
TGraph *gry=new TGraph(3,yz,yy);
TF1 *fy=new TF1("fy","pol1",-2000,0);
r=gry->Fit(fy,"SQ");
ty=fy->Eval(0);
SetTrace(htf8y,fy->GetParameter(1),fy->GetParameter(0),-1800,0);
for(int i=0;i<3;i++) dy[i]=yy[i]-fy->Eval(yz[i]);
c2ny=r->Chi2()/r->Ndf();
delete gry;
delete fy;
htar->Fill(tx,ty);
tree->Fill();
if(jentry%10000==0) cout<<"processing "<<jentry<<endl;
}
htf8x->Write();
htf8y->Write();
htar->Write();
tree->Write();
}
参考链接:跟我一起写Makefile:https://blog.csdn.net/xiaoshuai537/article/details/79340153
下面的Makefile中ROOTCFLAGS,ROOTLIBS,ROOTGLIBS是编译和链接ROOT环境的必要语句。
OBJ = 程序编译后的名称
#############################################################################
OBJ = tracking
MainFile = main.cpp
###############################################################################
SourceFile := $(wildcard $(shell pwd)/src/*.c $(shell pwd)/src/*.cc $(shell pwd)/src/*.C $(shell pwd)/src/*.cpp $(shell pwd)/src/*.cxx)
IncludeFile := $(wildcard $(shell pwd)/include/*.h $(shell pwd)/include/*.hh $(shell pwd)/include/*.hpp)
###############################################################################
ROOTCFLAGS = $(shell root-config --cflags)
ROOTLIBS = $(shell root-config --libs)
ROOTGLIBS = $(shell root-config --glibs)
GXX = g++
# -Wl ,--no-as-needed
DIR_INC = -I$(ROOTSYS)/include -I$(shell pwd)/include
CFLAGS = -Wall -O2 $(DIR_INC) -I$(ROOTSYS)/include $(ROOTLIBS) -lSpectrum -lXMLParser -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
###############################################################################
all:$(OBJ)
$(OBJ): $(MainFile) $(SourceFile)
$(GXX) $(CFLAGS) $(ROOTCFLAGS) $(ROOTLIBS) $(ROOTGLIBS) -o $@ $(MainFile) $(SourceFile)
@echo "=============================================================="
@echo "$@ done !"
@echo "=============================================================="
clean:
rm -f *.o *.d $(OBJ)
make clean
make
出现的主要错误:
#include <TGraph.h>
#include <iostream>
#include <TGraph.h>
#include "mylib.h"
!jupyter nbconvert exercise2.3 --to html