ANAROOT


はじめに

ここのページは僕のメモ帳です。 まとまった情報が こちらや、 こちらへ。 にあります。

解析の小枝

gH1: 現在表示しているヒストグラムへのポインタ
ex)
root[0] hn()
root[1] gH1->Draw("COLZH")
root[2] gH1->Fit("pol1","","COLZ",-0.1,0.1)
gethist(1): ls()したときの1番目のヒストグラムのポインタを替えす
ex)
root[0] hn()
root[1] gethist(11)->Draw("COLZH")
root[2] gethist(11)->Fit("pol1","","COLZ",-0.1,0.1)
DrawのオプションはCOLZHとしておけば一次元でも二次元でもanapawっぽい図になる
.rootrc
rootlogon.C
軸のprecision
文字の大きさ
センタリング
505,510
canvasを1:1にする。


綺麗な図の作り方

論文レベルとは言わないまでも、学校の卒業論文程度には十分と思われる図を作るための覚書。

.rootrc

.rootrcで気をつけるのは
Unix.*.Root.UseTTFonts:     true
となっていること。
TTFontsはTrue Type Fontの略で、綺麗なフォントになる代わりに描画時間が遅くなる。
sshで解析だけしたいときはむしろfalseにすると幸せになれる。
ただし、falseにしてy,z軸にタイトルをついたhistogramを表示しようとすると謎のエラーで落ちるので注意。

一旦root fileに保存する

図として載せたいヒストグラムはとにかく生成したあと、root fileに保存しておく。
そのあとマクロにタイトルやmaximum,minimumの値の調整を書いて、一気に図を作らないと
ちょこっと変更するのに大きな時間を食ってしまう。

綺麗な図を描画するように別途rootlogon.Cを用意

普段の解析で使用しているrootlogon.Cとは別に図作成用のrootlogon.Cを用意する。
例えばこんな感じ。
#ifndef __CINT__
#include "TROOT.h"
#include "TSystem.h"
#endif

void rootlogon()
{
  //Base Style
  //  gROOT->SetStyle("Plain");
  gROOT->SetStyle("Modern");
  //  gROOT->SetStyle("Classic");

  //Force Style
  //  gStyle->SetNumberContours(20);
  gStyle->SetHistFillColor(7);
  gStyle->SetHistFillStyle(3002);
  gStyle->SetHistLineColor(kBlue);
  gStyle->SetFuncColor(kRed);
  gStyle->SetFuncWidth(3);
  gStyle->SetCanvasColor(0);
  gStyle->SetCanvasDefH(600);
  gStyle->SetCanvasDefW(600);
  gStyle->SetPadBorderMode(1);
  gStyle->SetPadRightMargin(0.15);
  gStyle->SetPadLeftMargin(0.16);
  gStyle->SetPadTopMargin(0.14);
  gStyle->SetPadBottomMargin(0.14);
  gStyle->SetPadGridX(1);
  gStyle->SetPadGridY(1);
  gStyle->SetFrameLineWidth(2);
  gStyle->SetGridStyle(3);
  gStyle->SetGridColor(16);
  gStyle->SetTitleFillColor(0);
  gStyle->SetTitleStyle(0);
  gStyle->SetTitleY(0.93);
  //  gStyle->SetTitleXOffset(1.);
  gStyle->SetTitleXOffset(1.5);
  gStyle->SetTitleYOffset(2.0);
  gStyle->SetTitleAlign(22);
  gStyle->SetStatColor(0);
  gStyle->SetStatStyle(0);
  //  gStyle->SetStatStyle(1001);
  gStyle->SetStatX(0.848);  
  gStyle->SetStatY(0.86);  
  gStyle->SetStatW(0.3); // SetOptFit(0)で1Dで縦の幅がおかしくなるのを解決できる
  //  gStyle->SetStatH(0.3); 
  //  gStyle->SetStatW(0.2*1.8);
  //  gStyle->SetStatFontSize(0.02);  
  gStyle->SetPalette(1);
  //  gStyle->SetOptLogz(1);
  //  gStyle->SetOptDate(1);
  gStyle->SetStripDecimals(kFALSE);

  if(0){
    gStyle->SetOptTitle(1);
    gStyle->SetOptFit(1);
    gStyle->SetOptStat(1111111);
  }else{
    gStyle->SetOptTitle(0);
    gStyle->SetOptFit(0);
    gStyle->SetOptStat(0);
  }

  gStyle->SetLabelFont(132,"XYZ");
  gStyle->SetLabelSize(0.04, "XYZ");
  gStyle->SetLabelOffset(0.015, "XY");  
  gStyle->SetTitleFont(132,"XYZ");
  gStyle->SetTitleFont(132,"");
  gStyle->SetTextFont(132);
  gStyle->SetStatFont(132);
}

