2

Context:

I am implementing a particle physics library called LCIO that is C++ code, but there is a python wrapper called pyLCIO.

When trying to run a function called setMomentum() the C++ implementation looks like this:

void    setMomentum (const float p[3])

Simple float array.

Alright python, lets try this:

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

The problem:

Now this threw an error. Here is the traceback:

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

Now this function is asking for a #1 constant, #2 the reference to the head of the array. How am I supposed to do this with python?

Does anyone with exerience with python wrapped C++ code, know how to creade a const float* in python?

Thank you for any help.

EDIT 180314

I tried:

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

To no avail; same error.

Tsangares
  • 780
  • 1
  • 9
  • 27

2 Answers2

1

Based on http://lcio.desy.de/v01-07/src/python/lcio_swig.i, it looks like they use tuples rather than arrays to represent the 3 element vectors.

You should be able to do something like 'particle.setMomentum((1.0, 2.0, 3.0))' and have it work. Likewise, getMomentum would return a 3 element tuple.

Charlie
  • 1,487
  • 10
  • 9
  • I see that comment in the document you referenced. Thank you so much for finding that! It did not work however, even though that document and Swig both say the tuple should work. I sent some guy at CERN an email asking about this. – Tsangares Mar 15 '18 at 02:28
  • This seems more on the right track than using c_types. – Tsangares Mar 15 '18 at 02:29
1

I emailed the developer and this was the response.

the python bindings for LCIO using swig have been discontinued a long time ago and they have nothing to do with pyLCIO, so that document you found is not relevant.

pyLCIO builds on top of the pyROOT bindings, making use of the ROOT dictionaries provided with LCIO that allow to store LCIO objects directly in ROOT files. These dictionaries also implicitly provide python interfaces to all classes. In pyROOT c-style arrays (or any other pointer to basic types) have to be passed as python arrays or numpy arrays of the corresponding type (see for example "19.1.9.2 Writing a Tree" in https://root.cern.ch/root/htmldoc/guides/users-guide/ROOTUsersGuide.html#using-pyroot). (Also, you should use IMPL.MCParticleImpl to construct MCParticles by hand, see http://lcio.desy.de/v02-09/doc/doxygen_api/html/classIMPL_1_1MCParticleImpl.html. The IOIMPL version only adds a constructor from an SIO stream which is needed to read it from an LCIO file).

In this case you should do

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)

Since I never liked the design choice of LCIO to pass physics vectors as c-style arrays I extended all class interfaces in pyLCIO to also support the usage of ROOT physics vectors (TVector3). All setters and getters that are in fact physics vectors have another version called setXxxVec() or getXxxVec() which accept or return physics vectors instead. If an object has getEnergy and getMomentum it will also have getLorentzVec in pyLCIO which returns a ROOT TLorentzVector object. See https://github.com/iLCSoft/LCIO/blob/master/src/python/pyLCIO/base/DecorateLcioClasses.py for the extended interfaces. So in your example you could also use

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

Since you are trying to create LCIO files you might find this example useful https://github.com/iLCSoft/LCIO/blob/master/examples/python/EventBuilder.py. In fact it already contains an example of how to create MCParticle objects. Please have a look at the other examples as well for how to use pyLCIO.

Tsangares
  • 780
  • 1
  • 9
  • 27