예제 #1
0
    def test_is_valid_and_test_empty(self):
        pat = ob.OBSmartsPattern()
        self.assertFalse(pat.IsValid())
        self.assertTrue(pat.Empty())

        pat.Init("CO")
        self.assertTrue(pat.IsValid())
        self.assertFalse(pat.Empty())
        pat = ob.OBSmartsPattern()
        with SuppressLogging():
            # This will send message to the error log.
            self.assertFalse(pat.Init("=O"))
        self.assertFalse(pat.IsValid())
        self.assertTrue(pat.Empty())
예제 #2
0
 def test_bad_smarts(self):
     pat = ob.OBSmartsPattern()
     # This writes an error to the log
     with SuppressLogging():
         self.assertFalse(pat.Init("%"))
     self.assertEqual(pat.NumAtoms(), 0)
     self.assertFalse(pat.IsValid())
예제 #3
0
def matchsmarts(smarts, outf, catoms):
    sm = openbabel.OBSmartsPattern()
    sm.Init(smarts)
    f = open(outf, 'r')
    s = f.read().splitlines()
    f.close()
    moll = openbabel.OBMol()
    obConversion = openbabel.OBConversion()
    obConversion.SetInAndOutFormats("smi", "smi")
    f = open(outf, 'w')
    for i, mol in enumerate(s):
        obConversion.ReadString(moll, mol)
        sm.Match(moll)
        # sm.Match(mol)
        smm = list(sm.GetUMapList())
        if len(smm) > 0:
            pmatch = smm[0]
            cc = ''
            for at in catoms:
                att = at - 1  # indexing
                cc += str(pmatch[att]) + ','
            #if i < nres:
            f.write(mol + ' ' + cc[:-1] + '\n')
            #f.write(s[i]+'\n')
        else:
            pass
    f.close()
    return 0
예제 #4
0
    def __init__(self, mol, **kwargs):
        """ Readies a fragmentation object for an OpenBabel molecule

            Arguments:
            mol -- molecule

            Keyword Arguments:
            defaults -- FragItConfig object defaults
        """
        conffile = kwargs.get('conffile', None)
        defaults = kwargs.pop('defaults', FragItDataBase)
        FragItConfig.__init__(self,
                              defaults=defaults,
                              filename=conffile,
                              **kwargs)
        self.mol = mol
        self.obc = openbabel.OBConversion()
        self.pat = openbabel.OBSmartsPattern()
        self._atom_names = []
        self._residue_names = []
        self._fragment_names = []
        self._fragment_charges = []
        self._fragments = []
        self._backbone_atoms = []
        self._mergeable_atoms = []
        self._atoms = []
        self._fixAtomsAndCharges()
        self._nbonds_broken = 0
예제 #5
0
def process_types(poltype, mol):
    """
    Intent: Set up scalelist array for scaling certain multipole values
For alchol, the quadrupole on O and H should be mannually scaled by 0.6. This only applies to OH that connect to sp3 Carbon. Similarly for NH in amine (that connects to a sp3 C), scale the Q by 0.75 or 75%. See JCC 2011 32(5):967-77. 
    """
    scalelist = {}
    multipole_scale_dict = {}

    for atm in openbabel.OBMolAtomIter(mol):
        if symm.get_class_number(poltype, atm.GetIdx()) not in scalelist:
            scalelist[symm.get_class_number(poltype, atm.GetIdx())] = []
            scalelist[symm.get_class_number(poltype,
                                            atm.GetIdx())].append(None)
            scalelist[symm.get_class_number(poltype,
                                            atm.GetIdx())].append(None)
            scalelist[symm.get_class_number(poltype,
                                            atm.GetIdx())].append(None)
            multipole_scale_dict = {}

    #multipole_scale_dict['[OH][CX4]'] = [2, 0.6]
    #multipole_scale_dict['[NH2][CX4]'] = [2, 0.75]
    for (sckey, scval) in multipole_scale_dict.items():
        sp = openbabel.OBSmartsPattern()
        openbabel.OBSmartsPattern.Init(sp, sckey)
        match = sp.Match(mol)
        for ia in sp.GetUMapList():
            scalelist[symm.get_class_number(poltype,
                                            ia[0])][scval[0]] = scval[1]

    return scalelist
예제 #6
0
 def test_replace_with_bad_smarts(self):
     pat = ob.OBSmartsPattern()
     self.assertTrue(pat.Init("CCCC"))
     self.assertEqual(pat.NumAtoms(), 4)
     # Re-init and verify that there's an overwrite
     # This writes an error to the log
     with SuppressLogging():
         self.assertFalse(pat.Init("Q"))
     self.assertEqual(pat.NumAtoms(), 0)
     self.assertFalse(pat.IsValid())
예제 #7
0
    def test_4_membered_ring(self):
        pat = ob.OBSmartsPattern()
        self.assertTrue(pat.Init("*1~*~*~*~1"), "failed to Init")
        mol = parse_smiles("C1CCCC1")
        m = pat.Match(mol)
        self.assertFalse(m, "had a match?")

        mol = parse_smiles("C1CCC1")
        m = pat.Match(mol)
        self.assertTrue(m, "no match?")
예제 #8
0
 def __init__(self, mol):
     FragItConfig.__init__(self)
     self.mol = mol
     self.obc = openbabel.OBConversion()
     self.pat = openbabel.OBSmartsPattern()
     self._residue_names = []
     self._fragment_names = []
     self._fragment_charges = []
     self._fragments = []
     self._backbone_atoms = []
     self._atoms = [mol.GetAtom(i) for i in range(1, mol.NumAtoms() + 1)]
     self._mergeable_atoms = []
예제 #9
0
파일: zft.py 프로젝트: agiliopadua/ms-tools
    def __init__(self, name, smarts):
        self.name = name
        self.smarts = smarts
        self.obsmarts = None
        # smarts not provided means this is a fake root define
        if smarts is not None:
            self.obsmarts = ob.OBSmartsPattern()
            if not self.obsmarts.Init(smarts):
                raise Exception('Invalid SMARTS: %s' % smarts)

        self.children: [TypeDefine] = []
        self.parent: TypeDefine = None
예제 #10
0
 def test_num_atoms_and_bonds(self):
     pat = ob.OBSmartsPattern()
     self.assertEqual(pat.NumAtoms(), 0)
     self.assertEqual(pat.NumBonds(), 0)
     pat.Init("C")
     self.assertEqual(pat.NumAtoms(), 1)
     self.assertEqual(pat.NumBonds(), 0)
     pat.Init("C#N")
     self.assertEqual(pat.NumAtoms(), 2)
     self.assertEqual(pat.NumBonds(), 1)
     pat.Init("c1ccccc1")
     self.assertEqual(pat.NumAtoms(), 6)
     self.assertEqual(pat.NumBonds(), 6)
예제 #11
0
 def parse_sma(self, sma):
     """parse smarts and return OBSmartsPattern after storing in global dict
    or return from global dict"""
     if self.pat.has_key(sma):
         return self.pat[sma]
     if len(self.pat) < self.maxsma:
         pat = openbabel.OBSmartsPattern()
         #notice('new pat for %s' % sma)
     else:
         key, pat = self.pat.popitem()
         #notice('pattern reuse %s for %s' % (key,sma))
     if pat.Init(sma):
         self.pat[sma] = pat
         return pat
     else:
         #notice('pattern None')
         return None
