How do I pass over an error in pymol/python?

1.2k views Asked by At

I'm trying to find the distances between residues of a protein in pymol using a python script, which calls the pymol command cmd.get_distance. However, sometimes there are multiple atom assignments, which causes an error:

GetDistance-Error: Selection 2 doesn't contain a single atom/vertex.

I want to skip over sites that have this problem so I'm trying to use try/pass:

try:
    cmd.get_distance(atom2)
except GetDistance-Error:
    pass

However, it tells me that there is no such error message:

NameError: global name 'GetDistance' is not defined.

How do I tell it to pass this error? isn't GetDistance-Error the error?

2

There are 2 answers

0
pippo1980 On

my attempt :

import pymol

from pymol import cmd, CmdException


print(' pymol version : ', pymol.cmd.get_version())


# pymol.finish_launching()


# cmd.feedback( "disable" , "all" , "errors")  # funziona !!!!!!!!!!!!!!!!!!!!!  removes print di errors



cmd.load('2p09.pdb' , '2p09')

cmd.select('all_waters', 'resn HOH')

cmd.remove('all_waters')


cmd.select('atom1', 'resi 16  and name CA')


try:
    a = cmd.get_distance('atom1')



except Exception as e:
    
    print('e ---------------> ',e ,' type ---> ', type(e))
    print('e.message ---> ',e.message)
    
    
try:
    a = cmd.get_distance('atom1')


except CmdException as e:
    
    
    print('e ---------------> ',e ,' type ---> ', type(e))
    
    print('e.message ---> ',e.message)
    
    print('e.label ---> ',e.label)
    
    print('e.traceback ---> ',e.__traceback__)
    
    
    print('e.with_traceback  ---> ',e.with_traceback(e.__traceback__) )

output:

 pymol version :  ('2.3.0', 2.001, 2001000, 1582201323, '', 0)
 PyMOL not running, entering library mode (experimental)
Selector-Error: Invalid selection name "pk2".
pk2<--
GetDistance-Error: Selection 2 invalid.
e --------------->   Error:   type --->  <class 'pymol.CmdException'>
e.message --->  
Selector-Error: Invalid selection name "pk2".
pk2<--
GetDistance-Error: Selection 2 invalid.
e --------------->   Error:   type --->  <class 'pymol.CmdException'>
e.message --->  
e.label --->  Error
e.traceback --->  <traceback object at 0x7efd34e6d680>
e.with_traceback  --->   Error: 

Note that :

Selector-Error: Invalid selection name "pk2".
pk2<--
GetDistance-Error: Selection 2 invalid.

printing depends on cmd.feedback( "disable" , "all" , "errors") being coomented/uncommented out.

trying redirect both stdout and stderr with from contextlib import redirect_stdout, redirect_stderr won't result in same effect of cmd.feedback( "disable" , "all" , "errors") being uncommented out; possibly because of:

Note that the global side effect on sys.stdout means that this context manager is not suitable for use in library code and most threaded applications. It also has no effect on the output of subprocesses. However, it is still a useful approach for many utility scripts.

see: https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout

I believe somehow CmdException are not loaded at least for get_distance command

0
Ravnclaw On

I stumbled over the same issue. I want to catch the error from pymols cmd.get_distance. In my case, one (or both) of the selections does not contain an atom at all (instead of 2).

This answer will not clarify handling error in pymol scripting but resolve the issue itself.

So instead of catching the error, you could check before if there is exactly 1 atom in your selection.

Erroneous code:

PyMOL>dist = cmd.get_distance("///A/44/CA","///A/60/CA")
GetDistance-Error: Selection 1 doesn't contain a single atom/vertex.

Optimized code:

PyMOL>p1 = cmd.select("p1","///A/44/CA")
PyMOL>p2 = cmd.select("p2","///A/60/CA")
PyMOL>dist = "N/A"
PyMOL>if p1 == 1 and p2 == 1: dist = cmd.get_distance("p1","p2")

So instead of catching the error, you check the requirements (one atom per selection) for the get_distance command. If you run a continuous code, the dist = "N/A" is needed, otherwise you will falsely get the last assignment of the distance.