Mac で root_numpy をインストールする苦悩

# 概要
かなりの時間をかけて、ようやく使えるようにした root_numpy。この root_numpy は Python 使い (Python以外使いたくない、なるべくPythonを使いたい人) にとっては大変ありがたい存在です。
巷には PyROOT や rootpy がありますが、これらは結局 全然 Python 使っている感じがありません (ROOT を使っている感じがものすごくします 笑)。下の例を見てもらえば一目瞭然だと思います。

- PyROOT の活用例：

```
>>> from ROOT import gROOT, TCanvas, TF1
>>> gROOT.Reset()
>>> c1 = TCanvas( 'c1', 'Example with Formula', 200, 10, 700, 500 )
>>> fun1 = TF1( 'fun1', 'abs(sin(x)/x)', 0, 10 )
>>> c1.SetGridx()
>>> c1.SetGridy()
>>> fun1.Draw()
>>> c1.Update()
```
(上の例文は [PyROOT 公式サイト](https://root.cern.ch/pyroot)より引用しました。)

- rootpy の活用例：

```
>>> from rootpy.plotting import Hist2D
>>> hist = Hist2D(10, 0, 1, 5, 0, 1, type='F')
>>> hist.__class__.__bases__
```
(上の例文は [rootpy の公式サイト](http://www.rootpy.org)より引用しました。)

上の2つの例文を見て、皆さんきっとこう思うことでしょう。

**もはや ROOTじゃん！！**


きっと生粋の Python 使い (Python を意地でも使いたい人) は **ROOT で読み込んだデータを Python らしく処理したい**はずです。

そのための解決法として、 **root_numpy** という素晴らしいライブラリがあります。この中に、読み込んだツリーを ndarray に変換する素晴らしい関数 (**tree2array**) があります。
これにより、ROOTファイルのデータを ndarray に変換し、あとはいつも通り Python らしく処理することができるというわけです。

つまり、Python 使いの ROOT データの扱いはこうなります。
1) root ファイルを PyROOT で読み込む
2) 読み込んだ root データ(tree) を、root_numpy で ndarray に変換する
3) あとはいつも通り pythonic に処理する

さて、早速 root_numpy のインストールを始めましょう。
（ここからが険しい道であった...）

# インストール環境

- Mac OS High Sierra 10.13.6
- ROOT 6.14/04 (2018.10.7時点で最新バージョン)

ROOT と Geant4 のインストールに関しては、以下を参考にしてください。
ROOT インストール: [「ROOT, PyROOT, rootpy の Macへのインストレーション」](http://osksn2.hep.sci.osaka-u.ac.jp/~taku/osx/install_root.html)

以下では、ROOT やその関連のPATH は上のURLでダウンロードする PATH になっているので、適宜読み替えてください。

# インストール手順

## 1. システム python を使用する

まず、注意しなければならないのは、**PyROOT や root_numpy を使う際には、システム(OS標準)のpython (/usr/bin/python) を使用しなければなりません**。

まず、どの python を使っているか、```which python```で調べます。

```
$ which python
/usr/bin/python
```

これで、もし/usr/local/bin/python あるいは 他の python の path が表示される場合には、以下を試してみてください。

### A: /usr/local/bin/python 
```which python```でこの表示が出る場合は .bash_profile での PATH 設定で、/usr/bin より/usr/local/bin が優先される形になっています。
PATH の優先順位は、早く追加されたものが優位になるので、.bash_profile において、/usr/bin を /usr/local/bin より先に書くようにします (例1あるいは例2を参照)。

例1：

```~/.bash_profile
export PATH=/usr/bin:/usr/local/bin:$PATH
```

例2：

```~/.bash_profile
export PATH=/usr/bin:$PATH
...
export PATH=/usr/local/bin:$PATH
```

### B: ~/.pyenv/shims/python

~ は、/Users/(ユーザ名)で読み替えてください。
このような表示が出るのは、pyenv を使って複数の python 環境を用途に合わせて使用している場合だと思います。

この場合、スマートなやり方はわかりませんでしたが、root_numpy などをインストールする前に、とりあえず**.bash_profile にある pyenv に関する PATH を全部コメントアウトしてください**（後からコメントアウトを解除して、以前通り pyenv が使えるように戻しますので）。

そして、もう一度 ```which python``` をして、どこの python に繋がっているか確認してください。もし /usr/local/bin/python が表示されたら、A と同じことを行います。

### C. 他の事例

例えば、anaconda を直接インストールして使っている人などはこちらに該当します。この場合は、B と同様に.bash_profile において、該当する PATH をコメントアウトしてください。そして、もう一度 ```which python``` をして、どこの python に繋がっているか確認し、もし /usr/local/bin/python が表示されたら、A と同じことを行います。
（ただし、この場合は**直接インストールした anaconda の環境から PyROOT や root_numpy は使えない**ので、個人的には pyenv でシステム python (/usr/bin/python) と他の環境 (anaconda, etc) を使い分けられるようにしておくことをオススメします（いずれその方法も説明したいと思います）。）

```which python``` で /usr/bin/python が表示されるようになってから、次に進みます。

## 2. ROOTSYS と PYTHONPATH を確認する

### ROOTSYS

もし、ROOT を 上のURL[「ROOT, PyROOT, rootpy の Macへのインストレーション」](http://osksn2.hep.sci.osaka-u.ac.jp/~taku/osx/install_root.html) 通りにインストールしているならば、以下のように表示されます。

```
$ echo $ROOTSYS
/Users/(ユーザ名)/local/root/pro
```

あるいは、Homebrew を使ってインストールした人は、

```
$ echo $ROOTSYS
/usr/local/Cellar/root/HEAD/lib/root
```

が表示されます（上のはHEADの部分は色々書いてあるかもしれない）。

このどちらも表示されない場合には、きっと thisroot.sh の設定がなされていないはずです。その場合には、以下を.bash_profileに追記してください。

- 上のURL通り(~/local/root)に ROOT をインストールした場合

```~/.bash_profile
source ~/local/root/pro/bin/thisroot.sh
```

- Homebrew(/usr/loca/Cellar/HEAD/lib/root)で ROOT をインストールした場合 

```~/.bash_profile
source /usr/local/bin/thisroot.sh
```
### PYTHONPATH 

ROOTSYS の設定の確認が終わったら、次に PYTHONPATH も確認してください。

```
$ echo $PYTHONPATH
/Users/(ユーザ名)/local/root/pro/lib/root
```

あるいは

```
$ echo $PYTHONPATH
/usr/local/Cellar/root/HEAD/lib/root
```

きっと、$ROOTSYS/lib/root のような path が表示されるはずです。

ちなみにこの時点で、PyROOT は使えるようになっているはずです。ターミナルで以下のコマンドを打つと確認できます。

```
$ python -c 'import ROOT'
```
何もエラーが返ってこなければ、ライブラリインポートが正常に行えたことを意味しているので、PyROOT が使えるようになっています。

## 3. pip で root_numpy をインストールする

まず、pip をインストールします。

```
$ sudo easy_install pip
```
次に、numpy と root_numpy を同時にインストールします。先に numpy がインストールされている場合もあるので、先に両方とも完全にアンインストールしておきます（インストールされてなければ、されてないと返ってくるはずですが無視して大丈夫です）。

```
$ pip uninstall numpy root_numpy 
$ pip install --upgrade --ignore-installed --no-cache-dir numpy root_numpy
```

**備考）なぜ、pip install root_numpy をしないのか**
どのブログも、```pip install --user root_numpy``` あるいは、```sudo ROOTSYS=$ROOTSYS pip install root_numpy``` など、root_numpy 単体でインストールを行っているが、その場合、```ImportError: cannot import name _librootnumpy```というエラーが発生した（少なくとも、私のPCでは）。したがって、そのようなエラーを回避するために、ここでは上のやり方を取っている。
参考ページはこちら->[「Problem with import root_numpy #315」](https://github.com/scikit-hep/root_numpy/issues/315)

## 4. 仕上げ（ここがみそ！）

ほとんどのブログも、3. まで行ったら、root_numpy が使えると書いてあったが、そんな嘘だ！（とりあえず、私の Mac ではエラーが出ました）

root_numpy が import できるか ```python -c```確認してみてください。きっと次のようなエラーが表示されることでしょう。（そしてエラーが何も出ないラッキーな人は、以下の動作は不要です）

```
$ python -c 'import root_numpy'
Traceback (most recent call last):
...
ImportError: dlopen(/Library/Python/2.7/site-packages/root_numpy/_librootnumpy.so, 2): Library not loaded: @rpath/libHist.so
  Referenced from: /Library/Python/2.7/site-packages/root_numpy/_librootnumpy.so
  Reason: image not found
```

このエラーが出たアンラッキーな人も心配無用です。以下のコマンドを一度打てば解決できることでしょう。（これを見つけるのに時間がかかりました。。）

```Terminal
$ sudo install_name_tool -add_rpath $ROOTSYS/lib/ /Library/Python/2.7/site-packages/root_numpy/_librootnumpy.so
```

このエラーの参考ページはこちら->[「root_numpy 4.7.3 no macOS 10.13.1」](http://iruata.blogspot.com/2018/02/rootnumpy-473-no-macos-10131.html)。

## 5. 最後に、pyenv ユーザへ

ここまでうまくいったなら、.bash_profile でコメントアウトした、pyenv 関係のpath を元の設定に戻し、source .bash_profile してください。

次回以降、PyROOT および root_numpy を使いたいときは、システム Python を使えば良いので、作業ディレクトリで

```Terminal
$ pyenv local system
```

を打てば、システム python で、PyROOT と root_numpy が使えるようになります。

---

以上になります。
質問などあれば気軽にご連絡ください。
(2018.10.7 作成)