예제 #12
0
def matchsmarts(smarts, outf, catoms):
    sm = openbabel.OBSmartsPattern()
    print('---Test for developer version----')
    sm.Init(smarts)
    print('smart is:', smarts)
    current_path = os.getcwd()
    print('current path:', current_path)
    print('file open:', outf)
    f = open(outf, 'r')
    s = f.read().splitlines()
    f.close()
    # moll = openbabel.OBMol()
    # obConversion = openbabel.OBConversion()
    # obConversion.SetInAndOutFormats("smi", "smi")
    f = open(outf, 'w')
    # print('in file is:', s)
    moll = openbabel.OBMol()  # add
    obConversion = openbabel.OBConversion()  # add
    obConversion.SetInAndOutFormats("smi", "smi")  # add
    for i, mol in enumerate(s):
        obConversion.ReadString(moll, mol)
        sm.Match(moll)
        # sm.Match(mol)
        # print('mol current:', mol)
        smm = list(sm.GetUMapList())
        print('#:', i)
        print('mol current:', mol)
        print('smm current', smm)
        print('catoms:', catoms)
        if len(smm) > 0:
            pmatch = smm[0]
            cc = ''
            for at in catoms:
                att = at - 1  # indexing
                cc += str(pmatch[att]) + ','
            # if i < nres:
            f.write(mol + ' ' + cc[:-1] + '\n')
        # f.write(s[i]+'\n')
        else:
            pass
        f.close()
        return 0
예제 #13
0
def is_in_polargroup(poltype, mol, smarts, bond, f):
    """
    Intent: Check if a given bond is in the group defined by the smarts string
    Input:
        mol: OBMol object
        smarts: Smarts String defining the group (e.g. O-[*])
        bond: bond in question
        f: output file (not used)
    Output:
        True if the bond is in the group, False if not
    Referenced By: gen_peditinfile
    Description: -
    """
    sp = openbabel.OBSmartsPattern()
    openbabel.OBSmartsPattern.Init(sp, smarts)
    sp.Match(mol)
    for i in sp.GetUMapList():
        if ((bond.GetBeginAtomIdx() in i) and \
             (bond.GetEndAtomIdx() in i)):
            return True
    return False
예제 #14
0
        def MatchPlattsBGroups(self, smiles):

            # Load functional group database
            current_dir = os.getcwd()
            filepath = os.path.join(current_dir, 'groups.xls')
            wb = xlrd.open_workbook(filepath)
            wb.sheet_names()

            data = wb.sheet_by_name(u'PlattsB')
            col1 = data.col_values(0)
            col2 = data.col_values(1)
            col3 = data.col_values(2)

            databaseB = []
            for (SMART, name, B) in zip(col1, col2, col3):
                databaseB.append(functionalgroup(SMART, name, B))

            platts_B = 0
            mol = pybel.readstring("smi", smiles)
            for x in databaseB:
                # Initialize with dummy SMLES to check for validity of real one
                smarts = pybel.Smarts("CC")
                smarts.obsmarts = ob.OBSmartsPattern()
                success = smarts.obsmarts.Init(x.smarts.__str__())
                if success:
                    smarts = pybel.Smarts(x.smarts.__str__())
                else:
                    print "Invalid SMARTS pattern", x.smarts.__str__()
                    break
                matched = smarts.findall(mol)
                x.num = len(matched)
                if (x.num > 0):
                    print "Found group", x.smarts.__str__(
                    ), 'named', x.name, 'with contribution', x.value, 'to B', x.num, 'times'
                platts_B += (x.num) * (x.value)

            self.B = platts_B + 0.071
예제 #15
0
def get_atom_types(molecule, config):
    """
    Creates a dictionary containing all the identified atom types for all atoms
    in this molecule. Only feasible really for small molecules and not for protein
    structures.
    """
    # PREPARE DICTIONARY DATA STRUCTURE FOR MOLECULE ATOM TYPES
    atom_types = dict((atom.idx, {}) for atom in molecule.atoms)

    # ITERATE THROUGH ALL SMARTS PATTERNS OF ALL CREDO ATOM TYPES
    for atom_type in config['atom types']:
        for smarts in config['atom types'][atom_type].values():

            # MATCH THAT IS GOING TO BE SET FOR MATCHING ATOMS
            pattern = ob.OBSmartsPattern()
            pattern.Init(str(smarts))

            pattern.Match(molecule.OBMol)

            for match in pattern.GetUMapList():
                for idx in match:
                    atom_types[idx][atom_type] = 1

    return atom_types
