2

语境:

我正在实现一个名为 LCIO 的粒子物理库,它是 C++ 代码,但是有一个名为 pyLCIO 的 python 包装器。

当尝试运行一个名为setMomentum()C++ 的函数时,实现如下所示:

void    setMomentum (const float p[3])

简单的浮点数组。

好的python,让我们试试这个:

 particle.setMomentum([1.0,2.0,3.0])

问题:

现在这引发了一个错误。这是回溯:

Traceback (most recent call last):
  File "driver.py", line 5, in <module>
    particle.setMomentum(momentum)
  File "/path/to/pyLCIO/base/HandleExceptions.py", line 17, in wrappedMethod
    return method(*args, **kargs)
TypeError: none of the 2 overloaded methods succeeded. Full details:
  void MCParticleImpl::setMomentum(const float* p) =>
    could not convert argument 1
  void MCParticleImpl::setMomentum(const double* p) =>
    could not convert argument 1

现在这个函数要求一个#1 常量,#2 是对数组头部的引用。我应该如何用 python 做到这一点?

有没有使用 python 包装的 C++ 代码经验的人,知道如何const float*在 python 中创建一个?

感谢您的任何帮助。

编辑 180314

我试过了:

particle.setMomentum((1.0,2.0,3.0))

无济于事;同样的错误。

4

2 回答 2

1

我给开发者发了电子邮件,这是回复。

使用 swig 的 LCIO 的 python 绑定很久以前就停止了,它们与 pyLCIO 无关,因此您找到的文档不相关。

pyLCIO 构建在 pyROOT 绑定之上,利用 LCIO 提供的 ROOT 字典,允许将 LCIO 对象直接存储在 ROOT 文件中。这些字典还隐式地为所有类提供 python 接口。在 pyROOT 中,c 样式的数组(或任何其他指向基本类型的指针)必须作为相应类型的 python 数组或 numpy 数组传递(例如,参见https://root.cern 中的“19.1.9.2 编写树”。 ch/root/htmldoc/guides/users-guide/ROOTUsersGuide.html#using-pyroot)。(另外,您应该使用 IMPL.MCParticleImpl 手动构建 MCParticles,请参阅http://lcio.desy.de/v02-09/doc/doxygen_api/html/classIMPL_1_1MCParticleImpl.html。IOIMPL 版本仅添加了来自 SIO 的构造函数从 LCIO 文件中读取它所需的流)。

在这种情况下,你应该做

from pyLCIO import IMPL
from array import array
particle=IMPL.MCParticleImpl()
p = array('f', [1.0, 2.0, 3.0])    # the type ‘f’ has the length of a C++ float, for a double use ‘d'
particle.setMomentum(p)

由于我从不喜欢 LCIO 的设计选择将物理向量作为 c 样式数组传递,因此我扩展了 pyLCIO 中的所有类接口以支持 ROOT 物理向量 (TVector3) 的使用。所有实际上是物理向量的 setter 和 getter 都有另一个称为 setXxxVec() 或 getXxxVec() 的版本,它们接受或返回物理向量。如果一个对象有 getEnergy 和 getMomentum 它也将在 pyLCIO 中有 getLorentzVec,它返回一个 ROOT TLorentzVector 对象。有关扩展接口,请参阅https://github.com/iLCSoft/LCIO/blob/master/src/python/pyLCIO/base/DecorateLcioClasses.py。所以在你的例子中你也可以使用

from pyLCIO import IMPL
from ROOT import TVector3
particle=IMPL.MCParticleImpl()
p = TVector3(1.0, 2.0, 3.0)
particle.setMomentumVec(p)

由于您正在尝试创建 LCIO 文件,您可能会发现此示例很有用https://github.com/iLCSoft/LCIO/blob/master/examples/python/EventBuilder.py。事实上,它已经包含了一个如何创建 MCParticle 对象的示例。请查看其他示例以及如何使用 pyLCIO。

于 2018-03-15T20:14:55.547 回答
1

基于http://lcio.desy.de/v01-07/src/python/lcio_swig.i,看起来他们使用元组而不是数组来表示 3 个元素向量。

您应该能够执行类似 'particle.setMomentum((1.0, 2.0, 3.0))' 的操作并让它工作。同样,getMomentum 将返回一个 3 元素元组。

于 2018-03-15T00:04:27.880 回答