physpolyglot

主にPC関連の自分用メモのうち、役立ちそうなものを共有します。

TTreeFormulaの使い方

自分用メモ。適宜加筆する予定。コードはコンパイルチェックしてません。

目的

TTreeに格納されている数字から任意(限界は?)の計算を行う。

使用法(例)

コンストラクタ

TTreeFormula *formula = new TTreeFormula("formula_name","branch.fValue", tree);

値を読み出してヒストグラムにFillする

インスタンスが1つの場合

branch.fValueを適当なヒストグラムにFillする。 その際anotherBranch.fValue > 0という制限をかける。

TTreeFormula *formula = new TTreeFormula("formula_name","branch.fValue", tree);
TTreeFormula *selection = new TTreeFormula("selection_name","anotherBranch.fValue > 0", tree);
for (Long64_t iEvent = 0, nEvent = tree->GetEntries(); iEvent != nEvent; ++iEvent) {
   tree->LoadTree(iEvent);
   if (selection->EvalInstance()) {
      h->Fill(formula->EvalInstance());
   }
}

よく分かっていないところ

TTreeFormulaManager::Syncの働き

xargsに空文字列が渡ったときのMacとLinuxでの挙動の違い

今流行りのpecoを使ったシェルコマンドを書いているときに、 xargsが空文字列を受け取ったときの挙動がMacScientific Linux(以降SL)で違って戸惑った。

echo | xargs echo "hoge"

としたときにMacは何もエコーされないのに対し、SLだとhogeがエコーされる。

SLでは-rオプションをつけることで、空文字列が渡ってきたときに無視することは出来るが、Macではエラーになってしまう。

http://linuxjm.sourceforge.jp/html/GNU_findutils/man1/xargs.1.html によれば、rオプションはGNUの拡張らしい。

Macにgxargsが(MacPortsで)入っていたのでこれを使うことにする。

zshの補完候補の除外設定

シェルでtabを押すといろいろ補完してくれて便利なのだけど、 Emacsのバックアップファイルとかも補完されてしまってうっとおしいことがある。

zshであれば、除外設定が可能(他のシェルは調べてない)。

zstyle ':completion:*:*files' ignored-patterns '*?~' '*\#'

これを.zshrcにかいておけば、Emacsのバックアップファイルが補完候補からは除外される。

zargsとお手軽並列計算

zargsはxargsのzsh版とでもいうべきもの。
zshの拡張グロブでファイルリストを生成し、それぞれのファイルについて処理を行うことができる。

シェルのグロブパターン*1で長過ぎるファイルリストをコマンドに渡すと、 シェルに怒られてしまい*2処理を実行できないときがある。

そんなときに活躍するのがxargsとかzargsとか。

xargsも便利だとおもうのだけど、findで欲しいファイルを検索してくるのは面倒くさい……。というかfindの使い方覚えてない。
zshの拡張グロブなら直感的にファイルを指定できるので最高です!
従来のシェルと同様のファイル名生成はもちろん、ファイル属性も指定できるし、編集子を使えば拡張子を取り除くなどの簡単な編集さえ出来てしまう……。神!

拡張グロブについてはそのうち自分用メモとしてまとめるつもりです。 *3

zargsを使う場合は、事前にautoloadをしておく。もちろんzsh限定。

autoload zargs

zargsの基本的な使い方はこんな感じ。

zargs OPTIONS -- GLOB -- COMMAND

例えば、

zargs -- some_dir/*.dat -- ./some_program

とするとsome_programの引き数にsome_dir/*.datにマッチする全てのファイルが渡され、 順次実行される。

-Pオプションで並列プロセス数を設定することが出来る。
-P2で2プロセス同時実行とか。
-P0にすると最大のプロセス数が設定される。

zargs -P0 -- some_dir/*.dat -- ./some_program

これで簡単並列処理ができる。本当に簡単。

zargsはシェル配列に入ったものに対しても処理を行うことが出来る。

array=(hoge hige hage)
zargs -P0 -- ${=array} -- ./some_program

=を使ってシェル配列を展開してやればよい。
この例の場合、hoge,hige,hageそれぞれがsome_programに渡される。

コマンドが複数の引数を受け付ける場合にグロブ展開したものを入力する場所を指定したいなら、-iオプションでプレースホルダを指定できる。

-istringとすると(stringは任意の文字列でプレースホルダとなる)、二つ目の--の後でstringの部分にグロブの展開結果が代入される。

zargs -P0 -ifile -- ./*.dat -- ./some_program ${hoge} file ${fuga}

zargsと拡張グロブと何らかの言語のワンライナーを使いこなせれば、 複雑な処理でも1行で簡単に書けてうれしいですね。

*1:アスタリスクとか

*2:Argument list too long

*3:なぜこんな便利な機能なのにネット上にまとめが見つからないのだろうか……