예제 #16
0
def process_arpeggio(mol2_filename):

    slig = SmallMol(mol2_filename)
    slig.write('tmp.pdb')

    pdb_filename = 'tmp.pdb'

    # LOAD STRUCTURE (BIOPYTHON)
    pdb_parser = PDBParser()
    s = pdb_parser.get_structure('structure', pdb_filename)
    s_atoms = list(s.get_atoms())

    logging.info('Loaded PDB structure (BioPython)')

    # CHECK FOR HYDROGENS IN THE INPUT STRUCTURE
    input_has_hydrogens = False
    hydrogens = [x for x in s_atoms if x.element == 'H']

    if hydrogens:
        logging.info(
            'Detected that the input structure contains hydrogens. Hydrogen addition will be skipped.'
        )
        input_has_hydrogens = True

    # LOAD STRUCTURE (OPENBABEL)
    ob_conv = ob.OBConversion()
    ob_conv.SetInFormat('pdb')
    mol = ob.OBMol()
    ob_conv.ReadFile(mol, pdb_filename)

    # CHECK THAT EACH ATOM HAS A UNIQUE SERIAL NUMBER
    all_serials = [x.serial_number for x in s_atoms]

    if len(all_serials) > len(set(all_serials)):
        raise AtomSerialError

    # MAPPING OB ATOMS TO BIOPYTHON ATOMS AND VICE VERSA

    # FIRST MAP PDB SERIAL NUMBERS TO BIOPYTHON ATOMS FOR SPEED LATER
    # THIS AVOIDS LOOPING THROUGH `s_atoms` MANY TIMES
    serial_to_bio = {x.serial_number: x for x in s_atoms}

    # DICTIONARIES FOR CONVERSIONS
    ob_to_bio = {}
    bio_to_ob = {}

    for ob_atom in ob.OBMolAtomIter(mol):

        serial = ob_atom.GetResidue().GetSerialNum(ob_atom)

        # MATCH TO THE BIOPYTHON ATOM BY SERIAL NUMBER
        try:
            biopython_atom = serial_to_bio[serial]

        except KeyError:
            # ERRORWORTHY IF WE CAN'T MATCH AN OB ATOM TO A BIOPYTHON ONE
            raise OBBioMatchError(serial)

        # `Id` IS A UNIQUE AND STABLE ID IN OPENBABEL
        # CAN RECOVER THE ATOM WITH `mol.GetAtomById(id)`
        ob_to_bio[ob_atom.GetId()] = biopython_atom
        bio_to_ob[biopython_atom] = ob_atom.GetId()

    logging.info('Mapped OB to BioPython atoms and vice-versa.')

    # ADD EMPTY DATA STRUCTURES FOR TAGGED ATOM DATA
    # IN A SINGLE ITERATION
    for atom in s_atoms:

        # FOR ATOM TYPING VIA OPENBABEL
        atom.atom_types = set([])

        # LIST FOR EACH ATOM TO STORE EXPLICIT HYDROGEN COORDINATES
        atom.h_coords = []

        # DETECT METALS
        if atom.element.upper() in METALS:
            atom.is_metal = True
        else:
            atom.is_metal = False

        # DETECT HALOGENS
        if atom.element.upper() in HALOGENS:
            atom.is_halogen = True
        else:
            atom.is_halogen = False

    # ADD EXPLICIT HYDROGEN COORDS FOR H-BONDING INTERACTIONS
    # ADDING HYDROGENS DOESN'T SEEM TO INTERFERE WITH ATOM SERIALS (THEY GET ADDED AS 0)
    # SO WE CAN STILL GET BACK TO THE PERSISTENT BIOPYTHON ATOMS THIS WAY.
    if not input_has_hydrogens:
        mol.AddHydrogens(False, True, ph)  # polaronly, correctForPH, pH

        logging.info('Added hydrogens.')

    # ATOM TYPING VIA OPENBABEL
    # ITERATE OVER ATOM TYPE SMARTS DEFINITIONS
    for atom_type, smartsdict in ATOM_TYPES.items():

        #logging.info('Typing: {}'.format(atom_type))

        # FOR EACH ATOM TYPE SMARTS STRING
        for smarts in smartsdict.values():

            #logging.info('Smarts: {}'.format(smarts))

            # GET OPENBABEL ATOM MATCHES TO THE SMARTS PATTERN
            ob_smart = ob.OBSmartsPattern()
            ob_smart.Init(str(smarts))

            #logging.info('Initialised for: {}'.format(smarts))

            ob_smart.Match(mol)

            #logging.info('Matched for: {}'.format(smarts))

            matches = [x for x in ob_smart.GetMapList()]

            #logging.info('List comp matches: {}'.format(smarts))

            if matches:

                # REDUCE TO A SINGLE LIST
                matches = set(reduce(operator.add, matches))

                #logging.info('Set reduce matches: {}'.format(smarts))

                for match in matches:

                    atom = mol.GetAtom(match)
                    ob_to_bio[atom.GetId()].atom_types.add(atom_type)

                #logging.info('Assigned types: {}'.format(smarts))

    # ALL WATER MOLECULES ARE HYDROGEN BOND DONORS AND ACCEPTORS
    for atom in (x for x in s_atoms if x.get_full_id()[3][0] == 'W'):
        atom.atom_types.add('hbond acceptor')
        atom.atom_types.add('hbond donor')

    # OVERRIDE PROTEIN ATOM TYPING FROM DICTIONARY
    for residue in s.get_residues():

        if residue.resname in STD_RES:

            for atom in residue.child_list:

                # REMOVE TYPES IF ALREADY ASSIGNED FROM SMARTS
                for atom_type in PROT_ATOM_TYPES.keys():
                    atom.atom_types.discard(atom_type)

                # ADD ATOM TYPES FROM DICTIONARY
                for atom_type, atom_ids in PROT_ATOM_TYPES.items():

                    atom_id = residue.resname.strip() + atom.name.strip()

                    if atom_id in atom_ids:
                        atom.atom_types.add(atom_type)

    def make_pymol_string(entity):
        '''
        Feed me a BioPython atom or BioPython residue.
        See `http://pymol.sourceforge.net/newman/user/S0220commands.html`.
        chain-identifier/resi-identifier/name-identifier
        chain-identifier/resi-identifier/
        '''

        if isinstance(entity, Atom):

            chain = entity.get_parent().get_parent()
            residue = entity.get_parent()
            atom_name = entity.name

        elif isinstance(entity, Residue):
            chain = entity.get_parent()
            residue = entity
            atom_name = ''

        else:
            raise TypeError(
                'Cannot make a PyMOL string from a non-Atom or Residue object.'
            )

        res_num = residue.id[1]

        # ADD INSERTION CODE IF NEED BE
        if residue.id[2] != ' ':
            res_num = str(res_num) + residue.id[2]

        macro = '{}/{}/{}'.format(chain.id, res_num, atom_name)

        return macro

    '''

    with open(pdb_filename.replace('.pdb', '.atomtypes'), 'w') as fo:

        if headers:
            fo.write('{}\n'.format('\t'.join(
                ['atom', 'atom_types']
            )))

        for atom in s_atoms:
            fo.write('{}\n'.format('\t'.join([str(x) for x in [make_pymol_string(atom), sorted(tuple(atom.atom_types))]])))

    logging.info('Typed atoms.')


    '''

    return s_atoms
