第一届(2020)高能物理计算暑期学校上机练习一,作业提交及使用1, 作业准备2,作业提交3,作业查询4,作业删除5,查看作业结果二,容器使用1 容器技术介绍1.1 容器的特点1.2 容器与虚拟机区别1.3 容器引擎2 hep_containerHep_container的特点2.1 命令说明2.2 查看支持镜像2.3 查看支持用户组/实验组2.4 进入容器环境2.5 容器内执行命令3 镜像制作3.1 通过定义文件制作镜像3.2 使用自制镜像3.3 其他镜像制作方法三,Git 使用1 git本地配置2 准备本地代码仓库3 工作目录操作4 暂存操作5 提交操作6 远程仓库操作7 分支操作8 标签操作四,ROOT 分析作业1,生成数据样本1.1 定义分布函数1.2 生成数据样本,填tree,写入root文件2. 读取root文件,填直方图,画出直方图3. 拟合直方图
xxxxxxxxxx
$ ssh username@schlogin.ihep.ac.cn
注意,username需替换为你的用户名
xxxxxxxxxx
$ pwd
$ ls
xxxxxxxxxx
$ touch job.sh
xxxxxxxxxx
vim job.sh
xxxxxxxxxx
echo"This job is running on$(hostname)."
/bin/sleep10
echo"We're doing a simple operation:"
result=$(expr 1 + 1)
echo" 1+1=$result"
/bin/sleep10
echo"Job Done!"
xxxxxxxxxx
:wq
xxxxxxxxxx
$ chmod+x job.sh
xxxxxxxxxx
$ hep_subjob.sh
如果成功,显示内容如下:
xxxxxxxxxx
1job(s) submitted to cluster13
其中,13代表作业id,作业id为作业最重要的身份信息,可利用作业id进行作业查询和删除等操作。
xxxxxxxxxx
# 按用户查询
$ hep_q-utest001
# 按作业ID查询
$ hep_q-i13
# 如果作业状态为'H', 表明作业被挂起,可使用如下命令
$ hep_q-i13-hold
$ hep_q-utest001-hold
xxxxxxxxxx
# 删除当前用户所有作业
$ hep_rm-a
# 按作业ID删除
$ hep_rm13
xxxxxxxxxx
$ ls
找到 .out 和 .err 文件:
xxxxxxxxxx
-.out 文件保存标准输出内容
-.err 文件保存标准错误内容
查看结果文件:
xxxxxxxxxx
$ catjob.sh.out*
输出如下,说明作业正常运行结束
xxxxxxxxxx
This job is running on accap059.ihep.ac.cn.
We're doing a simple operation:
1+1=2
Job Done!
其中,accap059.ihep.ac.cn 为作业执行节点,该节点名会根据实际执行的节点,有所变化
容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序可以在几乎任何地方以相同的方式运行。无需任何修改就能够在生产系统的虚拟机、物理服务器或公有云主机上运行。
跨环境、可移植、资源和应用隔离性、安全性。
Singularity是目前在高性能计算平台上被大量应用的轻量虚拟化容器技术,能够提供操作系统级的虚拟化。
Hep_container是基于singularity容器管理命令开发的适用于高能所计算集群的容器客户端工具,满足用户使用多种操作系统版本及环境的需求。说明:本文涉及的命令均需要登陆节点上运行,所用命令在以下目录,建议将该目录加入用户个人环境变量 PATH 中。
xxxxxxxxxx
/cvmfs/container.ihep.ac.cn/bin/
exportPATH=$PATH:/cvmfs/container.ihep.ac.cn/bin/
Hep_container的容器命令主要有以下操作images、shell、exec等。可以在命令行中通过help参数查看各个命令的使用说明和样例
xxxxxxxxxx
$ hep_containerhelp
Usage : ./hep_container [command options...]
CONTAINER USAGE COMMANDS:
shell Run a Bourne shell within container image
exec Execute a command within container image
images List Support container images
groups List Support groups
-ggroupname With a specific group name
EXAMPLES:
./hep_container images
./hep_container groups
./hep_container shell SL5
./hep_container shell SL5-gphysics
./hep_container exec SL5cat/etc/redhat-release
./hep_container exec SL5 python ./yourprograme.py
./hep_container exec SL5-gphysicscat/etc/redhat-release
命令格式:hep_container images 该指令可以查看当前提供的操作系统容器镜像。
xxxxxxxxxx
$ hep_containerimages
Hep_container support images:
SL5 : Scientific Linux5
SL6 : Scientific Linux6
SL7 : Scientific Linux7
命令格式:hep_container groups 该指令可以查看容器命令当前支持提供的用户组或者实验组。通过 -g 参数指定用户组或实验组,容器内会挂载对应用户目录和实验目录。不指定-g参数默认采用主组作为用户组或实验组。
xxxxxxxxxx
$ hep_containergroups
Hep_container support groups:
u07|atlas|atlasrun|comet|offline|physics|higgs|ams|cms|dyw|hxmt|polars|juno|argo|lhaaso|sch
命令格式:hep_container shell [container image] 该指令可以在容器内启动一个shell,因此可以在容器外部与容器内部进行交互操作。运行exit则可以退出该shell。 下例为运行启动一个SL5操作系统镜像后,用户当前为SL5的系统环境.
xxxxxxxxxx
$ hep_containershell SL5
Singularity: Invoking an interactive shell within container...
Singularity>cat/etc/redhat-release
Scientific Linux SL release5.5 (Boron)
Singularity>exit
exit
命令格式:hep_container exec [container image] [command] 该指令可以在外部主机上将指定的command运行在指定的容器内。 下例为在lxslc7上以SL5的环境运行SL5命令,并得到结果。
xxxxxxxxxx
$ hep_containerexec SL5cat/etc/redhat-release
Scientific Linux SL release5.5 (Boron)
xxxxxxxxxx
[user1@dockertest02]# cat mymkimage.def
BootStrap:yum
OSVersion: 7.8
MirrorURL: http://mirror.ihep.ac.cn/centos/7/os/x86_64/
UpdateURL: http://mirror.ihep.ac.cn/centos/7/os/x86_64/
Include: yum
%setup
%files
#~/home/yourfile ~/usr/local/yourfile
%runscript
echo "Running the container..."
%post
echo "Installing base group"
yum -y groupinstall "Minimal Install"
echo "Installing basic packages"
yum -y install vim-enhanced wget ntp gcc gcc-c++ glibc make
echo "Installing requied packages"
yum -y install python36
xxxxxxxxxx
sudo singularity build mymkimage.sif mymkimage.def
xxxxxxxxxx
export MYIMAGE=/home/sch/test001/mymkimage.sif
hep_container shell MYIMAGE
参考https://sylabs.io/guides/3.5/user-guide/build_a_container.html
xxxxxxxxxx
# 请修改your name为自己的名字
$ gitconfig--globaluser.name"your name"
# 请修改your_email_address为自己的邮箱地址
$ gitconfig--globaluser.email your_email_address
xxxxxxxxxx
$ gitconfig--globalcore.editorvim
xxxxxxxxxx
$ gitconfig--list
xxxxxxxxxx
[user]
name="Your-name"
email="Your-email"
[alias]
a=add .
v=!gitk
br=branch
ci=commit-m
cm=commit-m
co=checkout
df=diff
dump=cat-file-p
hs=log--pretty=format:\"%h %ad | %s%d [%an]\"--graph--date=short
last=log-1HEAD
pl=pull
ps=push
st=status
type=cat-file-t
sum=shortlog-sn
[push]
default=matching
xxxxxxxxxx
#### ~/.ssh/config
Host code
Hostname code.ihep.ac.cn
Usergit
Identityfile ~/.ssh/id_rsa
xxxxxxxxxx
$ mkdir-p~/source
$ rsync-avru/cvmfs/slurm.ihep.ac.cn/2020_summer_school_git/marigold ~/source/
$ cd~/source/marigold &&gitconfig receive.denyCurrentBranch ignore &&cd~
$ gitclone ~/source/marigold
xxxxxxxxxx
$ cd~/marigold
# 编辑修改该目录下的文件README
$ echo"1. Modified to check file status after edit.">> README.md
# 编辑后查看文件状态
$ gitstatus
xxxxxxxxxx
# 将修改的文件README.md暂存
$ gitadd README.md
# 查看文件状态
$ gitstatus
xxxxxxxxxx
# 提交暂存区的文件
$ gitcommit-m'Add one line on README.md.'
# 查看文件状态
$ gitstatus-s
xxxxxxxxxx
# 查看远程仓库
$ gitremote-v
# 发布到远程仓库(一般 push 分支)
$ gitpush origin master
xxxxxxxxxx
# 查看分支
$ gitbranch
# 创建分支
$ gitbranch chkbr
# 切换到新建的branch
$ gitcheckout chkbr
# 查看分支
$ gitbranch
# 修改文件README.md
echo"2. Add a new branch named chkbr for branch operation practice.">> README.md
# 将修改后的文件放置暂存区
$ gitadd README.md
# 提交修改后的文件
$ gitcommit-m'Modify README.md - practise branch operations.'
# push 分支到远程仓库
$ gitpush origin chkbr
# 切换回master分支
$ gitcheckout master
# 合并分支chkbr
$ gitmerge chkbr
# 查看branch
$ gitbranch
# 查看操作日志
$ gitlog--oneline--decorate--graph-–all
# 删除分支
$ gitbranch-dchkbr
# 查看分支
$ gitbranch
xxxxxxxxxx
# 给自己的稳定版本增加版本标签吧
$ gittag-av1.0-m'Basic version'
# 列出所有标签
$ gittag
# or
$ gittag-l
# 查看标签的详细信息
$ gitshow v1.0
# 共享标签
$ gitpush origin v1.0
查看练习示例脚本
xxxxxxxxxx
>cdroot_exercise
>ls
-rw-r--r--1user group1792Aug1619:45 exercise0.C
-rw-r--r--1user group969Aug1619:49 exercise1.C
-rw-r--r--1user group2848Aug1619:40 exercise2.C
Lorentzian Peak function:
xxxxxxxxxx
// Quadratic background function
Double_tbackground(Double_t*x,Double_t*par) {
returnpar[0]+par[1]*x[0]+par[2]*x[0]*x[0];
}
// Lorentzian Peak function
Double_tlorentzianPeak(Double_t*x,Double_t*par) {
return(0.5*par[0]*par[1]/TMath::Pi())/TMath::Max(1.e-10,
(x[0]-par[2])*(x[0]-par[2])+.25*par[1]*par[1]);
}
// Sum of background and peak function
Double_tFunction(Double_t*x,Double_t*par) {
returnbackground(x,par)+lorentzianPeak(x,&par[3]);
}
xxxxxxxxxx
// create the file, the Tree and a few branches
TFilef=TFile::Open("tree.root","recreate");
TTree*tree=newTTree("tree","treelibrated tree");
Float_tx,y;
// create a branch with energy
tree->Branch("X",&x);
tree->Branch("Y",&y);
// create a TF1 with the range from 0 to 3 and 6 parameters
TF1*Fcnx=newTF1("Fcnx",Function,0,3,6);
TF1*Fcny=newTF1("Fcny",Function,0,3,6);
// Fix the Parameters of function
Fcnx->SetParameters(-1,45,-13.3,13.8,0.2,1);
Fcny->SetParameters(-1,45,-13.3,13.8,0.1,1.5);
// fill some events with random numbers
Int_tnevent=1000;
for(Int_tiev=0;iev<nevent;iev++) {
x=Fcnx->GetRandom();
y=Fcny->GetRandom();
tree->Fill();// fill the tree with the current event
}
// save the Tree header. The file will be automatically closed
// when going out of the function scope
tree.Write();
操作练习
xxxxxxxxxx
> root-lexercise0.C
root [0]
Processing exercise0.C...
root [1] .q
# 查看生成的 root 文件
>ls-l
-rw-r--r--1user group1792Aug1619:45 exercise0.C
-rw-r--r--1user group969Aug1619:49 exercise1.C
-rw-r--r--1user group2848Aug1619:40 exercise2.C
-rw-r--r--1user group76796Aug1620:03 tree.root
# 打开 root 文件, 通过 TBrowser 查看内容
> root-ltree.root
root [0] TBrowser a
# 在弹出窗口左侧文件列表中 "ROOT Files" 目录下找到 tree.root 文件,
# 双击 root 文件查看tree "tree",双击 tree 查看 Branch "X" 和 “Y”,
# 双击 Branch “X” 可以在右侧窗口中看到 “X” 的直方图。

