how to check if file is already loaded in pymol

86 Views Asked by At

I'm writing a python script to run pymol. I want to check if a file is already loaded so I can avoid loading the same molecule again and again.

here's a pseudocode of my idea:

if (file is already loaded on pymol):
   skip to next step
else:
   fetch [filename]

[next step]

how can i implement the first line in python?

1

There are 1 best solutions below

0
pippo1980 On

I think something along the line of

....

from pymol import cmd

....

if filename in [i for i in cmd.get_names(type = 'objects', enabled_only = 0)]:
    skip to next step
else:
    fetch [filename]

[next step]
...

should work, see https://pymolwiki.org/index.php/Get_Names

Regarding loading file from onsite [ think you could apply same logic to pymol.cmd.fetch ] I devised the strategy below:

First I start launching pymol with modified cmd.load and cmd.delete from this file :

import pymol

import os

pymol.finish_launching()

load_old = pymol.cmd.load

loaded = {}

def load(*args, **kwargs):
    
    global loaded   #noy necessary, but needed for def delete()
    
    print('argsz : ', args, type(args), len(args))
    
    if len(args) > 0 :
        
        if len(args[0].rsplit('/' , 1)) > 1:
        
            a, b = args[0].rsplit('/' , 1)
            
        else :
            
            a, b = '' , args[0]
        
        b = b.rsplit('.' , 1 )[0]
        
        print('args[0] : ' , args[0] )
        
        print(' a : ', a , ' b : ', b)
        
        if b in loaded:
            
            if loaded[b] == a:
            
                print(b ,' is already loaded  ')
                
                raise pymol.CmdException(b+' is already loaded ')
                
                return 
            
            elif loaded[b] != a:
            
                print(b ,' is already loaded  from ', loaded[b]  )
                
                if loaded[b] != '' :
                    
                    dire = loaded[b]
                    
                else :
                    
                    dire = os.curdir
                    # dire = os.getcwd() # more usefull
                
                raise pymol.CmdException(b +' is already loaded  from ' + dire)
                
                return 
        
        else: 
        
            loaded[b] = a
            
            load_old(*args, **kwargs)
            
            print('loaded : ', loaded)
        
        
    elif 'filename' in kwargs :
        
        
        if len(kwargs['filename'].rsplit('/' , 1)) > 1:
        
            a, b = kwargs['filename'].rsplit('/' , 1)
            
        else :
            
            a, b = '' , kwargs['filename']
        
        
        b = b.rsplit('.' , 1 )[0]
        
        print('kwargs[filename] : ' , kwargs['filename'])
        
        print(' a : ', a , ' b : ', b)
        
        if b in loaded:
            
            if loaded[b] == a:
        
                print(b ,' is already loaded  ')
                
                raise pymol.CmdException(b+' is already loaded ')
                
                return 
            
            elif loaded[b] != a:
            
                print(b ,' is already loaded  from ', loaded[b]  )
                
                if loaded[b] != '' :
                    
                    dire = loaded[b]
                    
                else :
                    
                    dire = os.curdir
                    # dire = os.getcwd() # more usefull
                
                raise pymol.CmdException(b+' is already loaded  from ' + dire)
                
                return 
        else: 
        

            loaded[b] = a
            
            load_old(*args, **kwargs)
            
            print('loaded : ', loaded)
        
    else:
        
        load_old(*args, **kwargs)
        
        print('loaded : ', loaded)
        
        
pymol.cmd.extend('load' , load)
pymol.cmd.load = load
    

delete_old = pymol.cmd.delete


def delete(*args, **kwargs):
    
    global loaded
    
    if len(args) > 0 :
        
        if args[0] in loaded :
            
            loaded.pop(args[0], None)
            
            print('loaded pop : ' , loaded)
        
            delete_old(*args , **kwargs)
            
        elif args[0] == 'all' :
            
            loaded = {}
            
            print('loaded pop : ' , loaded)
        
            delete_old(*args , **kwargs)
            
        else:
            
            delete_old(*args , **kwargs)
    else:
        
        delete_old(*args , **kwargs)
        
    print('loaded : ', loaded)
        

pymol.cmd.extend('delete' , delete)
pymol.cmd.delete = delete

then from pymol GUI I can launch my script [ menu : File --> Run Script ], that tries to load same pdb three time from different locations (copies of the file are there):

import pymol

print('start')

try:
    
    pymol.cmd.load('A/2lyz.pdb')
    
except Exception as e:
    
    print(e)
    
print('next step')

print('start again')


try:
    
    pymol.cmd.load('2lyz.pdb')
    
except Exception as e:
    
    print(e)
    
print('next step')


print('start again different directory')


try:
    
    pymol.cmd.load('A/B/2lyz.pdb')
    
except Exception as e:
    
    print(e)
    
print('next step')

output printed on pymole console while first molecule is shown on maainwindow:

start
argsz :  ('A/2lyz.pdb',) <class 'tuple'> 1
args[0] :  A/2lyz.pdb
 a :  A  b :  2lyz
loaded :  {'2lyz': 'A'}
next step
start again
argsz :  ('2lyz.pdb',) <class 'tuple'> 1
args[0] :  2lyz.pdb
 a :    b :  2lyz
2lyz  is already loaded  from  A
 Error: 2lyz is already loaded  from A
next step
start again different directory
argsz :  ('A/B/2lyz.pdb',) <class 'tuple'> 1
args[0] :  A/B/2lyz.pdb
 a :  A/B  b :  2lyz
2lyz  is already loaded  from  A
 Error: 2lyz is already loaded  from A
next step

Clearly my first script does not allow pymol to load different states of the same molecule, each molecule is identified by its filename (i.e. 2x3y.pdb)