예제 #17
0
class Molecule(object):

    # for more rendering options visit:
    # http://www.ggasoftware.com/opensource/indigo/api/options#rendering
    _obElements = openbabel.OBElementTable()
    _obSmarts = openbabel.OBSmartsPattern()
    
    @staticmethod
    def GetNumberOfElements():
        return Molecule._obElements.GetNumberOfElements()
    
    @staticmethod
    def GetAllElements():
        return [Molecule._obElements.GetSymbol(i) for i in 
                xrange(Molecule.GetNumberOfElements())]

    @staticmethod
    def GetSymbol(atomic_num):
        return Molecule._obElements.GetSymbol(atomic_num)
            
    @staticmethod
    def GetAtomicNum(elem):
        if type(elem) == types.UnicodeType:
            elem = str(elem)
        return Molecule._obElements.GetAtomicNum(elem)
    
    @staticmethod
    def VerifySmarts(smarts):
        return Molecule._obSmarts.Init(smarts)
    
    def __init__(self):
        self.title = None
        self.obmol = openbabel.OBMol()
        self.smiles = None
        self.inchi = None

    def __str__(self):
        return self.title or self.smiles or self.inchi or ""
        
    def __len__(self):
        return self.GetNumAtoms()
    
    def Clone(self):
        tmp = Molecule()
        tmp.title = self.title
        tmp.obmol = openbabel.OBMol(self.obmol)
        tmp.smiles = self.smiles
        tmp.inchi = self.inchi
        return tmp
    
    def SetTitle(self, title):
        self.title = title 
    
    @staticmethod
    def FromSmiles(smiles):
        m = Molecule()
        m.smiles = smiles
        obConversion = openbabel.OBConversion()
        obConversion.AddOption("w", obConversion.OUTOPTIONS)
        obConversion.SetInFormat("smiles")
        if not obConversion.ReadString(m.obmol, m.smiles):
            raise OpenBabelError("Cannot read the SMILES string: " + smiles)
        try:
            m.UpdateInChI()
        except OpenBabelError:
            raise OpenBabelError("Failed to create Molecule from SMILES: " + smiles)
        m.SetTitle(smiles)
        return m
        
    @staticmethod
    def FromInChI(inchi):
        m = Molecule()
        m.inchi = inchi
        obConversion = openbabel.OBConversion()
        obConversion.AddOption("w", obConversion.OUTOPTIONS)
        obConversion.SetInFormat("inchi")
        obConversion.ReadString(m.obmol, m.inchi)
        try:
            m.UpdateSmiles()
        except OpenBabelError:
            raise OpenBabelError("Failed to create Molecule from InChI: " + inchi)
        m.SetTitle(inchi)
        return m
    
    @staticmethod
    def FromMol(mol):
        m = Molecule()
        obConversion = openbabel.OBConversion()
        obConversion.AddOption("w", obConversion.OUTOPTIONS)
        obConversion.SetInFormat("mol")
        obConversion.ReadString(m.obmol, mol)
        try:
            m.UpdateInChI()
            m.UpdateSmiles()
        except OpenBabelError:
            raise OpenBabelError("Failed to create Molecule from MOL file:\n" + mol)
        m.SetTitle("")
        return m

    @staticmethod
    def FromOBMol(obmol):
        m = Molecule()
        m.obmol = obmol
        try:
            m.UpdateInChI()
            m.UpdateSmiles()
        except OpenBabelError:
            raise OpenBabelError("Failed to create Molecule from OBMol")
        m.SetTitle("")
        return m
    
    @staticmethod
    def _FromFormat(s, fmt='inchi'):
        if fmt == 'smiles' or fmt == 'smi':
            return Molecule.FromSmiles(s)
        if fmt == 'inchi':
            return Molecule.FromInChI(s)
        if fmt == 'mol':
            return Molecule.FromMol(s)
        if fmt == 'obmol':
            return Molecule.FromOBMol(s)
    
    @staticmethod
    def _ToFormat(obmol, fmt='inchi'):
        obConversion = openbabel.OBConversion()
        obConversion.AddOption("w", obConversion.OUTOPTIONS)
        obConversion.SetOutFormat(fmt)
        res = obConversion.WriteString(obmol)
        if not res:
            raise OpenBabelError("Cannot convert OBMol to %s" % fmt)
        if fmt == 'smiles' or fmt == 'smi':
            res = res.split()
            if res == []:
                raise OpenBabelError("Cannot convert OBMol to %s" % fmt)
            else:
                return res[0]
        elif fmt == 'inchi':
            return res.strip()
        else:
            return res
        
    @staticmethod
    def Smiles2InChI(smiles):
        obConversion = openbabel.OBConversion()
        obConversion.AddOption("w", obConversion.OUTOPTIONS)
        obConversion.SetInAndOutFormats("smiles", "inchi")
        obmol = openbabel.OBMol()
        if not obConversion.ReadString(obmol, smiles):
            raise OpenBabelError("Cannot read the SMILES string: " + smiles)
        return obConversion.WriteString(obmol).strip()

    @staticmethod
    def InChI2Smiles(inchi):
        obConversion = openbabel.OBConversion()
        obConversion.AddOption("w", obConversion.OUTOPTIONS)
        obConversion.SetInAndOutFormats("inchi", "smiles")
        obmol = openbabel.OBMol()
        if not obConversion.ReadString(obmol, inchi):
            raise OpenBabelError("Cannot read the InChI string: " + inchi)
        return obConversion.WriteString(obmol).split()[0]
        
    def RemoveHydrogens(self):
        self.obmol.DeleteHydrogens()
    
    def RemoveAtoms(self, indices):
        self.obmol.BeginModify()
        for i in sorted(indices, reverse=True):
            self.obmol.DeleteAtom(self.obmol.GetAtom(i+1))
        self.obmol.EndModify()
        self.smiles = None
        self.inchi = None
        
    def SetAtomicNum(self, index, new_atomic_num):
        self.obmol.GetAtom(index+1).SetAtomicNum(new_atomic_num)
        self.smiles = None
        self.inchi = None
        
    def ToOBMol(self):
        return self.obmol
    
    def ToFormat(self, fmt='inchi'):
        return Molecule._ToFormat(self.obmol, fmt=fmt)
    
    def ToMolfile(self):
        return self.ToFormat('mol')

    def UpdateInChI(self):
        self.inchi = Molecule._ToFormat(self.obmol, 'inchi')

    def ToInChI(self):
        """ 
            Lazy storage of the InChI identifier (calculate once only when 
            asked for and store for later use).
        """
        if not self.inchi:
            self.UpdateInChI()
        return self.inchi
    
    def UpdateSmiles(self):
        self.smiles = Molecule._ToFormat(self.obmol, 'smiles')
    
    def ToSmiles(self):
        """ 
            Lazy storage of the SMILES identifier (calculate once only when 
            asked for and store for later use).
        """
        if not self.smiles:
            self.UpdateSmiles()
        return self.smiles
    
    def GetFormula(self):
        tokens = re.findall('InChI=1S?/([0-9A-Za-z\.]+)', self.ToInChI())
        if len(tokens) == 1:
            return tokens[0]
        elif len(tokens) > 1:
            raise ValueError('Bad InChI: ' + self.ToInChI())
        else:
            return ''
    
    def GetExactMass(self):
        return self.obmol.GetExactMass()
    
    def GetAtomBagAndCharge(self):
        inchi = self.ToInChI()

        fixed_charge = 0
        for s in re.findall('/q([0-9\+\-]+)', inchi):
            fixed_charge += int(s)

        fixed_protons = 0
        for s in re.findall('/p([0-9\+\-]+)', inchi):
            fixed_protons += int(s)
        
        formula = self.GetFormula()

        atom_bag = {}
        for mol_formula_times in formula.split('.'):
            for times, mol_formula in re.findall('^(\d+)?(\w+)', mol_formula_times):
                if not times:
                    times = 1
                else:
                    times = int(times)
                for atom, count in re.findall("([A-Z][a-z]*)([0-9]*)", mol_formula):
                    if count == '':
                        count = 1
                    else:
                        count = int(count)
                    atom_bag[atom] = atom_bag.get(atom, 0) + count * times
        
        if fixed_protons:
            atom_bag['H'] = atom_bag.get('H', 0) + fixed_protons
            fixed_charge += fixed_protons
        return atom_bag, fixed_charge
        
    def GetHydrogensAndCharge(self):
        atom_bag, charge = self.GetAtomBagAndCharge()
        return atom_bag.get('H', 0), charge
        
    def GetNumElectrons(self):
        """Calculates the number of electrons in a given molecule."""
        atom_bag, fixed_charge = self.GetAtomBagAndCharge()
        n_protons = 0
        for elem, count in atom_bag.iteritems():
            n_protons += count * self._obElements.GetAtomicNum(elem)
        return n_protons - fixed_charge
    
    def GetNumAtoms(self):
        return self.obmol.NumAtoms()

    def GetAtoms(self):
        return [self.obmol.GetAtom(i+1) for i in xrange(self.obmol.NumAtoms())]
    
    def FindSmarts(self, smarts):
        """
        Corrects the pyBel version of Smarts.findall() which returns results as tuples,
        with 1-based indices even though Molecule.atoms is 0-based.
    
        Args:
            mol: the molecule to search in.
            smarts_str: the SMARTS query to search for.
        
        Returns:
            The re-mapped list of SMARTS matches.
        """
        Molecule._obSmarts.Init(smarts)
        if Molecule._obSmarts.Match(self.obmol):
            match_list = Molecule._obSmarts.GetMapList()
            shift_left = lambda m: [(n - 1) for n in m]
            return map(shift_left, match_list)
        else:
            return []

    def GetAtomCharges(self):
        """
            Returns:
                A list of charges, according to the number of atoms
                in the molecule
        """
        return [atom.GetFormalCharge() for atom in self.GetAtoms()]
