数据:s4.root
Int_t pe[48];//Pie 0-47
Int_t re[48];//Ring 0-47
基本步骤
%jsroot on
TFile *f=new TFile("../s4.root");
TTree *tree=(TTree*)f->Get("tree");
TCanvas *c1=new TCanvas;
tree->Draw("pe[0]>>hx0(1000,0,2000)");//单条
tree->Draw("pe[1]>>hx1(1000,0,2000)");//单条
TH1I *hx0=(TH1I*)gROOT->FindObject("hx0");
TH1I *hx1=(TH1I*)gROOT->FindObject("hx1");
hx0->SetLineColor(kGreen);
hx1->Draw();
hx0->Draw("same");
c1->Draw();
tree->Draw("pe>>(1000,0,2000)");//所有条pe[0-47]
c1->Draw();
tree->Draw("re[0]>>hy0(1000,0,2000)");//单条
tree->Draw("re[1]>>hy1(1000,0,2000)");//单条
TH1I *hy0=(TH1I*)gROOT->FindObject("hy0");
TH1I *hy1=(TH1I*)gROOT->FindObject("hy1");
//gPad->SetLogy();
hy0->SetLineColor(kGreen);
hy1->Draw();
hy0->Draw("same");
c1->Draw();
TH1F *h=NULL,*hb=NULL;
Int_t nfound;
Double_t *xpeaks=NULL, *ypeaks=NULL;
TSpectrum *s=NULL;
void peaks(TString hname, vector<Double_t> &pe, Double_t thres=0.05,int backsub=0)
{
pe.clear();//清空pe
multimap<Int_t,Double_t> me;//用于排序
h=(TH1F*)gROOT->FindObject(hname);
if(!s) s=new TSpectrum(500);
if(backsub)
{
hb=(TH1F*)s->Background(h,80,"same");//80-本底光滑程度
h->Add(h,hb,1,-1);
}
nfound=s->Search(h,2,"",thres);
TList *functions = h->GetListOfFunctions();//added by xi
TPolyMarker *pm=(TPolyMarker *)h->GetListOfFunctions()->FindObject("TPolyMarker");
pm->SetMarkerStyle(32);
pm->SetMarkerColor(kGreen);
pm->SetMarkerSize(0.4);
xpeaks=s->GetPositionX();
ypeaks=s->GetPositionY();
TString sout;
for(int j=0;j<nfound;j++)
{
stringstream ss;
ss<<xpeaks[j];
TString s1=ss.str();
TLatex *tex=new TLatex(xpeaks[j],ypeaks[j],s1);
//sout.Form("%2d. %4d %d",j,xpeaks[j],ypeaks[j]);
//cout<<sout.Data()<<endl;
me.insert(make_pair(int(ypeaks[j]),xpeaks[j]));
tex->SetTextFont(13);
tex->SetTextSize(14);
tex->SetTextAlign(12);
tex->SetTextAngle(90);
tex->SetTextColor(kRed);
tex->Draw();
}
for(auto ie=me.rbegin(); ie!=me.rend(); ie++)
{
cout<<ie->second<<" "<<ie->first<<endl;//peak,count;
pe.push_back(ie->second);//按照计数由大到小填入
}
me.clear();
}
注意调用前,相关参量的声明
gROOT->ProcessLine(".L ./peaks.C");//可以在代码内部直接使用,等价于.L peaks.C
vector<Double_t> pe;
Double_t e[4]={5.5658,6.1748, 6.6708, 8.6931};//alpha energy
peaks("hx1",pe);
gPad->SetLogy(0);
c1->Draw();
PS:peaks中的map是按照统计排序的,并按照统计由多到少,将对应的xch填入向量pe中
更一般的策略为,将TSpectrum寻到的峰位与刻度能量进行随机组合,对比拟合后的chi2/ndf值
sort(pe.begin(),pe.begin()+6); //pe按照统计由高到底,存入了对应统计的峰位(能量),sort:按照能量排序
Double_t mpe[4],cpe[4];//peak,count
for(int i=0;i<4;i++) {
mpe[i]=pe[2+i]; //取能量最高的四个峰
cpe[i]=hx1->GetBinContent(hx1->FindBin(mpe[i]));
cout<<mpe[i]<<" "<<cpe[i]<<endl;
}
TGraph *gr=new TGraph(4,mpe,e);
gr->Draw("A*");
gr->Fit("pol1");
TF1 *f1=gr->GetFunction("pol1");
c1->Draw();
Double_t p0=f1->GetParameter(0);
Double_t p1=f1->GetParameter(1);
Double_t dpe[4];
for(int i=0;i<4;i++) dpe[i]=p0+p1*mpe[i]-e[i];
TGraph *rgr=new TGraph(4,mpe,dpe);
rgr->Draw("AL*");
c1->Draw();
hx1->Draw();
c1->Draw();
利用peak得到的峰位(mean)与计数(Conunts)作为拟合的初始参量
double par[4][3];//peak,sigma,chi2/ndf
double ge[4];
TF1 *fg[4];
TFitResultPtr fr;
for(int i=0;i<4;i++) {
fg[i]=new TF1(Form("fg%d",i),"gaus");
fg[i]->SetParameters(cpe[i],mpe[i],4);//constant,mean, sigma,将寻峰的结果作为第二次拟合的初始参量;
fr=hx1->Fit(fg[i],"SQ+","",mpe[i]-5,mpe[i]+8);//superimpose TF1 to hx1,区间不对称拟合,低能少,高能多
par[i][0]=fg[i]->GetParameter(1);
par[i][1]=fg[i]->GetParameter(2);
par[i][2]=fr->Chi2()/fr->Ndf();
ge[i]=par[i][0];//得到新的峰位拟合结果
cout<<Form("peaks=%4.f, sigma=%.2f, chi2/ndf=%.2f",par[i][0],par[i][1],par[i][2])<<endl;
}
c1->Draw();
拟合、刻度
TGraph *gr1=new TGraph(4,ge,e);
gr1->Draw("A*");
gr1->Fit("pol1");
TF1 *f2=gr->GetFunction("pol1");
c1->Draw();
查看偏差
p0=f2->GetParameter(0);
p1=f1->GetParameter(1);
for(int i=0;i<4;i++) dpe[i]=p0+p1*ge[i]-e[i];
TGraph *rgr1=new TGraph(4,ge,dpe);
rgr1->Draw("AL*");
c1->Draw();
tree->Draw(Form("pe[0]*%f+%f>>hx1e(1000,-1,10)",p1,p0));//单条
hx1e->Draw();
c1->Draw();//存在锯齿,需要在刻度前加入dithering。
!jupyter nbconvert example3_1.ipynb --to html