-- MasahiroMorinaga - 03 Apr 2014

基本的にはROOTができれば大丈夫。

ATLASのデータセット(dataとmc)はTTreeでrootfileにつまっている、そのTTreeをC++等のコードで読んでヒストグラムを作って、絵を作る。

最近の解析はD3PDというフォーマット(中身がTTreeのrootfile)で行うことを前提にいろいろなツールが作られているので、TTreeを使えるようになってください。

このチュートリアルはlogin.iceppのSL6のマシンで行うことを前提としてます。

適当なディレクトリを作ってそのの下で作業をしましょう。

Higgs->WW->lnuqq

ここではHiggsがWWに崩壊して、一つのWがレプトニックに崩壊するモードのサンプルを使ってお勉強をしましょう。 サンプルは

/gpfs/fs3001/atljphys/datafiles/NTUP_COMMON/mc12_8TeV/mc12_8TeV.167930.PowhegPythia8_AU2CT10_ggH400CPS_WWlepnuqq.merge.NTUP_COMMON.e1617_s1581_s1586_r3658_r3549_p1575/

にあります。この中の適当なファイルを一つROOTで読んで中のTTreeを読むクラスを作りましょう。

 $ root -l /gpfs/fs3001/atljphys/datafiles/NTUP_COMMON/mc12_8TeV/mc12_8TeV.167930.PowhegPythia8_AU2CT10_ggH400CPS_WWlepnuqq.merge.NTUP_COMMON.e1617_s1581_s1586_r3658_r3549_p1575/NTUP_COMMON.01343854._000028.root.1

Applying ATLAS style settings...

root [0]
Attaching file NTUP_COMMON.01343854._000028.root.1 as _file0...
Warning in <TClass::TClass>: no dictionary for class AttributeListLayout is available
Warning in <TClass::TClass>: no dictionary for class pair<string,string> is available
root [1] .ls
TFile**         NTUP_COMMON.01343854._000028.root.1     StreamNTUP_COMMON
 TFile*         NTUP_COMMON.01343854._000028.root.1     StreamNTUP_COMMON
  KEY: AttributeListLayout      Schema;1
  KEY: TDirectoryFile   physicsMeta;1   physicsMeta
  KEY: TDirectoryFile   Lumi;1  Lumi
  KEY: TTree    CollectionTree;1        CollectionTree
  KEY: TTree    physics;1       physics
  KEY: TTree    physicsTrigDec;1        physicsTrigDec
root [2] physics->MakeClass();
Info in <TTreePlayer::MakeClass>: Files: physics.h and physics.C generated from TTree: physics
root [3] .q

physics.hとphysics.Cというファイルができているはずです、中身を見てみてください。

たくさん、ブランチが定義されています、ブランチの名前を見るといくつかの種類に分けられます、

el_* Electronの変数たち
ph_* フォトンですよね
mu_* Muonの人たち
tau_* タウの変数
jet_* ジェットたち
MET_* Missing ETたち
L1_* Level 1トリガーたち
L2_* Level 2トリガーたち
EF_* EventFilter(LV3 トリガー)たち
trig_* 各トリガーの計算に用いた変数たち
vx_* バーテックス
trk_* トラックたち
mc_* モンテカルロのtruthの情報

まあ、実際の解析で普通に使うのはこれくらいです。

このphysicsというクラスを使ってイベント毎に解析をします。

MyAna

Step1

ここからはC++のコードを書いてきます。

physicsを継承させたMyAnaというクラスを作ります。

ここに書くのは面倒なので/home/morinaga/Tutorial2014/step1においたのでコピーしてください。

Makefile見ればわかりますが、physicsクラスは巨大なのでコンパイルは一度だけ初めにやって、共有ライブラリ作ります。

使い方は、

 $ make physics
 Compiling physics/physics.o 
Compiling Shared physics 
 $ make clean;make
Now Cleaning
 Compiling main/main.o 
 Compiling MyAna/MyAna.o 
 Compiling all Succesfully Done!!!

とすると、anaという人が出来上がるので、それを

./ana -i input.txt

とするとたくさん数字が出てきます。MyAnaの中身をみればわかりますが(わからなかったらやばいよやばいよ)、electronの数を表示しているだけです。 (コンパイラはclang++にしていますが適宜好きなものにしてください、好みです。Makefile変えてね。) ここまでがStep1です。お疲れ様です。

Step2