예제 #18
0
def prepare(self, to_format = 'mol2', addH = False, calc_charge = False,
            correct_for_pH = False, pH = 7.4):
    """
    Read a molecule structure with Openbabel and get basic information from
    it.  If requested modifiy the data and convert the file.

    :param to_format: format to convert to if not empty
    :type to_format: string
    :param addH: add hydrogens? (experimental)
    :type addH: bool
    :param calc_charge: force total formal charge calculation if True,
                        leave it to Openbabel if False
    :type calc_charge: bool
    :param correct_for_pH: correct for pH, i.e. determine protonation state?
                           (very experimental!)
    :type correct_for_pH: bool
    :param pH: pH to be considered when correct_for_pH is True
               (very experimental!)
    :type pH: float
    :raises: SetupError
    """

    conv = ob.OBConversion()
    mol = ob.OBMol()
    ob_read_one(conv, self.mol_file, mol, self.mol_fmt, to_format)

    # FIXME: does this test for the right thing?
    if mol.GetDimension() != 3:
        raise errors.SetupError('input cooridnates (%s) must have 3 dimensions'
                                % self.mol_file)

    orig_atoms = []

    etab = ob.OBElementTable()
    acnt = 0

    for atom in ob.OBMolAtomIter(mol):
        acnt += 1

        res = atom.GetResidue()     # when is this NULL?
        element = etab.GetSymbol(atom.GetAtomicNum() )
        orig_atoms.append( (res.GetAtomID(atom).strip(), element) )

        if to_format:
            res.SetAtomID(atom, '%s%d' % (element, acnt) )

    if addH:
        logger.write('Adding hydrogens')

        mol.DeleteHydrogens()

        if correct_for_pH:              # reimplementation from phmodel.cpp
            mol.SetAutomaticFormalCharge(correct_for_pH)

            transform = ob.OBChemTsfm()

            logger.write('Applying transforms')

            for reactant, product, pKa in const.TRANSFORM_SMARTS:
                success = transform.Init(reactant, product)

                if not success:
                    raise ValueError('BUG in SMARTS transform Init %s >> %s',
                                     (reactant, product) )

                if (transform.IsAcid() and pH > pKa) or \
                       (transform.IsBase() and pH < pKa):
                    success = transform.Apply(mol)

        mol.AddHydrogens(False, False, 0.0) # valence filling


    if mol.GetTotalSpinMultiplicity() != 1:
        raise errors.SetupError('only multiplicity=1 supported (%s)'
                                % self.mol_file)

    if to_format:
        logger.write('Converting/Writing %s (%s format) to %s format' %
                     (self.mol_file, self.mol_fmt, to_format) )

        # NOTE: this relies on a modified Openbabel MOL2 writer
        conv.AddOption('r', ob.OBConversion.OUTOPTIONS)  # do not append resnum

        self.mol_file = const.CONV_MOL2_FILE % to_format
        self.mol_fmt = to_format

        try:
            conv.WriteFile(mol, self.mol_file)
        except IOError as why:
            raise errors.SetupError(why)
    else:
        logger.write('Leaving %s unmodified.' % self.mol_file)


    # some formats allow formal charge definition:
    # PDB (col 79-80), SDF(M CHG, atom block), MOL2 (UNITY_ATOM_ATTR?)
    if calc_charge:
        logger.write('Computing total formal charge\n')

        # set formal charge for some functional groups by hand because
        # OpenBabel doesn't support it in C++ for formats like mol2
        formal_charge = 0
        sm = ob.OBSmartsPattern()

        for smarts, fchg in const.CHARGE_SMARTS:
            sm.Init(smarts)

            if sm.Match(mol):
                m = list(sm.GetUMapList() )
                formal_charge += fchg * len(m)

        mol.SetTotalCharge(formal_charge)
        self.charge = formal_charge
    else:
        logger.write('Total formal charge taken from coordinate file\n')
        self.charge = mol.GetTotalCharge()  # trust Openbabel...

    self.atomtype = 'sybyl'     # Openbabel will try to convert to Sybyl format

    conv.SetOutFormat('smi')
    conv.AddOption('n')
    conv.AddOption('c')
    smiles = conv.WriteString(mol).rstrip()

    conv.SetOutFormat('inchikey')
    errlev = ob.obErrorLog.GetOutputLevel()
    ob.obErrorLog.SetOutputLevel(0)

    inchi_key = conv.WriteString(mol).rstrip()

    ob.obErrorLog.SetOutputLevel(errlev)

    logger.write('''Ligand key data:
Formula: %s
SMILES: %s
InChIKey: %s
Net charge: %i
Molecular weight: %f\n''' % (mol.GetFormula(), smiles, inchi_key, self.charge,
                             mol.GetMolWt() ) )
