Problem loading files through a python extension

Hello,

I have been writing a python extension to add ORCA support to Avogadro. The extension so far consists of a input generator, which works nicely, and an output-file reader, which I can’t seem to get to work satisfactorily.

The dialog for the output reader is working nicely, but I have become a bit stuck when it comes to making the extracted molecular geometries visible in the GLWidget.

Initially my approach was to extract the coordinates into lists, where the first item was a string that acted as a “title” for that set of coordinates (for example, “OPT CYCLE 5” or “SINGLE POINT”), followed by a list for every atom, consisting of its atomicNumber as an int and x, y, z coordinates as floats.

This was then translated into Avogadro with the function below:

@pyqtSignature("")
def renderCartesians(self):
    molecule = Avogadro.molecules.addMolecule()
    atom_index = 0
    for info in self.cartesians[-1][1:]:
        molecule.addAtom()
        molecule.atom(atom_index).atomicNumber = info[0]
        molecule.atom(atom_index).pos = numpy.array(info[1:])
        atom_index += 1
    self.glwidget.molecule = molecule

This seemed to work, except that the molecule only consists of atoms (no bonds), and does not seem to be recognised by any of avogadro’s other extensions or plugins.

To avoid using the openbabel python bindings, my solution to the bond problem was to extract the coordinates and format them as a string in the .xyz format; then create a temporary .xyz file, write the coordinates to the file and read them back into Avogadro using MoleculeFile.readMolecule():

@pyqtSignature("")
def renderCartesians(self):
    tempxyz = tempfile.NamedTemporaryFile(suffix=".xyz")
    tempxyz.write(self.cartesians_xyz[-1])
    tempxyz.seek(0)
    molecule = Avogadro.MoleculeFile.readMolecule(tempxyz.name)
    tempxyz.close()
    self.glwidget.molecule = molecule

This procedure seemed to work when I tried it in the avogadro python terminal (although the molecule is still not recognised by the other plugins) but when implemented, as shown above, through my Extension script, Avogadro just crashes when the line “self.glwidget.molecule = molecule” is executed.

I feel like I should be using setMolecule(), but I am not sure how to use it.

I have also been reading about “Avogadro::Extension::moleculeChanged”, but this does not seem to be included in the python Extension class.

Does anyone have any tips on how to render a molecule object and have it recognised by the other avogadro plugins (Such as View>Properties>Molecular properties…)? I am using Avogadro 1.1.0 on Mac OS X 10.8.

thanks,

Nick

Hi,

On Thu, Mar 7, 2013 at 3:20 PM, Mason, Nicholas
nicholas.mason08@imperial.ac.uk wrote:

Hello,

I have been writing a python extension to add ORCA support to Avogadro. The
extension so far consists of a input generator, which works nicely, and an
output-file reader, which I can’t seem to get to work satisfactorily.

The dialog for the output reader is working nicely, but I have become a bit
stuck when it comes to making the extracted molecular geometries visible in
the GLWidget.

Initially my approach was to extract the coordinates into lists, where the
first item was a string that acted as a “title” for that set of coordinates
(for example, “OPT CYCLE 5” or “SINGLE POINT”), followed by a list for every
atom, consisting of its atomicNumber as an int and x, y, z coordinates as
floats.

This was then translated into Avogadro with the function below:

@pyqtSignature("")
def renderCartesians(self):
    molecule = Avogadro.molecules.addMolecule()
    atom_index = 0
    for info in self.cartesians[-1][1:]:
        molecule.addAtom()
        molecule.atom(atom_index).atomicNumber = info[0]
        molecule.atom(atom_index).pos = numpy.array(info[1:])
        atom_index += 1
    self.glwidget.molecule = molecule

This seemed to work, except that the molecule only consists of atoms (no
bonds), and does not seem to be recognised by any of avogadro’s other
extensions or plugins.

To avoid using the openbabel python bindings, my solution to the bond
problem was to extract the coordinates and format them as a string in the
.xyz format; then create a temporary .xyz file, write the coordinates to the
file and read them back into Avogadro using MoleculeFile.readMolecule():

@pyqtSignature("")
def renderCartesians(self):
    tempxyz = tempfile.NamedTemporaryFile(suffix=".xyz")
    tempxyz.write(self.cartesians_xyz[-1])
    tempxyz.seek(0)
    molecule = Avogadro.MoleculeFile.readMolecule(tempxyz.name)
    tempxyz.close()
    self.glwidget.molecule = molecule

This procedure seemed to work when I tried it in the avogadro python
terminal (although the molecule is still not recognised by the other
plugins) but when implemented, as shown above, through my Extension script,
Avogadro just crashes when the line “self.glwidget.molecule = molecule” is
executed.

This is just using Open Babel under the covers to read and perceive bonds.

I feel like I should be using setMolecule(), but I am not sure how to use
it.

I have also been reading about “Avogadro::Extension::moleculeChanged”, but
this does not seem to be included in the python Extension class.

This is what I added to allow for extensions to read molecules, the
problem was that we needed to be able to inform the GUI there was a
new molecule and emitting a signal was the best solution I found. I
never thought, or got around to, adding this to the Python wrapping.

Does anyone have any tips on how to render a molecule object and have it
recognised by the other avogadro plugins (Such as View>Properties>Molecular
properties…)? I am using Avogadro 1.1.0 on Mac OS X 10.8.

Either writing the extension in C++, or we could look at extending the
Python API to support this signal. It has been a while, but I might be
able to find some time to take a look at extending (although I never
did much of the work on the SIP layer that this needs - I think that
was Tim).

Marcus

I have been writing a python extension to add ORCA support to Avogadro. The extension so far consists of a input generator, which works nicely, and an output-file reader, which I can’t seem to get to work satisfactorily.

Sorry for the delay, I think both Marcus and I have been a bit swamped recently. I’d love to see an ORCA reader to Open Babel. Would you be willing to work with me on porting your Python reader to C++?

The point you raised is a good one, and needs to be addressed, but we can also quickly get ORCA working through Open Babel as well.

Cheers,
-Geoff