xxxxxxxxxx
TFile*f=TFile::Open("tree.root");
TTree*t1=(TTree*)f->Get("tree");
Float_tx,y;
t1->SetBranchAddress("px",&px);
t1->SetBranchAddress("py",&py);
// create two histograms
TH1F*hx=newTH1F("hx","x distribution",100,-3,3);
TH2F*hxy=newTH2F("hxy","y vs x",30,-3,3,30,-3,3);
// read all entries and fill the histograms
Long64_tnentries=t1->GetEntries();
for(Long64_ti=0;i<nentries;i++) {
t1->GetEntry(i);
hx->Fill(x);
hxy->Fill(x,y);
}
// draw the histograms
TCanvas*c1=newTCanvas();
hx->Draw("E0");
c1->Print("hx.png")// eps, ps, jpg
TCanvas*c2=newTCanvas();
hxy->Draw("colz");// BOX, SCAT, ARR
c1->Print("hxy.png")
操作练习
xxxxxxxxxx
> root-lexercise1.C
root [0]
# 可以看到生成了一个一维直方图以及二维直方图
# 尝试改变画图选项,得到不同风格的直方图


单击菜单栏中 View 下拉菜单选中 Editor 选项可以调出编辑面版,可以手动编辑图片属性,如坐标轴标题,添加网格,直方图颜色等。尝试用鼠标单击图像不同位置,如直方图,坐标轴,标题处,观察编辑面板编辑选项的变化。尝试手动编辑图像属性。