예제 #19
0
    def partition_protein(self, mol, special_reslists=None, fragsize=None):
        """
        Partition a protein into the individual amino acids and caps.

        @param mol: the protein
        @type mol:  L{molecule}

        @param special_reslists:
            lists of residue numbers that should be treated within one 3-FDE fragment
        @type special_reslists: list of lists of integers

        @param fragsize:
            number of residues in one 3-FDE fragment (not for residues in special_reslist)
        @type fragsize: int
        """

        import openbabel

        # generate fragment list

        res_of_atoms = mol.get_residue_numbers_of_atoms()

        capped_bonds = []
        # list of bonds between residues within fragment
        non_capped_res = []
        # to which fragment belongs the residue
        frag_indices = []

        # clear the fragment list
        self._frags = []
        self._caps = []

        if fragsize == None:
            fragsize = 1
        if special_reslists == None:
            special_reslists = {}

        #----------------------------------------------------------------------------------
        # simplest fragmentation: each residue is one fragment

        if special_reslists == {} and fragsize == 1:

            # get the individual residues
            for res in mol.get_residues():
                self.append(cappedfragment(None, res))
                frag_indices.append(len(self._frags) - 1)
        #----------------------------------------------------------------------------------
        # more complicated fragmentation

        else:
            # careful with residue numbers (internal openbabel index idx starts at 0)

            fragmentation_list = []
            residuelist = mol.get_residues()
            frag_indices = [-1 for i in range(len(residuelist))]

            # get list of residues connected by covalent bonds (tuples)
            connected_residues = []
            for b in mol.get_all_bonds():
                if not (res_of_atoms[b[0] - 1] == res_of_atoms[b[1] - 1]):
                    # -1 is not totally clear to me, but works
                    connected_residues.append(
                        set([res_of_atoms[b[0] - 1], res_of_atoms[b[1] - 1]]))

            #------------------------------------------------------------------------------
            # first get fragmentation list: which residues belong to which fragment
            # something like [ [3,4,5], [11,12,14], [1, 2], [6, 7], [8, 9], [10], [13]]

            # ugly
            # dictionary that connects pdb resnums with internal idx
            # problem: resnum as key is not unique, use combination of residue name and chain as key
            res_idx = {}
            for res in residuelist:
                resnum = res.mol.GetResidue(0).GetNum()
                reschain = res.mol.GetResidue(0).GetChain()
                reskey = 'c' + str(reschain) + str(resnum)
                intresnum = res.mol.GetResidue(0).GetIdx()
                res_idx[reskey] = intresnum

            # convert residue numbers in special_reslists to internal numbers
            for i in range(len(special_reslists)):
                for j in range(len(special_reslists[i])):
                    special_reslists[i][j] = res_idx[special_reslists[i][j]]

            # flatten list of lists so that you can check whether a residue is a special residue
            specialresnums = []
            for slist in special_reslists:
                if isinstance(slist, (list, tuple)):
                    specialresnums.extend(slist)
                # else should not occur, but maybe it is needed later
                else:
                    specialresnums.append(slist)

            # first add special residues to fragmentation list
            for slist in special_reslists:
                fragmentation_list.append(slist)

            fragl = []  # templist for fragments
            # add all other residues
            # use res.GetIdx() instead of enumerate
            for res in residuelist:
                resnum = res.mol.GetResidue(0).GetIdx()
                if resnum not in specialresnums:
                    # take care of fragsize
                    if fragsize == 1:
                        fragmentation_list.append([resnum])
                    else:
                        # check whether there has to be a new fragment
                        if len(fragl) != 0:
                            if not set([resnum, fragl[-1]]) in connected_residues or \
                                    len(fragl) == fragsize:
                                # no covalent connection? new fragment! fragsize reached?
                                fragmentation_list.append(fragl)
                                fragl = []
                        # new fragment
                        if len(fragl) == 0:
                            fragl.append(resnum)
                        # add to fragment
                        else:
                            fragl.append(resnum)
            # last fragment
            if len(fragl) != 0:
                fragmentation_list.append(fragl)

            #------------------------------------------------------------------------------
            # now add fragments to _frags using fragmentation list
            # take care of uncapped bonds and fragindices etc.

            frag_reslist = []

            for rlist in fragmentation_list:
                for rnum in range(len(rlist)):
                    res = mol.get_residues(idx=rlist[rnum])[0]
                    frag_reslist.append(res)

                    # if residue is added to an existing fragment: add tuple of residues to
                    # list of connected (non-capped) residues (only if they are connected)

                    # take also care of disulfide bonds within one fragment
                    # check whether new residue is connected to another residue within this fragment
                    if len(frag_reslist) > 1:
                        for rd in range(len(frag_reslist)):
                            if set([rlist[rnum],
                                    rlist[rd]]) in connected_residues:
                                non_capped_res.append(
                                    set([rlist[rnum], rlist[rd]]))

                    # take care of residue information here
                    frag_indices[rlist[rnum]] = len(self._frags)

                res_frag = fragment(None, mols=frag_reslist)

                self.append(cappedfragment(None,
                                           res_frag.get_total_molecule()))
                # clear frag_reslist for next fragment
                frag_reslist = []

        #------------------------------------------------------------------------------

        # find all peptide bonds and create caps

        sp = openbabel.OBSmartsPattern()
        sp.Init('[C;X4;H1,H2][CX3](=O)[NX3][C;X4;H1,H2][CX3](=O)')
        # this SMARTS pattern matches all peptide bonds
        #
        # (in this comment: atom numbering starts at 1;
        #  in the code below the numbering of the list starts at 0)
        # the peptide bond is between atoms 2 and 4
        # atoms 1-5 (+ connected hydrogens) form the cap fragment
        # part 1 (o-part): atoms 1-3
        # part 2 (n-part): atoms 4-5

        sp.Match(mol.mol)
        maplist = sp.GetUMapList()
        for mp in maplist:
            mp = list(mp)

            if set([res_of_atoms[mp[3] - 1],
                    res_of_atoms[mp[1] - 1]]) not in non_capped_res:

                capped_bonds.append(set([mp[1], mp[3]]))
                cap_o = mp[0:3] + mol.find_adjacent_hydrogens(mp[0:3])
                cap_n = mp[3:5] + mol.find_adjacent_hydrogens(mp[3:5])
                m_cap = mol.get_fragment(cap_o + cap_n)
                m_cap.set_spin(0)
                m_cap.set_residue('CAP', 1, atoms=range(1, len(cap_o) + 1))
                m_cap.set_residue('CAP',
                                  2,
                                  atoms=range(
                                      len(cap_o) + 1,
                                      len(cap_o + cap_n) + 1))
                m_cap.add_hydrogens()

                # find the capped fragments
                #   frag1: fragment that contains the N atom (mp[3])
                #   frag2: fragment that contains the C=O atom (mp[1])
                # why minus 1???

                fi1 = frag_indices[res_of_atoms[mp[3] - 1]]
                fi2 = frag_indices[res_of_atoms[mp[1] - 1]]

                frag1 = self._frags[fi1]
                frag2 = self._frags[fi2]
                self.append_cap(cappedfragment(None, capmolecule(m_cap)),
                                frag1, frag2)

        #------------------------------------------------------------------------------

        # check here for disulfide bonds and create disulfide bond caps

        sp_sulfide = openbabel.OBSmartsPattern()
        sp_sulfide.Init('[C;X4;H1,H2]SS[C;X4;H1,H2]')
        # SMARTS pattern for disulfde bonds

        sp_sulfide.Match(mol.mol)
        maplist_sulfide = sp_sulfide.GetUMapList()
        for mps in maplist_sulfide:
            mps = list(mps)

            if set([res_of_atoms[mps[2] - 1],
                    res_of_atoms[mps[1] - 1]]) not in non_capped_res:

                capped_bonds.append(set([mps[1], mps[2]]))
                cap_s1 = mps[0:2] + mol.find_adjacent_hydrogens(mps[0:2])
                cap_s2 = mps[2:] + mol.find_adjacent_hydrogens(mps[2:])
                m_cap_s = mol.get_fragment(cap_s1 + cap_s2)
                m_cap_s.set_spin(0)
                m_cap_s.set_residue('SCP', 1, atoms=range(1, len(cap_s1) + 1))
                m_cap_s.set_residue('SCP',
                                    2,
                                    atoms=range(
                                        len(cap_s1) + 1,
                                        len(cap_s1 + cap_s2) + 1))
                m_cap_s.add_hydrogens()

                fi1 = frag_indices[res_of_atoms[mps[2] - 1]]
                fi2 = frag_indices[res_of_atoms[mps[1] - 1]]

                frag_s1 = self._frags[fi1]
                frag_s2 = self._frags[fi2]
                self.append_scap(cappedfragment(None, capmolecule(m_cap_s)),
                                 frag_s1, frag_s2)

        #------------------------------------------------------------------------------

        # find bonds between different residues and check if they have been capped

        num_uncapped_bonds = 0
        for b in mol.get_all_bonds():

            if not (res_of_atoms[b[0] - 1] == res_of_atoms[b[1] - 1]):

                if not set([b[0], b[1]]) in capped_bonds \
                        and not set([res_of_atoms[b[0] - 1], res_of_atoms[b[1] - 1]]) in non_capped_res \
                        and not set([res_of_atoms[b[0] - 1], res_of_atoms[b[1] - 1]]).issubset(special_reslists):

                    num_uncapped_bonds += 1
                    print "Bond between atoms ", b[0], " and ", b[
                        1], "not capped."
                    print "Bond between res ", res_of_atoms[
                        b[0] - 1], " and ", res_of_atoms[b[1] -
                                                         1], "not capped."

        if num_uncapped_bonds > 0:
            print num_uncapped_bonds, " bonds not capped. "
            raise PyAdfError('Not all bonds capped in partition_protein')
예제 #20
0
def parse_smarts(smarts):
    "Parse a SMARTS into an ObSmartsPattern"
    pat = ob.OBSmartsPattern()
    assert pat.Init(smarts)
    return pat
