Z Candidateの質量分布を作る
次の5つのファイルをダウンロードしてください。(code03)
main.cxx
ZZ.h
ZZ.cxx
signal.script
Makefile
ZZ.h,cxxにメンバ関数を若干追加しました。
解析の大きな流れは、もちろん
1. Muon candidatesの選択
2. Z candidatesの再構成
です。
そのために、メンバ関数
1. SelectMuon()
2. MakeZBoson()
を追加しました。また、MakeZBoson()は内部で
MakeZBoson(std::vector &ZBosons, std::vector &Leptons)
をコールしています。これは単純にElectronを追加したときに便利だと思ったからです。
あと、追加したメンバ関数は
- ClearLists()
- DeleteLists()
です。これらはプログラムの上では重要な役割を持っています。- 解析の上ではどうでもいいが、存在しないと解析自体はうまく終らない。
ClearLists()はMuonとZmmという入れ物(std::vector)の中をきれいにしています。
つまり、メンバであるMuonとZmmの中にあるものを入れ物から削除します。
(入れ物から削除するだけで、それ以上のことはしません。)
これをしないと、イベントループで次のイベントのとき前イベントのMuonやZmmが残ってしまいます。
きちんとプログラムの流れを考えて、どこかに必ず必要です。今回はイベントの最初の方におきました。
DeleteListsはZmmの中身を"delete"しています。
Zmmの中身の生成過程を見ると分かりますが"new"で生成しています。
ユーザーが"new"で生成したのだから、"delete"もユーザーの責任で行います。
この関数を呼ばないとメモリーリークが起こります。
これも、きちんとプログラムの流れを考えてどこかに必ず必要です。今回はイベントの最後におきました。
DeleteListsの中から呼ばれているDeleteListは基底クラスのメンバ関数で
void ATHENA_CBNT_Event::DeleteList(std::vector &list) {
for (std::vector::reverse_iterator i = list.rbegin();
i != list.rend(); ++i) {
delete *i;
}
}
というシンプルな内容です。
よくあることですが、これらはreturnをたくさん入れると呼び忘れることがあります。
ここで、若干プログラムの中を見てみます。
int Userana::SelectMuon(void)
{
int nMuonPlus = 0;
int nMuonMinus = 0;
for (unsigned i=0;i<GetMuonListAtlfast().size();++i) {
// GetMuonListAtlfast()[i]だと長いので短い名前のポインタで受けた。(参照でもいい)
Particle * trk = GetMuonListAtlfast()[i];
// Isolated Muonかどうかチェックしている。
// PIDクラス($ATLJ_TOP_DIR/include/particle/PID.h)を利用。
if (trk->pId().isIsoMuon()) {
// Ptやetaの情報にアクセス。
// 本来はMomentumクラス($ATLJ_TOP_DIR/include/particle/Momentum.h)の役割だが
// よく使うものだけはParticleクラス($ATLJ_TOP_DIR/include/particle/Particle.h)にもメンバ関数が準備されている。
if (trk->pt() > mc_IsoMuonPtCut &&
fabs(trk->eta()) < mc_IsoMuonEtaCut) {
Muon.push_back(trk);
// 電荷はPDG idで確認する。
// Ptypeクラス($ATLJ_TOP_DIR/include/particle/Ptype.h)を利用するが、
// これもよく使うのでParticleクラスにメンバ関数がある。
if (trk->pType().pdgid() > 0) {
++nMuonMinus;
} else {
++nMuonPlus;
}
}
}
}
if (nMuonMinus >= 1 && nMuonPlus >= 1 &&
nMuonMinus+nMuonPlus >= mc_IsoLetponNCut) {
return 1;
} else {
return 0;
}
}
void Userana::MakeZBoson(std::vector<Particle*> &ZBosons,
std::vector<Particle*> &Leptons)
{
int nL = int(Leptons.size());
if (nL < 2) return;
for (int i=0;i<nL-1;++i) {
for (int j=i+1;j<nL;++j) {
// 電荷が逆であることを要求している。
if (Leptons[i]->pType().pdgid()*Leptons[j]->pType().pdgid() < 0) {
// CLHEPの4次元運動量を扱うクラス(HepLorentzVector)を利用している。
// +という演算子があるので簡単。
HepLorentzVector p = Leptons[i]->p()+Leptons[j]->p();
// Particleオブジェクトを作成している。
// 引数としては、HepLorentzVectorとPtype。ZのPDG idは23。
Particle *z = new Particle(p,Ptype(23));
// より詳しい解析のために、Zをどの粒子から再構成したか? という情報を保存しておく。
// このために、Relationクラス($ATLJ_TOP_DIR/include/particle/Relation.h)を利用する。
if (Leptons[i]->pType().pdgid() < 0) { // in order: + - of charge
z->relation().append(Leptons[i]);
z->relation().append(Leptons[j]);
} else {
z->relation().append(Leptons[j]);
z->relation().append(Leptons[i]);
}
ZBosons.push_back(z);
}
}
}
}
これらのプログラムを実行する(10000イベント)とZ candidatesの質量分布は次のようになります。
Go to the next page
Go to the previous page
Go to the index page
jtanaka