ROOT-数据读取-直方图-Roofit拟合基本流程-(入门实用)

文|梁佐佐

笔者最近在测核素能谱,测出的能谱需要分析,比如计算某全能峰的分辨率。用到的数据处理分析工具是ROOT(cern),整个能谱读取分析的流程可给各位看官当入门或干货材料使用。不过,ROOT大神就必看本文了,至少节约2分钟的时间,日后要是有新鲜的ROOT技巧会另作分享。

本文ROOT分析的实验背景和数据处理目的如下图1所示:


图1 实验背景和ROOT数据处理的目的

目的1:得到扣除本底后的能谱并绘制出图

基本过程为:1)*.Spe文件数据读取;2)定义一个ROOT文件用于存储能谱;3)数据读取到直方图,并作本底扣除;4)写入ROOT文件;5)画图。

#include "RooRealVar.h"

#include "RooDataSet.h"

#include "RooGaussian.h"

#include "RooBreitWigner.h"

#include "RooPolynomial.h"

#include "RooAddPdf.h"

#include "RooFitResult.h"

#include "RooRealIntegral.h"

#include "TCanvas.h"

#include "RooPlot.h"

#include "TFile.h"

#include "TTree.h"

#include "TH2D.h"

#include "TH1D.h"

#include "THStack.h"

#include "TROOT.h"

#include "TLatex.h" 

#include "TF2.h"

#include "TF1.h"  

#include "iostream"

#include "fstream"

#include "RooCBShape.h"

#include "TMath.h" 

#include "RooFit.h"

#include "RooMath.h" 

using namespace RooFit; 

using namespace std;

void templateread(){ 

const int varnum=2;       

const char *newlabelname[varnum]={"CsI-B","CsI-Cs137"};

string filename[varnum]={"20190401-csi-bg-1725s.Spe","cs137-csi-1725s.Spe"};

double measuringtime[varnum]={1725,1725};  

const int channelnum=24+2048; 

string tempdata; 

ifstream fin[varnum]; 

TH1F *spec[varnum];     


int font=22;

TFile *outputFile=new

TFile("CsI-1cm1cm1cm-new.root","RECREATE");

for (int i1=0;i1<2;i1++)

{ fin[i1].open(filename[i1],ios_base::in); 

spec[i1] = new TH1F(newlabelname[i1],newlabelname[i1],2048,0,2048); 

for (int i=0;i<channelnum;i++)

 {     

 fin[i1]>>tempdata; 

 if(i>24)


 { 

spec[i1]->SetBinContent(i-24,stod(tempdata)); 

 }  


}     


spec[i1]->SetFillColor(kRed);

spec[i1]->SetYTitle("Counts");

spec[i1]->SetXTitle("Channel");

spec[i1]->SetLineColor(kRed);

spec[i1]->SetLabelSize(0.04,"X");

spec[i1]->SetLabelSize(0.04,"Y");

spec[i1]->SetLabelFont(font,"X");

spec[i1]->SetLabelFont(font,"Y");

spec[i1]->SetLabelOffset(0.01,"X");

spec[i1]->SetLabelOffset(0.01,"Y");

spec[i1]->SetTitleOffset(1.0,"X");

spec[i1]->SetTitleOffset(1.2,"Y"); 

spec[i1]->SetTitleOffset(1.2,"Z");

spec[i1]->SetTitleSize(0.05,"X");   

spec[i1]->SetTitleSize(0.05,"Y");

spec[i1]->SetTitleSize(0.05,"Z");

spec[i1]->SetTitleFont(font,"X");

spec[i1]->SetTitleFont(font,"Y");

spec[i1]->SetTitleFont(font,"Z");                



gStyle->SetOptStat(""); 


spec[1]->Add(spec[0],-(measuringtime[1]/measuringtime[0]));

for (int j=0;j<2;j++)

for (int i=0;i<2048;i++)

 {     


   if(spec[j]->GetBinContent(i+1)<0) {spec[j]->SetBinContent(i+1,0); }

    

}  

for (int i=0;i<20;i++)

{

spec[1]->SetBinContent(i+1,0);

}

outputFile->Write();

//spec[0]->Write();

//spec[1]->Write();

//outputFile->Close();

TCanvas*myc=new

TCanvas("myc","myc",650,450);

myc->SetLeftMargin(0.12);    

myc->SetRightMargin(0.08);

myc->SetTopMargin(0.08);

myc->SetBottomMargin(0.12);          

spec[1]->Draw();

//myc->Print(Form("CsI-NoBackground-sec1725.png"));    


图2 绘制能谱

目的2:对能谱全能峰进行拟合

基本过程为:1)已经保存的ROOT文件中读取直方图;2)定义拟合函数的参数区间;3)选择感兴趣的几个函数用于全能峰拟合;4)绘制拟合结果。


#include "RooRealVar.h"

#include "RooDataSet.h"

#include "RooGaussian.h"

#include "TCanvas.h"

#include "RooPlot.h"

#include "TAxis.h"

//#include <stdlib.h>

using namespace RooFit ;

using namespace std ;


void goodfit()