예제 #21
0
def make_structure(request):
    def makeResidue(mol, idx, aaatoms):
        res = mol.NewResidue()
        res.SetNum(idx)
        for atom in ob.OBMolAtomIter(mol):
            if atom.GetIdx() not in aaatoms:
                res.AddAtom(atom)

    aminoacids = request.GET.getlist("as")
    color = request.GET.get("rescol", "#3EC1CD")

    mol = ob.OBMol()
    conv = ob.OBConversion()
    pattern = ob.OBSmartsPattern()
    pattern.Init("[NX3][$([CX4H1]([*])),$([CX4H2])][CX3](=[OX1])[OX2]")
    builder = ob.OBBuilder()
    conv.SetInAndOutFormats("sdf", "svg")
    conv.AddOption("d", ob.OBConversion.OUTOPTIONS)
    conv.AddOption("b", ob.OBConversion.OUTOPTIONS, "none")
    conv.ReadString(mol, str(Substrate.objects.get(pk=int(aminoacids[0])).structure))
    pattern.Match(mol)
    mollist = pattern.GetUMapList()[0]
    oatom = mol.GetAtom(mollist[4])
    catom = mol.GetAtom(mollist[2])
    firstnatom = mol.GetAtom(mollist[0])
    makeResidue(mol, 0, mollist)

    i = 1
    for aa in aminoacids[1:]:
        mol2 = ob.OBMol()
        conv.ReadString(mol2, str(Substrate.objects.get(pk=int(aa)).structure))
        pattern.Match(mol2)
        mollist = pattern.GetUMapList()[0]
        makeResidue(mol2, i, mollist)

        molnatoms = mol.NumAtoms()
        mol += mol2

        natom = mol.GetAtom(molnatoms + mol2.GetAtom(mollist[0]).GetIdx())

        builder.Connect(mol, catom.GetIdx(), natom.GetIdx())

        foatom = mol.GetAtom(molnatoms + mol2.GetAtom(mollist[4]).GetIdx())
        catom = mol.GetAtom(molnatoms + mol2.GetAtom(mollist[2]).GetIdx())
        mol.DeleteHydrogens(oatom)
        mol.DeleteAtom(oatom)

        natom.SetImplicitValence(3)
        mol.DeleteHydrogens(natom)
        mol.AddHydrogens(natom)
        oatom = foatom

        i += 1

    nidx = firstnatom.GetIdx()
    oidx =  oatom.GetIdx()
    builder.Build(mol)
    natom = mol.GetAtom(nidx)
    oatom = mol.GetAtom(oidx)
    for res in ob.OBResidueIter(mol):
        for atom in ob.OBResidueAtomIter(res):
            for bond in ob.OBAtomBondIter(atom):
                data = ob.OBPairData()
                data.SetAttribute("color")
                data.SetValue(color)
                bond.CloneData(data)
    mol.DeleteHydrogens()
    gen2d = ob.OBOp.FindType("gen2d")
    gen2d.Do(mol)

    opp = oatom.GetY() - natom.GetY()
    adj = oatom.GetX() - natom.GetX()
    angle = abs(math.atan(opp / adj))
    if opp > 0 and adj > 0:
        pass
    elif opp > 0 and adj < 0:
        angle = math.pi - angle
    elif opp < 0 and adj < 0:
        angle = math.pi + angle
    elif opp < 0 and adj > 0:
        angle = 2 * math.pi - angle
    angle = -angle
    mol.Rotate(ob.double_array([math.cos(angle), -math.sin(angle), 0,
                                math.sin(angle), math.cos(angle),  0,
                                0,               0,                1]))
    svg = conv.WriteString(mol)
    # need to get rid of square aspect ratio
    delstart = svg.find("width")
    delend = svg.find("svg", delstart)
    delend = svg.find("viewBox", delend)
    svgend = svg.rfind("</g>")
    svg = svg[0:delstart] + svg[delend:svgend]
    return HttpResponse(svg, mimetype="image/svg+xml")
예제 #22
0
 def __init__(self,smartspattern):
     """Initialise with a SMARTS pattern."""
     self.obsmarts = ob.OBSmartsPattern()
     success = self.obsmarts.Init(smartspattern)
     if not success:
         raise IOError("Invalid SMARTS pattern")
예제 #23
0
 def _setupSmartsPattern(self):
     self._pattern = openbabel.OBSmartsPattern()
