【ROOT】ROOTをコンパイルして使う

Pythonでは遅い、rootでインタラクティブに実行しても遅い。みたいな時にはやはりコンパイルして実行するのが一番です。

はじめに

重たい処理を素早く実行したいのであればコンパイルして実行するのが一番です。

長々としたはじめに

ROOTはC++でマクロが記述されることがほとんどですが、稀にPythonで書いて実行するPyROOTの使い手もいます。(私は訳があって両方を使い分けていますが…)

Python堅苦しい記法ではなく書きやすく、もっと言えばコーディングにかかる時間が短くて済むという長所があると思います。
しかし、短所は実行速度は遅いこと、特にloopの回数が増せば増すほど遅いです。ネストなんてしたらとんでもないことになります。
これは主に型の宣言が不要というところが効いており、loopを回すたびに変数の型を判断しているという影響がある
もちろんPyPyやCython、Numbaを活用するといったテクニックもありますが、今回は省きます。
その他Pythonで処理を高速にするテクニックは存在します。PythonのライブラリはC/C++で書かれているので時間のかかる処理でライブラリをうまく活用するといったことがその例です。

が、純粋にC++で実行する方が圧倒的に速い。
ROOTでは実装されているClangのおかげでインタラクティブC++のコードを書くことができます。
ですが、本当に速度を求めるのであれば一度コンパイルして実行するとよいでしょう。

ROOTのマクロをコンパイルして実行する。

コンパイルは以下のように行います。

$ g++ macro.C -o macro `root-config --cflags --libs'`
$ ./macro

optionでROOTのライブラリを引っ張ってきているという事ですね。


コンパイル用のコマンドを作る

その都度

$ g++ macro.C -o macro `root-config --cflags --libs'`

なんてオプションをずらずら書くなど馬鹿らしい。
という事で、shell scriptを実行するコマンドを作ります。

以下のよう"rt++.sh"を記述。

#!/bin/bash
g++ $@ 'root-config --cflags --libs'

ファイルのに実行権限を与えます。

$ chmod 777 rt++.sh

.bashrcにはaliasを追加しましょう。

alias rt++="$HOME/sh/rt++.sh"

以上で完了。
ターミナルを立ち上げなおせば”rt++”でコンパイルができます。

errorが出てしまう場合

場合によっては以下のようなerrorが返ってくることがあります。
私の場合は別環境でコンパイルしようとしたときに起こりました。

$ rt++ macro.C 
g++: error: root-config --cflags --libs: No such file or directory

しかし、次のようにコンパイルに必要なライブラリを次のコマンドで出力させると、正常に出力されることがわかります。

$ root-config --cflags --libs
-pthread -std=c++11 -m64 -I/usr/local/root-6.18.00/mybuild/include -L/usr/local/root-6.18.00/mybuild/lib -lCore -lImt -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lROOTVecOps -lTree -lTreePlayer -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lMultiProc -lROOTDataFrame -pthread -lm -ldl -rdynamic


結論ですが、解決策は次のURL
stackoverflow.com
これによると、shell scriptの中のライブラリを引っ張るところの記述に誤りがあるようです。$を用いてライブラリを引数にすればいいわけですね。
(おかしい、ubuntu18.04では動いていたんだけどなぁ)

shell scriptを次のように書き換えました。

#!/bin/bash
g++ $@ $(root-config --cflags --libs)