{

//TFile f1("20190501bgona22.root");

//TH1D* hist =(TH1D*)f1.Get("BGO-Na22");

TFile* inputFile = TFile::Open("20190501bgona22.root");

//TFile* inputFile = TFile::Open("CsI-1cm1cm1cm-new.root");

//TFile* inputFile = TFile::Open("GAGG-6mm6mm6mm-cs137-exp.root");

TH1F *spec[4];

//spec[0]=new TH1F();

spec[0]=(TH1F*)inputFile->Get("BGO-Na22");

//spec[0]=(TH1F*)inputFile->Get("Cs137-TC");

//spec[0]=(TH1F*)inputFile->Get("CsI-Cs137");

//spec[0]=(TH1F*)inputFile->Get("BGO-Cs137");

// S e t u p m o d e l

// ---------------------

//double myscale=1.0/h1->Integral();

//h1->Scale(myscale);//normalize the hist

int meanv=450;

int rangexmin=390;int rangexmax=580;

int xmin=rangexmin;int xmax=rangexmax;

RooRealVar x("x","x",xmin,xmax) ;

RooRealVar mean("mean","mean",meanv,rangexmin,rangexmax) ;

RooRealVar sigma("sigma","sigma",20,5.,500) ;

RooGaussian sig("sig","signal p.d.f.",x,mean,sigma) ;


RooRealVar argpar1("argpar1","argus shape parameter",20,0.,40.) ;

RooRealVar argpar2("argpar2","argus shape parameter",20,0.,40.) ;

RooArgusBG argus("argus","Argus PDF",x,argpar1,argpar2) ;

RooRealVar a0("a0","a0",-0.0001,-1.,0.1);

// RooRealVar a1("a1","", 0.5, -1, 100);

RooExponential bkg("bkg","background p.d.f.", x,a0);

RooRealVar c0("c0","coefficient #0", -1.0,-300.,10.) ;

RooRealVar c1("c1","coefficient #1", 0.1,-100.,1.) ;

RooRealVar c2("c2","coefficient #2",-0.1,-100.,2.) ;

RooChebychev compton("bkg","background p.d.f.",x,RooArgList(c0,c1,c2)) ;

RooRealVar mean_bkg("mean_bkg","mean",rangexmin/2+rangexmax/2,rangexmin,rangexmax);

RooRealVar sigma_bkg("sigma_bkg","sigma",30,10.,60.);

RooGaussian bkg_peak("bkg_peak","peaking bkg p.d.f.",x,mean_bkg,sigma_bkg) ;

RooRealVar fpeakbkg("fpeakbkg","peaking background fraction",0.5,0.4,1.) ;

RooAddPdf totalbkg("totalbkg","compton+bkg_peak",RooArgList(bkg_peak,compton),fpeakbkg);


RooRealVar fsig("fsig","signal fraction",0.9,0.5,1.) ;

//RooAddPdf

model("model","sig+(compton+bkg_peak)",RooArgList(sig,totalbkg),fsig);

RooAddPdf model("model","sig+bkg-e",RooArgList(sig,bkg),fsig) ;

//RooAddPdf

model("model","sig+compton",RooArgList(sig,compton),fsig) ;

//RooAddPdf

model("model","sig+compton",RooArgList(sig),fsig) ;

//RooAddPdfmodel("model","sig+compton",RooArgList(sig,argus),fsig) ;


//RooPlot* frame = x.frame(Title("CsI Cs-137 662keV Photopeak Fitting;Channel"));

//RooPlot* frame = x.frame(Title("BGO Cs-137 662keV Photopeak Fitting;Channel"));

RooPlot* frame = x.frame(Title("BGO Na-22 511keV Photopeak Fitting;Channel"));

//RooPlot* frame = x.frame(Title("GAGG Ba-133 81keV Photopeak Fitting"));

RooAbsData* data = new RooDataHist("data","data",x,spec[0]);

data->plotOn(frame);

//data->plotOn(xframe,Binning(1000));

//model.fitTo(*data,Save(),Extended());

model.fitTo(*data,Save(),Extended(),Range(rangexmin,rangexmax));

//model.fitTo(*data,Save(),Extended(),Range(rangexmin,rangexmax));


model.plotOn(frame,LineColor(kGreen)) ;

//model.plotOn(frame,Components(argus),LineColor(kBlue),LineStyle(kDashed)) ;

model.plotOn(frame, Components(compton),LineColor(kBlue),LineStyle(kDashed)) ;

model.plotOn(frame, Components(sig),LineColor(kRed),LineStyle(kDashed)) ;

//model.plotOn(frame, Components(bkg_peak),LineColor(kViolet),LineStyle(kDashed)) ;

//model.plotOn(frame, Components(totalbkg),LineColor(kBlue),LineStyle(kDashed)) ;

//model.plotOn(frame, Components(bkg),LineColor(kBlue),LineStyle(kDashed)) ; 


//model.paramOn(frame, Format("NEU"), Layout(0.15,0.50,0.9));

model.paramOn(frame,Parameters(RooArgSet(sigma,mean)), Format("NEU"), Layout(0.55,0.9,0.9));

//model.paramOn(frame,Parameters(RooArgSet(sigma,mean,c0,c1,c2)), Format("NEU"),Layout(0.55,0.9,0.9));

//model.paramOn(frame,Parameters(RooArgSet(sigma,mean,fsig,a0)), Format("NEU"), Layout(0.55,0.9,0.9));

TCanvas* c = new TCanvas("c2","Fitting test",1200,800);

frame->Draw() ;

//c->Print(Form("Na22-511keVfit0903.png"));

//c->Print(Form("Ba133-81keVfit0903.png"));

}


图3 全能峰拟合

到这里,两个目的均已达成,Roofit其实算是种很偷懒的拟合,未来的教程将探讨普适的Fit以及TSpectrum的机智用法。


图4 TSpectrum用作峰位的初始化值很方便,且很准确
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容