右上に凡例をよく付けるが、これは
TLegend *leg = new TLegend(0.2,0.73,0.6,0.8,NULL,"NDC");
leg->SetTextFont(132);
leg->SetTextSize(0.04);
leg->AddEntry(hist1,"NEUT","lp");
leg->AddEntry(hist2,"VETO","lp");
leg->SetBorderSize(0);
leg->SetFillColor(0);

hist1->Draw("COLZH");
hist2->Draw("COLZHsame");
leg->Draw("same");
というように、ヒストグラムを書いた後からつければ良い。


図をDrawしていく

以下はanarootに同封されているnadekoライブ ラリを使ったときの関数の例。
clear();
fetch("root/hime_inclxx.root");
ht(3);
chbin(2,2);
mami(0,100);
histtune(";Time of Flight (ns);Pulse Height (MeVee)",510,510,510);
htp();
redrawframe();
print("hime_inclxx_tof_ph.eps");
こんな感じ。
histtuneとかredrawframeはtrunkにはなくて2012SAMURAI.dayone.tanakaにしか入ってないかもしないので以下に示しておく。。
void histtune(const char* title, int nxdiv, int nydiv, int nzdiv, double xmin, double xmax, double ymin, double ymax)
{
  TH1* hist = gH1;
  if(!hist) return;

  hist->SetTitle(title);

  hist->GetXaxis()->SetNdivisions(nxdiv);
  hist->GetYaxis()->SetNdivisions(nydiv);
  hist->GetZaxis()->SetNdivisions(nzdiv);

  hist->GetXaxis()->CenterTitle(1);
  hist->GetYaxis()->CenterTitle(1);

  if(xmin < xmax){
    hist->GetXaxis()->SetLimits(xmin,xmax);
  }
  if(ymin < ymax){
    hist->SetMaximum(ymax);
    hist->SetMinimum(ymin);
  }

//  if(hist->GetDimension() == 1){
//    hist->Draw("COLZHHIST");
//  }else{
//    hist->Draw("COLZH");
//  }
  hist->Draw();

  ReDrawFrame();
}

void TArtSimpleFunction::ReDrawFrame()
{
  if(!gPad) return;
  TFrame* frame = gPad->GetFrame();
  frame->SetFillStyle(0);
  frame->Draw("same");
}

pryしたあとにX軸のタイトルがやけに離れる問題

TH1::ProjectionYとかすると、y軸のタイトルのオフセットがx軸に反映されてしまう。 これを直すためには、
histd->SetTitleOffset(hist2->GetTitleOffset("X"),"X");
というのをBanYとかに書けば良い。 手動でepsを修正するとか、後からSetTitleOffsetを使って適当に調整しても良いけど。




valgrindによるメモリリークのDEBUG

メモリリークのDEBUGはgdbではやりかたがわからなかったが、valgrindだといとも簡単にわかってしまう。 使い方はこんな感じ。
valgrind --error-limit=no --leak-check=yes --show-reachable=no ./macros/test/test_program 2> var.log

文字数が多いのでターミナルに表示するよりはファイルに書き出してemacsとかで見る方が楽。
気をつけることは、rootのメモリリークを探すときに、
valgrind --error-limit=no --leak-check=yes --show-reachable=no root -l 2> var.log

とやっても内側で打ったコマンドのメモリリークはなぜか探してくれない。
なので、standaloneのプログラムとしてコンパイルし、これをvalgrindに投げる必要がある。
MageFileはこんな感じ。
TARGET = test_program

