PyROOT で C 配列を使う

なんか毎度やり方を忘れて検索し直すので、本当に自分用の覚え書き。Blog にわざわざ書くネタとしては今さら感があり過ぎますが、ほんと最近物忘れがひどい。

ROOT 自体は C++ で書かれているので、C の配列を引数に持つ関数というのはいくらでもあります。例えば TAxis の constructor なんかがそうです。

TAxis TAxis(Int_t nbins, const Double_t* xbins)

自分で作った FITS 用の library でも、WCS を使って pixel 座標と天空座標の変換をするときなんかも、C の配列を渡してます*1

一方で、Python は C の配列なんて知ったこっちゃないので、PyROOT で C 配列を引数に渡したいときは、少し特殊なことをします。例は次の通り。使っている library は自作のものなので、ROOT.TFitsFile というのは、ROOT 公式には含まれていません。

>>> import ROOT
>>> import array
>>> fits = ROOT.TFitsFile("GLAST/GasData/DHT/Wco_orion_crop.fits.gz") # open a FITS file
>>> pix = array.array("d", [100, 100]) # declare pixel coordinates
>>> sky = array.array("d", [0, 0]) # allocate memory for sky coordinates
>>> wcs = fits.GetImageHDU(0).GetWcs() # Get WCS
>>> wcs.Pix2Sky(pix, sky) # convert pixel coords to sky coords
>>> sky # see the result
array('d', [212.625, -17.625])

同じことを CINT でやると、こんな感じ。

root [0] TFitsFile fits = TFitsFile("GLAST/GasData/DHT/Wco_orion_crop.fits.gz")
root [1] Double_t pix[2] = {100, 100}
root [2] Double_t sky[2]
root [3] TWcs* wcs = fits.GetImageHDU(0)->GetWcs()
root [4] wcs->Pix2Sky(pix, sky)
root [5] sky[0]
(Double_t)2.12625000000000000e+02
root [6] sky[1]
(Double_t)(-1.76250000000000000e+01)

Python array の型についての情報はこちら*2

*1:std::vector とかでも良いかもしれないが。

*2:'d' とか 'i' の話。