3

ipythonノートブックでROOTファイルを操作しようとしています(ここのROOTは、Pythonインターフェースを備えたCERNのROOTデータ分析プログラムです)。ROOT の厄介な機能の 1 つは、多くの場合、出力を文字列として返すのではなく、stdout に直接送信することです。この出力を結果として ipython ノートブックに表示するために、次のように少し書きましたcell_magic

  • ROOT に stdout をファイルにリダイレクトするように指示します。
  • セルで python コマンドを実行します
  • ROOT の出力リダイレクトをオフにします
  • ファイルを読み取り、内容を出力します

これが私の小さなセルマジックコードです

import tempfile
import ROOT
from IPython.core.magic import register_cell_magic

@register_cell_magic
def rootprint(line, cell):
  """Capture Root stdout output and print in ipython notebook."""

  with tempfile.NamedTemporaryFile() as tmpFile:

    ROOT.gSystem.RedirectOutput(tmpFile.name, "w")
    exec cell
    ROOT.gROOT.ProcessLine("gSystem->RedirectOutput(0);")
    print tmpFile.read()

このコードを ipython ノートブック セルに入れて実行すると、うまくいきます。例えば、

In [53]: f = ROOT.TFile('myRootFile.root')   # Load the Root file


In [54]: %%rootprint
         f.ls()  # Show the contents of the ROOT file

         ... f.ls() output appears here - yay! ...

通常、 の出力はf.ls()stdout に送られ、セルの結果として表示されません。しかし、このセル マジックを使用すると、出力がセルの結果に表示されます。それは素晴らしいです!

しかし、セル マジック コードをモジュールに入れると、機能しません。たとえば、上記のコードをノートブックに入れipythonRoot.py、実行します。import ipythonRoot.py上記のセルを実行しようとすると、定義されていない%%rootprintというエラーが表示されます。行を にf変更しようとしましたが、それは役に立ちませんでした。execexec cell in globals()

これを行う方法はありますか?また、cell_magic関数を記述するためのより良い方法はありますか (たとえば、印刷する代わりに出力を返す必要があります)。助けてくれてありがとう!

4

2 に答える 2

5

そこで、IPython コードを見てこれを理解しました。具体的には IPython/core/magics/execution.py にいくつかのヒントがありました。これが私の新しいモジュールです

import tempfile
import ROOT
from IPython.core.magic import (Magics, magics_class, cell_magic)

@magics_class
class RootMagics(Magics):
  """Magics related to Root.

      %%rootprint  - Capture Root stdout output and show in result cell
  """

    def __init__(self, shell):
      super(RootMagics, self).__init__(shell)

  @cell_magic
  def rootprint(self, line, cell):
    """Capture Root stdout output and print in ipython notebook."""

    with tempfile.NamedTemporaryFile() as tmpFile:

      ROOT.gSystem.RedirectOutput(tmpFile.name, "w")
      ns = {}
      exec cell in self.shell.user_ns, ns
      ROOT.gROOT.ProcessLine("gSystem->RedirectOutput(0);")
      print tmpFile.read()

# Register
ip = get_ipython() 
ip.register_magics(RootMagics)

Magicsクラスとshell、特にノートブックの名前空間を保持する属性の使用に注意してください。これは定期的にインポートでき、正常に動作します。

于 2013-02-23T14:37:51.373 に答える
1

私の理解が正しければ、magic/alias/user 名前空間は分離されています。「インポート」を実行しても、マジック/エイリアスの名前空間に干渉しません。これが %load_ext マジックがある理由ですが、エントリ ポイントを定義する必要があります。【Rマジックでの例】.( https://github.com/ipython/ipython/blob/master/IPython/extensions/rmagic.py#L617 ).

また、一時ファイルなしで stdout/err をキャプチャするキャプチャ マジックとして見ることをお勧めします。

これが機能したら、拡張機能インデックスに拡張機能を追加することもできます

于 2013-02-23T10:03:34.410 に答える