ROOTCFLAGS  = $(shell root-config --cflags)
ROOTLIBS    = $(shell root-config --libs)
CFLAGS = -I$(TARTSYS)/include -L$(TARTSYS)/lib -lanaroot -lanaanaloop -lXMLParser -g

GXX = g++

all: $(TARGET)

$(TARGET): $(TARGET).C
        $(CXX) $(CFLAGS) $(ROOTCFLAGS) $(ROOTLIBS) -o $@ $^

clean:
        rm -f $(TARGET)
中身はこんなの、
#include "TAlEncExample.hh"
#include "TArtAlias.hh"
#include "TArtAnaLoopManager.hh"
#include "TSystem.h"

int main(int argc, char *argv[]){
  book(new TAlEncExample, "ana/shift.ana");
  push("ridf/sm_dayone/sdaq02/dayone0321.ridf");
  start();
  gSystem->Sleep(10000);
  end();
}

解析開始してから10秒まって終了している。
コツはいきなり全部書かないこと。まずは何もしないmainを買いて、実行してみる。
それでもかなりメモリリークがあるので、まずはlogに目をならす(一度だけ呼ばれるnewはdeleteされなくてもまぁどうでもいい。ここで潰しておくと後でlogが短くなって楽)。
次にgSystem->Sleep(xxx)を増やして行って、logのしたの方にくる奴がloopの中でdeleteされなかった厄介なメモリリークである。
時々deleteされないとかいうのでもまぁ10秒も回せば数kbyteとかになって露見してくる。
ただし、valgrindはかなり処理が遅くて10秒sleepさせるとなぜか1分ぐらい時間がかかる。
あとはlogをみてnewされてるけどdeleteされてない物が見つかるのでコードを読んで問題を理解し潰す。
デバッガ強し。

ちなみに毎loop deleteされないで残っているnewとかはemacsでnewとdeleteを検索した方が早いと思われる。

ANAROOT:libXMLParser.so

ANAROOTで遊んでいるが、libXMLParser.soが入っていないと言って怒られる。
http://root.cern.ch/phpBB3/viewtopic.php?f=3&t=10778

を読む限りでは、libxml2とlibxml++*-devを先に入れて、
さらに、ROOTのコンパイルの時に、
linux --prefix=/usr/local --enable-minuit2 --enable-glite --enable-dcache --enable-memstat
--enable-xml --enable-xrootd --enable-tmva --enable-reflex --enable-castor

と、ばこばこいろいろenableにしないといけないっぽい。
yumでも入るっぽいがそれはやりたくないよね。

さらに、64bitだとX11回りのディレクトリがそのまんまでは見えなかったりする。
configureのオプションに、--with-x11-libdir=/usr/lib64とか指定すれば一応何とかなるっぽい。
あー、configureのhelpを読むと、linuxのx86-64bitの場合の指定があるじゃん。
./configure linuxx8664gcc ....
と環境を明示的に書けばいちいちlib64とか指定しなくていけるのね。

xlsxからxmlを作るときのなぞ

今はxml toolsっていうアドオンを使っているが、xmlとする範囲を選択する時に、
セルの右下にコピペの矢印があるとエラーを吐くっぽい。
なんで、余分に下の方までコピーして矢印がない範囲を選択するとなんかいける。

xlsx to xml

anarootではパラメータファイルをxmlで扱っている。
これはexcel等で簡単に編集でき、且つ読み込みも確立したライブラリを使って簡単?に読み込めるからと考えられる。
で、xmlでどうやって吐くのか、そのログ(まだエラーで止まってる)。

1. アドオンが必要
http://office.microsoft.com/ja-jp/excel-help/HA010342365.aspx

2. 開発タブを見えるようにする(適当に検索すれば見つかる)。

3. 何かコードに変更がある(名前が変わった)らしいので直す。
http://office.microsoft.com/en-us/excel-help/create-an-xml-data-file-and-xml-schema-file-from-worksheet-data-HA010342365.aspx

4. よくわからんエラーが出て死亡。→ 違うマスにコピペ(値のみコピー)したらエラーがでなくなった。

excelでの編集は便利だけど何か癖がある。linux上ではサクッと編集できるのかな?