예제 #24
0
def gen_peditinfile(poltype, mol):
    """
    Intent: Create a file with local frame definitions for each multipole
    These frame definitions are given as input into tinker's poledit
    Input:
        mol: OBMol object
    Output: *-peditin.txt is created
    Referenced By: main
    Description:
    1. Initialize lfzerox, or local-frame-zero-x-component, array
    2. For each atom a
            a. find the two heaviest atoms that a is bound to
               (heaviest defined by their symmetry class; 
               the more atoms an atom is bound to, the higher its symmetry class)
               These two atoms define the local frame for atom a
            b. This information is stored in the localframe1 and localframe2 arrays
    3. If atom a is bound to two atoms of the same symm class (that aren't Hydrogens),
       use these two atoms to define the frame
    4. Find the atoms that are only bound to one atom and define their local frame 
       based on the local frame of the one atom they are bound to. 
    5. Zero out the x-component of the local frame if there is more than one choice for the 
       x-component
       Note: If the atom is only bound to one atom, then the array lfzerox is altered
       If the atom is bound to more than one atom, then the array lf2write is altered
       Related to how poledit handles the local frames of atoms with valence 1
    6. Define bisectors; i.e. local frames where both components belong to the same sym class
    7. Write out frames to *-peditin.txt
    8. Write out polarizabilities for certain atom types
    9. Define polarizability groups by 'cutting' certain bonds
       The openbabel method, IsRotor() is used to decide whether a bond is cut or not
    """
    lfzerox = [False] * mol.NumAtoms()
    atomindextoremovedipquad = {
    }  # for methane need to make dipole and quadupole on the carbon zeroed out, will return this for post proccesing the keyfile after poledit is run
    atomindextoremovedipquadcross = {}
    atomtypetospecialtrace = {
    }  # for H on CH4 need to make sure Qxx=Qyy=-1/2*Qzz
    idxtobisecthenzbool = {}
    idxtobisectidxs = {}
    idxtotrisecbool = {}
    idxtotrisectidxs = {}
    # Assign local frame for atom a based on the symmetry classes of the atoms it is bound to

    for a in openbabel.OBMolAtomIter(mol):
        # iterate over the atoms that a is bound to
        for b in openbabel.OBAtomAtomIter(a):
            lf1 = poltype.localframe1[a.GetIdx() -
                                      1]  # defined to be zero at first?
            lf2 = poltype.localframe2[a.GetIdx() -
                                      1]  # defined to be zero at first?
            # Sort list based on symmetry class, largest first
            a1 = sorted(
                (lf1, lf2, b.GetIdx()),
                key=lambda x: symm.get_symm_class(poltype, x),
                reverse=True)  # the lf1 and lf2 return -1 via get_symm_class
            while a1[
                    0] == 0:  # redundant if you got the order (reverse or not ) in previous line
                a1 = rotate_list(a1)
            # Set localframe1 and localframe2 for atom a to be the first two atoms
            # of the above sorted list 'a1'
            poltype.localframe1[a.GetIdx() - 1] = a1[
                0]  # highest neighboring symmetry class gets stored as local frame 1
            poltype.localframe2[a.GetIdx() - 1] = a1[1]  # next highest is 2
    # if a is bound to two atoms of the same symmetry class that aren't hydrogens
    # use these two atoms to define the local frame
    for a in openbabel.OBMolAtomIter(
            mol):  # it seems that this case is not handled by above case
        classlist = {}
        for b in openbabel.OBAtomAtomIter(a):
            if b.GetAtomicNum() != 1:
                clsidx = poltype.symmetryclass[b.GetIdx() - 1]
                if clsidx not in classlist:
                    classlist[clsidx] = []
                classlist[clsidx].append(b.GetIdx())
        for clstype in classlist.values():
            if len(clstype) > 1:
                poltype.localframe1[a.GetIdx() - 1] = clstype[0]
                poltype.localframe2[a.GetIdx() - 1] = clstype[1]

    # Find atoms bonded to only one atom
    iteratom = openbabel.OBMolAtomIter(mol)
    for a in iteratom:
        lfa1 = poltype.localframe1[a.GetIdx() - 1]
        lfa2 = poltype.localframe2[a.GetIdx() - 1]
        lfb1 = poltype.localframe1[lfa1 - 1]
        lfb2 = poltype.localframe2[lfa1 - 1]

        if a.GetValence() == 1:
            # Set lfa2 to the other atom (the atom that isn't 'a') in the local frame of atom 'b'
            if lfb1 != a.GetIdx() and symm.get_symm_class(
                    poltype, lfb1) != symm.get_symm_class(
                        poltype, lfa1):  # make sure they are not the same type
                poltype.localframe2[a.GetIdx() - 1] = lfb1
            elif lfb1 == a.GetIdx():
                poltype.localframe2[a.GetIdx() - 1] = lfb2

    atomiter = openbabel.OBMolAtomIter(mol)
    lf2write = list(poltype.localframe2)
    for a in atomiter:
        idxtobisecthenzbool[a.GetIdx()] = False
        idxtotrisecbool[a.GetIdx()] = False
    for atom in openbabel.OBMolAtomIter(mol):
        atomidx = atom.GetIdx()
        val = atom.GetValence()
        atomneighbs = [neighb for neighb in openbabel.OBAtomAtomIter(atom)]
        lf1 = poltype.localframe1[atomidx - 1]
        lf2 = poltype.localframe2[atomidx - 1]
        lf1atom = mol.GetAtom(lf1)
        lf2atom = mol.GetAtom(lf2)
        lf1val = lf1atom.GetValence()
        lf1neighbs = [neighb for neighb in openbabel.OBAtomAtomIter(lf1atom)]
        lf1neighbsnota = RemoveFromList(poltype, lf1neighbs, atom)
        neighbsnotlf1 = RemoveFromList(poltype, atomneighbs, lf1atom)
        lf1neighbsallsameclass = CheckIfAllAtomsSameClass(poltype, lf1neighbs)
    # write out the local frames
    iteratom = openbabel.OBMolAtomIter(mol)
    if not os.path.isfile(poltype.peditinfile):
        f = open(poltype.peditinfile, 'w')
        f.write("\n")
        f.write('A\n')

        #Find aromatic carbon, halogens, and bonded hydrogens to correct polarizability
        iteratom = openbabel.OBMolAtomIter(mol)
        writesection = False
        lines = []
        for a in iteratom:
            if (a.GetAtomicNum() == 6 and a.IsAromatic()):
                lines.append(str(a.GetIdx()) + " " + str(1.750) + "\n")
                writesection = True
            elif (a.GetAtomicNum() == 9):
                lines.append(str(a.GetIdx()) + " " + str(0.507) + "\n")
                writesection = True
            elif (a.GetAtomicNum() == 17):
                lines.append(str(a.GetIdx()) + " " + str(2.500) + "\n")
                writesection = True
            elif (a.GetAtomicNum() == 35):
                lines.append(str(a.GetIdx()) + " " + str(3.595) + "\n")
                writesection = True
            elif (a.GetAtomicNum() == 1):
                iteratomatom = openbabel.OBAtomAtomIter(a)
                for b in iteratomatom:
                    if (b.GetAtomicNum() == 6 and b.IsAromatic()):
                        lines.append(str(a.GetIdx()) + " " + str(0.696) + "\n")
                        writesection = True
        if writesection == True:
            for line in lines:
                f.write(line)

        # Carboxylate ion O-
        sp = openbabel.OBSmartsPattern()
        openbabel.OBSmartsPattern.Init(sp, '[OD1]~C~[OD1]')
        sp.Match(mol)
        for ia in sp.GetMapList():
            f.write(str(ia[0]) + " " + str(0.921) + "\n")

        f.write("\n")
        f.flush()
        os.fsync(f.fileno())
        #Define polarizable groups by cutting bonds
        iterbond = openbabel.OBMolBondIter(mol)
        for b in iterbond:
            if (b.IsRotor()):
                cut_bond = True
                # If in this group, then don't cut bond
                cut_bond = cut_bond and (not is_in_polargroup(
                    poltype, mol, 'a[CH2][*]', b, f))
                cut_bond = cut_bond and (not is_in_polargroup(
                    poltype, mol, '[#6]O-[#1]', b, f))
                #cut_bond = cut_bond and (not is_in_polargroup(mol,'[#6][#6]~O', b,f))
                # Formamide RC=O
                cut_bond = cut_bond and (not is_in_polargroup(
                    poltype, mol, '[*][CH]=O', b, f))
                # Amide
                cut_bond = cut_bond and (not is_in_polargroup(
                    poltype, mol, 'N(C=O)', b, f))
                cut_bond = cut_bond and (not is_in_polargroup(
                    poltype, mol, 'C(C=O)', b, f))
                cut_bond = cut_bond and (not is_in_polargroup(
                    poltype, mol, 'aN', b, f))
                cut_bond = cut_bond and (not is_in_polargroup(
                    poltype, mol, 'O-[*]', b, f))
                #cut_bond = cut_bond and (not is_in_polargroup(mol,'C[NH2]', b,f))
                if (cut_bond):
                    f.write(
                        str(b.GetBeginAtomIdx()) + " " +
                        str(b.GetEndAtomIdx()) + "\n")

        f.write("\nN\n")
        f.write("\nN\n")

        f.flush()
        os.fsync(f.fileno())
        f.close()
    return lfzerox, atomindextoremovedipquad, atomtypetospecialtrace, atomindextoremovedipquadcross
예제 #25
0
                "Shannon R" + str(rnum) + " neutral",
                "Shannon R" + str(rnum) + " red"
            ])
        RCentre = np.array([0.0, 0.0, 0.0])
        for id in ring._path:
            at = mol.GetAtom(id)
            RCentre += np.array([at.GetX(), at.GetY(), at.GetZ()])
        RCentre /= ring.Size()

        ex = [homaring, seed + ".log"]
        hr = []
        for atom in list(sorted(ring._path)):
            hr.append(str(atom))
            rings.append(atom)
        ex.extend(hr)
        obpat = ob.OBSmartsPattern()
        obpat.Init("C=O")
        obpat.Match(mol)
        # avoid getting lots of <openbabel.vectorvInt; proxy ... > etc.
        matches = [m for m in obpat.GetUMapList()]
        quins = []
        for match in matches:
            if match[0] in rings: quins.append(match[1])
        homas = []
        flus = []
        pdis = []
        shans = []
        out = subprocess.Popen(ex,
                               stdout=subprocess.PIPE).stdout.read().split()
        homas.append(out[1])
        ex[0] = fluring
예제 #26
0
 def __init__(self, smartspattern):
     """Initialise with a SMARTS pattern."""
     self.obsmarts = ob.OBSmartsPattern()
     self.obsmarts.Init(smartspattern)