4

CERN の pyROOT モジュールを使用していくつかの作業を行っており、文字列の配列をバイナリ ツリーの葉として格納しようとしています。そのためには、明らかに、リストや辞書ではなく配列モジュールを使用して配列を渡す必要があります。このモジュールは、文字、整数などの標準 C 配列をサポートしていますが、文字列の配列、または効果的に文字配列の配列を作成するためにそれらをネストする方法を知っている人はいますか? それとも、行き過ぎたので、しばらくキーボードから離れる必要があります :)?

コード:

import ROOT

rowtree = ROOT.TTree("rowstor", "rowtree")

ROOT.gROOT.ProcessLine(
    "struct runLine {\
    Char_t test[20];\
    Char_t test2[20];\
    };" );
from ROOT import runLine
newline = runLine()
rowtree.Branch("test1", newline, "test/C:test2")

newline.test = ["AbcDefgHijkLmnOp","aaaaaaaaaaaaaaaaaaa"]

rowtree.Fill()

エラー:

python branchtest
Traceback (most recent call last):
  File "branchtest", line 14, in <module>
    newline.test = ["AbcDefgHijkLmnOp","aaaaaaaaaaaaaaaaaaa"]
TypeError: expected string or Unicode object, list found

この例に示されているリストを文字列の配列に変換できるかどうか疑問に思っています。

4

2 に答える 2

3

char 配列と Python 文字列の Python リストは、2 つのまったく異なるものです。

char 配列 (1 つの文字列) を含むブランチが必要な場合は、Python の組み込みbytearray型を使用することをお勧めします。

import ROOT
# create an array of bytes (chars) and reserve the last byte for null
# termination (last byte remains zero)
char_array = bytearray(21)
# all bytes of char_array are zeroed by default here (all b'\x00')

# create the tree
tree = ROOT.TTree('tree', 'tree')
# add a branch for char_array
tree.Branch('char_array', char_array, 'char_array[21]/C')
# set the first 20 bytes to characters of a string of length 20
char_array[:21] = 'a' * 20
# important to keep the last byte zeroed for null termination!
tree.Fill()
tree.Scan('', '', 'colsize=21')

の出力tree.Scan('', '', 'colsize=21')は次のとおりです。

************************************
*    Row   *            char_array *
************************************
*        0 *  aaaaaaaaaaaaaaaaaaaa *
************************************

したがって、ツリーがバイトを正しく受け入れていることがわかります。

文字列のリストを保存したい場合は、次を使用することをお勧めしますstd::vector<std::string>

import ROOT

strings = ROOT.vector('string')()

tree = ROOT.TTree('tree', 'tree')
tree.Branch('strings', strings)
strings.push_back('Hello')
strings.push_back('world!')
tree.Fill()
tree.Scan()

の出力tree.Scan()は次のとおりです。

***********************************
*    Row   * Instance *   strings *
***********************************
*        0 *        0 *     Hello *
*        0 *        1 *    world! *
***********************************

ループstrings.clear()では、次のエントリに文字列の新しいリストを入力する前に行う必要があります。

現在、rootpyパッケージ ( githubのリポジトリも参照) は、Python でツリーを作成するためのより優れた方法を提供します。以下は、rootpy を使用して「より使いやすい」方法で char 配列を使用する方法の例です。

from rootpy import stl
from rootpy.io import TemporaryFile
from rootpy.tree import Tree, TreeModel, CharArrayCol

class Model(TreeModel):
    # define the branches you want here
    # with branchname = branchvalue
    char_array = CharArrayCol(21)
    # the dictionary is compiled and cached for later
    # if not already available
    strings = stl.vector('string')

# create the tree inside a temporary file
with TemporaryFile():
    # all branches are created automatically according to your model above
    tree = Tree('tree', model=Model)

    tree.char_array = 'a' * 20
    # attemping to set char_array with a string of length 21 or longer will
    # result in a ValueError being raised.
    tree.strings.push_back('Hello')
    tree.strings.push_back('world!')
    tree.Fill()
    tree.Scan('', '', 'colsize=21')

の出力tree.Scan('', '', 'colsize=21')は次のとおりです。

***********************************************************************
*    Row   * Instance *            char_array *               strings *
***********************************************************************
*        0 *        0 *  aaaaaaaaaaaaaaaaaaaa *                 Hello *
*        0 *        1 *  aaaaaaaaaaaaaaaaaaaa *                world! *
***********************************************************************

TreeModelここで、rootpy で s を使用する別の例を参照してください。

https://github.com/rootpy/rootpy/blob/master/examples/tree/model_simple.py

于 2013-10-31T22:58:09.047 に答える
0

testa のメンバーrunLineを 20 文字の配列として定義しました。

Char_t test[20];\

しかし、次の 2 つの文字列のリストを渡そうとしています。

newline.test = ["AbcDefgHijkLmnOp","aaaaaaaaaaaaaaaaaaa"]

これは C (または CINT) や Python では意味をなさないので、もちろん PyROOT でも意味がありません。

また、あなたの質問には多くの混乱があるようです。PyROOT に「明らかに、リストや辞書ではなく配列モジュールを使用して配列を渡す必要がある」と言いますが、PyROOT は Pythonarrayモジュールを特に気にしません。これは、「配列モジュール」としてではなく、numpy考えている可能性があることを意味しますが、最後に確認したとき (確かにかなり前のことです)、それらはまったく相互作用しませんでした。PyROOT に渡すことができる何かが必要な場合は、バッファをエクスポートするように numpy に明示的に要求する必要がありました。numpyarray

于 2013-10-30T19:11:28.973 に答える