Source code for molutil

"""Module with utility functions that act on molecule objects."""
import PsiMod


[docs]def extract_clusters(mol, ghost=True, cluster_size=0): """Function to return all subclusters of the molecule *mol* of real size *cluster_size* and all other atoms ghosted if *ghost* equals true, all other atoms discarded if *ghost* is false. If *cluster_size* = 0, returns all possible combinations of cluster size. """ # How many levels of clusters are possible? nfrag = mol.nfragments() # Initialize the cluster array clusters = [] # scope the arrays reals = [] ghosts = [] # counter counter = 0 # loop over all possible cluster sizes for nreal in range(nfrag, 0, -1): # if a specific cluster size size is requested, only do that if (nreal != cluster_size and cluster_size > 0): continue # initialize the reals list reals = [] # setup first combination [3,2,1] lexical ordering # fragments indexing is 1's based, bloody hell for index in range(nreal, 0, -1): reals.append(index) # start loop through lexical promotion while True: counter = counter + 1 # Generate cluster from last iteration if (ghost): ghosts = [] for g in range(nfrag, 0, -1): if (g not in reals): ghosts.append(g) #print "Cluster #%d: %s reals, %s ghosts" % (counter,str(reals), str(ghosts)) clusters.append(mol.extract_subsets(reals, ghosts)) else: #print "Cluster #%d: %s reals" % (counter,str(reals)) clusters.append(mol.extract_subsets(reals)) # reset rank rank = 0 # look for lexical promotion opportunity # i.e.: [4 2 1] has a promotion opportunity at # index 1 to produce [4 3 1] for k in range(nreal - 2, -1, -1): if (reals[k] != reals[k + 1] + 1): rank = k + 1 break # do the promotion reals[rank] = reals[rank] + 1 # demote the right portion of the register val = 1 for k in range(nreal - 1, rank, -1): reals[k] = val val = val + 1 # boundary condition is promotion into # [nfrag+1 nfrag-1 ...] if (reals[0] > nfrag): break return clusters
[docs]def extract_cluster_indexing(mol, cluster_size=0): """Function to returns a LIST of all subclusters of the molecule *mol* of real size *cluster_size*. If *cluster_size* = 0, returns all possible combinations of cluster size. """ import copy # How many levels of clusters are possible? nfrag = mol.nfragments() # Initialize the cluster array clusters = [] # scope the arrays reals = [] # counter counter = 0 # loop over all possible cluster sizes for nreal in range(nfrag, 0, -1): # if a specific cluster size size is requested, only do that if (nreal != cluster_size and cluster_size > 0): continue # initialize the reals list reals = [] # setup first combination [3,2,1] lexical ordering # fragments indexing is 1's based, bloody hell for index in range(nreal, 0, -1): reals.append(index) # start loop through lexical promotion while True: counter = counter + 1 # Generate cluster from last iteration clusters.append(copy.deepcopy(reals)) # reset rank rank = 0 # look for lexical promotion opportunity # i.e.: [4 2 1] has a promotion opportunity at # index 1 to produce [4 3 1] for k in range(nreal - 2, -1, -1): if (reals[k] != reals[k + 1] + 1): rank = k + 1 break # do the promotion reals[rank] = reals[rank] + 1 # demote the right portion of the register val = 1 for k in range(nreal - 1, rank, -1): reals[k] = val val = val + 1 # boundary condition is promotion into # [nfrag+1 nfrag-1 ...] if (reals[0] > nfrag): break return clusters
[docs]def new_set_attr(self, name, value): """Function to redefine set_attr method of molecule class.""" fxn = object.__getattribute__(self, "is_variable") isvar = fxn(name) if isvar: fxn = object.__getattribute__(self, "set_variable") fxn(name, value) return object.__setattr__(self, name, value)
[docs]def new_get_attr(self, name): """Function to redefine get_attr method of molecule class.""" fxn = object.__getattribute__(self, "is_variable") isvar = fxn(name) if isvar: fxn = object.__getattribute__(self, "get_variable") return fxn(name) return object.__getattribute__(self, name)
[docs]def dynamic_variable_bind(cls): """Function to bind PsiMod.Molecule class.""" # class specific cls.__setattr__ = new_set_attr cls.__getattr__ = new_get_attr
dynamic_variable_bind(PsiMod.Molecule) # pass class type, not class instance # # Define geometry to be used by PSI4. # The molecule created by this will be set in options. # # geometry(" # O 1.0 0.0 0.0 # H 0.0 1.0 0.0 # H 0.0 0.0 0.0 #
[docs]def geometry(geom, name="default"): """Function to create a molecule object of name *name* from the geometry in string *geom*. """ molecule = PsiMod.Molecule.create_molecule_from_string(geom) molecule.set_name(name) activate(molecule) return molecule
[docs]def activate(mol): """Function to set molecule object *mol* as the current active molecule.""" PsiMod.set_active_molecule(mol) #PsiMod.IO.set_default_namespace(mol.get_name())