xxxxxxxxxx
// Read the Tree
TFile*f=TFile::Open("tree.root");
TTree*t1=(TTree*)f->Get("tree");
TCanvas*c1=newTCanvas("c1","Fitting Demo",10,10,700,500);
c1->SetFillColor(33);
c1->SetFrameFillColor(41);
c1->SetGrid();
// Create one histogram
TH1F*histo=newTH1F("histo","Lorentzian Peak on Quadratic Background",60,0,3);
histo->SetMarkerStyle(21);
histo->SetMarkerSize(0.8);
histo->SetStats(0);
// Fill the histograms
t1->Project("histo","X");
// create a TF1 with the range from 0 to 3 and 6 parameters
TF1*fitFcn=newTF1("fitFcn",fitFunction,0,3,6);
fitFcn->SetNpx(500);
fitFcn->SetLineWidth(4);
fitFcn->SetLineColor(kMagenta);
// first try without starting values for the parameters
// This defaults to 1 for each param.
// this results in an ok fit for the polynomial function
// however the non-linear part (lorenzian) does not
// respond well.
fitFcn->SetParameters(1,1,1,1,1,1);
histo->Fit("fitFcn","0");
// second try: set start values for some parameters
fitFcn->SetParameter(4,0.2);// width
fitFcn->SetParameter(5,1);// peak
histo->Fit("fitFcn","V+","ep");
// improve the picture:
TF1*backFcn=newTF1("backFcn",background,0,3,3);
backFcn->SetLineColor(kRed);
TF1*signalFcn=newTF1("signalFcn",lorentzianPeak,0,3,3);
signalFcn->SetLineColor(kBlue);
signalFcn->SetNpx(500);
Double_tpar[6];
// writes the fit results into the par array
fitFcn->GetParameters(par);
backFcn->SetParameters(par);
backFcn->Draw("same");
signalFcn->SetParameters(&par[3]);
signalFcn->Draw("same");
// draw the legend
TLegend*legend=newTLegend(0.6,0.65,0.88,0.85);
legend->SetTextFont(72);
legend->SetTextSize(0.04);
legend->AddEntry(histo,"Data","lpe");
legend->AddEntry(backFcn,"Background fit","l");
legend->AddEntry(signalFcn,"Signal fit","l");
legend->AddEntry(fitFcn,"Global Fit","l");
legend->Draw();
操作练习
xxxxxxxxxx
> root-lexercise1.C
得到拟合结果:

可以在输出 log 里面找到函数参数的拟合值:
xxxxxxxxxx
NO. NAME VALUE ERROR NEGATIVE POSITIVE
1p0-6.98862e+001.03331e+00
2p12.36951e+025.46818e+00
3p2-6.93593e+012.12246e+00
4p38.09132e+015.59809e+00
5p42.05657e-011.77811e-02
6p51.01006e+005.72858e-03
也可以通过以下方式拿到单个参数值及其误差:
xxxxxxxxxx
# Get Associated Function
root[0] TF1 *fit=histo->GetFunction("fitFcn");
# value of the first parameter
root[1] Double_t p1=fit->GetParameter(0);
# error of the first parameter
root[2] Double_t e1=fit->GetParError(0);
# 同时我们还可以计算拟合的 chisquare 值
root[3] Double_t chi2=fit->GetChisquare();
附加练习
尝试将本例中的朗道分布替换为高斯分布,完成 root 文件生成,root 文件读入,画直方图,拟合直方图。