Electronの数を表示するだけではだめなので、いろいろやりましょう。

ATLASでは、各物理オブジェクトを再構成してます(ジェットとかミューオンとか)、これには偽物もかなり入っているので(step1は信号なのに電子がたくさんいましたね)こいつらを落としていきます。

Electronの選択

電子は偽物多いです、Fake electronとか呼びますがそのほとんどがジェット(パイオン)由来です。これらを落とすためにATLASではいろいろやっています。

step2といいうディレクトリを見てください、さっきのMyAnaのExecute()にElectronのスタンダードなカットを書いておきました。

  // Electron Selection
  std::vector<TLorentzVector> GoodElectrons;GoodElectrons.clear();
  for (int i = 0; i < el_n; ++i) {
    TLorentzVector this_el = TLorentzVector();
    this_el.TLorentzVector::SetPxPyPzE(el_px->at(i)/1000.,el_py->at(i)/1000.,el_pz->at(i)/1000.,el_E->at(i)/1000.);
    if ((el_author->at(i) == 1) || (el_author->at(i) == 3)) {
      if (fabs(el_charge->at(i)) == 1) {
        if ((el_OQ->at(i)&1446) == 0) {
          if(fabs(this_el.Eta()) < 1.37 || (fabs(this_el.Eta()) > 1.52 && fabs(this_el.Eta()) < 2.47)){
            if(fabs(el_trackz0pvunbiased->at(i)*sin(el_tracktheta->at(i))) < 0.5){
              if(fabs(el_trackd0pvunbiased->at(i)/el_tracksigd0pvunbiased->at(i)) < 6.0){
                if(this_el.Pt() > 25.){
                  if(el_tightPP->at(i) == 1){
                    if( el_ptcone20->at(i)/1000./this_el.Et() < 0.14){
                      if( el_Etcone20->at(i)/1000./this_el.Et() < 0.15){
                        GoodElectrons.emplace_back(this_el);
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  std::cout << "#of Electron Raw/Select is " << el_n << "/" << GoodElectrons.size() << std::endl;

上から説明してくと、

まず、セレクションを通ったelectronの箱をvectorで作っておきます。ここで、TLorentzVectorというクラスを使っていますが、まあ知ってますよね、しらないなら調べてね。

再構成された電子のすべてをループでみます。まずTLorentzVectorに値をつめます。(ATLASのエネルギー等の標準の単位はMeVなので1/1000してGeVにします。解析に慣れたいまでもたまに忘れるので覚えておいてください)

ここから合計10つのカットをapplyします、

Cut1 1番目からわからないと思いますが、Authorというのはざっくり言うとどのアルゴリズムで再構成されたか、というフラッグです。はじめは魔法のことばとして適用してください。
Cut2 まあ、これはわかりますね。
Cut3 これも魔法のことばです、気になる人はATLASのノートとか見ると詳しく乗っています。
Cut4 ATLASの電子再構成はトラッカー使うので、これががある部分で行われます。間に1.37~1.52というギャップがありますが、これは検出器のサービスモジュールが集中してある部分でここはエネルギー測定精度が出ないので使いません。
Cut5,6 この2つは、電子のトラックと事象が発生したと思いたい衝突点(Primary vertex)との関係を見ています。衝突点ゆらいならこれらとトラックとの距離が小さいことが期待されます。(トラック等の標準単位はmmです。)
Cut7 電子がある程度大きなPtを持つことを要求します。
Cut8 偽物の電子を取り除くために強力なID(identification)をチェックします。これはEgammaグループという人たちが開発しています。
Cut9,10 Isolationカット。このXXconeYYという変数は、電子のまわりdR < Y.Y に存在するエネルギーの和です、それと電子のエネルギーの比をとったものが小さいことを要求します。これでジェットからの偽物が落ちます。理由は自分で考えてみましょう。

すべてのセレクションを通ったものをさっきの箱に詰めていきます。(emplace_backが使えない人はpush_backを使いましょう。)

最後にいくつの電子がセレクション通ったかを表示します。結構、落ちていることがわかります。

Muonの選択

続いてMuonのセレクションです。

  // Muon Selection
  std::vector<TLorentzVector> GoodMuons;GoodMuons.clear();
  for ( int i = 0; i < mu_staco_n; ++i) {
    TLorentzVector this_mu = TLorentzVector();
    this_mu.TLorentzVector::SetPxPyPzE(mu_staco_px->at(i)/1000.,mu_staco_py->at(i)/1000.,mu_staco_pz->at(i)/1000.,mu_staco_E->at(i)/1000.);
    if(mu_staco_author->at(i) == 6){
      if(fabs(mu_staco_eta->at(i)) < 2.5){
        if(mu_staco_isCombinedMuon->at(i) == 1) {
          if (mu_staco_expectBLayerHit->at(i) == 0.0 || mu_staco_nBLHits->at(i) > 0) {
            if (mu_staco_nPixHits->at(i) + mu_staco_nPixelDeadSensors->at(i) > 0) {
              if (mu_staco_nSCTHits->at(i) + mu_staco_nSCTDeadSensors->at(i) > 4) {
                if (mu_staco_nPixHoles->at(i) + mu_staco_nSCTHoles->at(i) < 3) {
                  int MuHitN = mu_staco_nTRTHits->at(i) + mu_staco_nTRTOutliers->at(i);
                  bool isOKTRT = false;
                  if ((fabs(mu_staco_eta->at(i)) > 0.1) && (fabs(mu_staco_eta->at(i)) < 1.9)){
                    if((MuHitN > 5) && (mu_staco_nTRTOutliers->at(i) < 0.9*MuHitN)){ isOKTRT = true; }
                  }
                  if((fabs(mu_staco_eta->at(i)) <= 0.1) || (fabs(mu_staco_eta->at(i)) >= 1.9)){
                    if(MuHitN > 5){
                      if(mu_staco_nTRTOutliers->at(i) < 0.9*MuHitN){ isOKTRT = true; }
                    }else{
                      if(MuHitN > 5){
                        if(mu_staco_nTRTOutliers->at(i) < 0.9*MuHitN){isOKTRT = true; }
                      }else{ isOKTRT = true; }
                    }
                  }
                  if(isOKTRT){
                    if(this_mu.Pt() > 25.){
                      if (fabs(mu_staco_trackz0pvunbiased->at(i)*sin(mu_staco_tracktheta->at(i))) < 0.5){
                        if(fabs(mu_staco_trackd0pvunbiased->at(i)/mu_staco_tracksigd0pvunbiased->at(i)) < 3.5){
                          if(fabs((mu_staco_id_qoverp->at(i)-mu_staco_me_qoverp->at(i))/(sqrt(mu_staco_id_cov_qoverp_exPV->at(i)+mu_staco_me_cov_qoverp_exPV->at(i)))) < 5.0){
                            if( mu_staco_ptcone20->at(i)/1000./this_mu.Pt() < 0.14){
                              if( mu_staco_etcone20->at(i)/1000./this_mu.Pt() < 0.15){
                                GoodMuons.emplace_back(this_mu);
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  std::cout << "#of Muon Raw/Select is " << mu_staco_n << "/" << GoodMuons.size() << std::endl;
全部で、14つあります。
Cut 1 Authorは電子のときと同じ
Cut 2 Etaもトラッカーwるとこだけ。
Cut 3 CombinedMuonといって、InnerDetector(ID)やMuonSpectrometer(MS)の各検出器で正しくMuonが再構成されていてかつ偽物ではないようなMuonを選びます。これはMCPグループの人たちが開発してます。
Cut 4 Blayerでのヒット数を要求します
Cut 5 今度はPixel
Cut 6 今度はSCT
Cut 7 PixelとSCTでの検出器の穴、死んでいる箇所を叩いている数が多くない
Cut 8 これは少しやっかいです。TRTでのヒット数をいろんな条件でチェックします。これもMCPの人たちが決めます。
Cut 9 Ptが大きい
Cut 10,11 トラックとPVの距離が大きくないことを要求します、宇宙線由来とかこれで落ちます。
Cut 12 すこしマニアックなカットですが、IDとMSで測ったトラックのq/pがほぼ同じであることを要求します。
Cut 13,14 これも電子のときと同じIsolationのカットです。

最後に通ったものを詰めて数を表示します。

ジェットの選択

ジェットです、ATLASでは標準的にAntiKtというアルゴリズムでジェットを再構成しています。4という数字はdR < 0.4の大きさを表します。LCTopoというのはざっくりいうとエネルギーの測り方です。気になれば調べてね。

  //Jet Selection
  std::vector<TLorentzVector> GoodJets;GoodJets.clear();
  for (int i = 0; i< jet_AntiKt4LCTopo_n; i++) {
    TLorentzVector this_jet = TLorentzVector();
    this_jet.TLorentzVector::SetPtEtaPhiE(jet_AntiKt4LCTopo_pt->at(i)/1000.,jet_AntiKt4LCTopo_eta->at(i),jet_AntiKt4LCTopo_phi->at(i),jet_AntiKt4LCTopo_E->at(i)/1000.);
    if(this_jet.Pt() > 30.){
      float const_eta = jet_AntiKt4LCTopo_constscale_eta->at(i);
      if (fabs(const_eta) < 4.5) {
        if (this_jet.Pt() < 50. && fabs(const_eta) < 2.4 && fabs(jet_AntiKt4LCTopo_jvtxf->at(i)) < 0.5) {
          if ((jet_AntiKt4LCTopo_isUgly->at(i) == 0) && (jet_AntiKt4LCTopo_isBadLooseMinus->at(i) == 0) ){
            GoodJets.emplace_back(this_jet);
          }
        }
      }
    } 
  }  
  std::cout << "#of Jet Raw/Select is " << jet_AntiKt4LCTopo_n << "/" << GoodJets.size() << std::endl; 
ジェットはカットが少ないです、偽物気にしなくて良いので。。。
Cut 1 Ptが30GeVより大きい
Cut 2 etaがカロリメータがあるところまで。
Cut 3 これは少しややこしいですが、JVF(JetVertexFlaction)という変数です、ざっくりいうとジェットのエネルギーが、その事象のバーテックスから出るすべてのトラックのうち、どれくらいを占めるか、というものでジェットの人たちが決めます。
Cut 4 ジェットクリーニングといって変なジェット(エネルギーが正しく測れなかったとか)を除きます。これもジェットの人たちが決めます。

MissingETの再構成(METだよ)

METの再構成は、概念的には簡単です。すべての物理オブジェクトのベクトル和の逆を取ればよいのです。

言葉では簡単でも、実際に行うのはとっっっっても難しいです。METグループがある程度計算してくれますが、解析によって少し修正しなければいけません。

それは難しいので、ここでは示しませんが解析やってればいずれはやります。

  // MET Reconstruction
  TVector2 MET;
  MET.Set(MET_RefFinal_STVF_etx,MET_RefFinal_STVF_ety);
ざっくり説明だけすると、RefFinalという種類のSTVFという補正をかけたMETです。

最後にコンパイルして、走らせてどれくらい数が変わるか見てみましょう。

step2はおしまいです。

Step3

ここではstep2でつくったElectron/Muon/Jet/METを使って実際に分布を作ってみましょう。

lnuqqなので、見えるものとしてはレプトン(el or mu)が1つ、ジェットが2本とMETです。

step2ではのべませんでしたが、これらを選ぶときに重要なカットがまだあります、Overlap removalと僕達は呼んでいますが、それぞれの物理オブジェクトが重なっていないということをチェックします。

step3のディレクトリをコピーとかしましょう。コードが新しくなっています。

Overlap Removal

物理オブジェクトのオーバーラップを解くことは大事です、実は電子なものがジェットとして再構成されていた、というのはよくあります。

基本的にはひとつひとつ他のオブジェクトとのdR が近くないかを調べます。

ATLASの解析でよくあるのは、Muon --> Electron --> Jet の順番に、dR < 0.2になっていないかをチェックします。これを簡単に実装しておいたのでMyAna見てください。 (C++11が使えない人は自分で書きなおしてね)

これをおこなったあとに分布をチェックしていきます。

(ヒストグラムを)つくってあそぼ

ヒストグラムくらいは作ったことあると思うので詳しくは述べませんが、いろんな分布を作ってください。例えば、レプトンのPt/Eta/Phiとか、ジェットのPt/Eta/Phiとか、METとか。。。

WW->lnuqqで重要な変数を幾つか挙げておくので、自分で考えて絵を作って見てください。

・W- > lep + nu の 横方向質量(transverse mass)とPt

・W -> qq(jet + jet) の 質量とPt

・WWシステムの質量とかPtとか。(W massを仮定して2次方程式を解きましょう)

この辺の絵を作って誰かに見せましょう。大丈夫そうだったら前のページのDataAndMc見てください。

Edit | Attach | Watch | Print version | History: r15 < r14 < r13 < r12 < r11 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r15 - 2014-04-14 - MasahiroMorinaga
 
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    Main All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright &© 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback