Create Schema frowns; Grant All On Schema frowns to public; Create Or Replace Function frowns.valid(smi Text) Returns Boolean As $EOPY$ from frowns import Smiles try: mol = Smiles.smilin(smi) return True except: return False $EOPY$ Language plpythonu Immutable; Create Or Replace Function frowns.cansmiles(smi Text) Returns Text As $EOPY$ from frowns import Smiles mol = Smiles.smilin(smi) return mol.cansmiles() $EOPY$ Language plpythonu Immutable; Create Or Replace Function frowns.smiles_to_symbols(smi Text) Returns Text[] As $EOPY$ from frowns import Smiles mol = Smiles.smilin(smi) return "{" + ",".join((a.symbol for a in mol.atoms)) + "}" $EOPY$ Language plpythonu Immutable; Create Or Replace Function frowns.smiles_to_bonds(smi Text) Returns Integer[][2] As $EOPY$ from frowns import Smiles mol = Smiles.smilin(smi) iatom = 0 return "{" + ",".join( \ [ "{" + ",".join((str(b.atoms[0].index+1),str(b.atoms[1].index+1),str(b.bondtype))) + "}" for b in mol.bonds ] \ ) + "}" $EOPY$ Language plpythonu Immutable; Create Or Replace Function frowns.smiles_to_molfile(smi Text, name Text, coords Numeric[][]) Returns Text As $EOPY$ from frowns import Smiles # just get the molfile format right. # stereochemistry missing; charges only appear in CHG records mol = Smiles.smilin(smi) (x,y,z) = (0.0, 0.0, 0.0) if name is None: tname = "" else: tname = name if coords is not None: tcoords = eval( (coords.replace('{','[')).replace('}',']') ) molfile = []; molfile.append(tname) molfile.append(' gNova FROWNS smiles_to_molfile') molfile.append(smi) atoms = mol.atoms bonds = mol.bonds molfile.append("%3d%3d%3d%3d%3d%3d%3d%3d%3d%6d V%4d" % (len(atoms), len(bonds), 0, 0, 0, 0, 0, 0, 0, 999, 2000)) # oddball mapping of charges #cmap[-3] = 7 #cmap[-2] = 6 #cmap[-1] = 5 #cmap[0] = 0 #cmap[1] = 3 #cmap[2] = 2 #cmap[3] = 1 cmap = [7,6,5,0,3,2,1] for a in atoms: if coords is not None: (x,y,z) = (tcoords[a.index][0], tcoords[a.index][1], tcoords[a.index][2]) molfile.append(" %9.4f %9.4f %9.4f %-2s%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d" % (x,y,z, a.symbol, 0,cmap[3+a.charge],0,0,0,0,0,0,0,0,0,0)) for b in bonds: molfile.append("%3d%3d%3d%3d%3d%3d%3d" % (b.atoms[0].index+1, b.atoms[1].index+1, b.bondtype,0,0,0,0)) for a in atoms: if a.charge: molfile.append("M CHG%3d %3d %3d" % (1, a.index+1, a.charge)) molfile.append("M END") molfile.append("$$$$") return "\n".join(molfile) $EOPY$ Language plpythonu; Create Or Replace Function frowns.smiles_to_molfile(smi Text, name Text) Returns Text As $EOSQL$ Select frowns.smiles_to_molfile($1, $2, null); $EOSQL$ Language SQL; Create Or Replace Function frowns.smiles_to_molfile(smi Text) Returns Text As $EOSQL$ Select frowns.smiles_to_molfile($1, null, null); $EOSQL$ Language SQL; Create Or Replace Function frowns.molfile_to_smiles(molfile Text) Returns Text As $EOPY$ from frowns import MDL from frowns import Smiles from frowns.mdl_parsers import Generator import StringIO import sys #fd = StringIO.StringIO(molfile + "\n$$$$") fd = StringIO.StringIO(molfile) reader = MDL.sdin(fd) mol, text, error = reader.next() fd.close() if not mol: print "Error parsing molfile" print error + text return None else: # sometimes mol.cansmiles emits [C] when C is proper, this seems to fix that return frowns.Generator.INDEX #return (Smiles.smilin(mol.cansmiles())).cansmiles() #raise ValueError("Error parsing molfile") return None $EOPY$ Language plpythonu Immutable; Drop Type frowns.named_property Cascade; Create Type frowns.named_property As (name Text, value Text); Create Or Replace Function frowns.molfile_properties(molfile Text) Returns Setof frowns.named_property As $EOPY$ from frowns import MDL import StringIO fd = StringIO.StringIO(molfile + "\n$$$$") for mol, text, error in MDL.sdin(fd): if not mol: print error + text return None else: #mol.fields["cansmiles"] = mol.cansmiles() return mol.fields.items() print "Error parsing molfile" #raise ValueError("Error parsing molfile") return None $EOPY$ Language plpythonu Immutable; Create Or Replace Function frowns.matches(smi Text, sma Text) Returns Boolean As $EOPY$ from frowns import Smiles from frowns import Smarts mol = Smiles.smilin(smi) pat = Smarts.compile(sma) match = pat.match(mol) try: assert match return True except: return False $EOPY$ Language plpythonu Immutable; Create Or Replace Function frowns.count_matches(smi Text, sma Text) Returns Integer As $EOPY$ from frowns import Smiles from frowns import Smarts mol = Smiles.smilin(smi) pat = Smarts.compile(sma) match = pat.match(mol) try: assert match imatch = 0 for path in match: imatch += 1 return imatch except: return 0 $EOPY$ Language plpythonu Immutable; Create Or Replace Function frowns.list_matches(smi Text, sma Text, imatch Integer, istart Integer) Returns Integer[] As $EOPY$ from frowns import Smiles from frowns import Smarts mol = Smiles.smilin(smi) pat = Smarts.compile(sma) try: match = pat.match(mol) assert match except: return '{null}' all_matches = list() nmatch = 0 for path in match: nmatch += 1 matches = [a.index+1 for a in path.atoms] pgarray = "{" + ",".join([str(i-1+istart) for i in matches]) + "}" if (nmatch == imatch): return pgarray all_matches.append(pgarray) return "{"+ ",".join(all_matches)+ "}" $EOPY$ Language plpythonu Immutable; Create Or Replace Function frowns.list_matches(Text, Text) Returns Integer[] As $EOSQL$ Select frowns.list_matches($1, $2, 1, 0); $EOSQL$ Language SQL Immutable; Create Or Replace Function frowns.list_matches(Text, Text, Integer) Returns Integer[] As $EOSQL$ Select frowns.list_matches($1, $2, $3, 0); $EOSQL$ Language SQL Immutable; Create Or Replace Function frowns.fp(smi Text, nbits Integer, maxpath Integer) Returns Bit As $EOPY$ from frowns import Fingerprint from frowns import Smiles mol = Smiles.smilin(smi) numints = nbits / 32 fp = Fingerprint.generateFingerprint(mol, numInts=numints, pathLength=maxpath) return "".join([str(bit) for bit in fp.to_list()]) $EOPY$ Language plpythonu Immutable; Create Or Replace Function frowns.fp(smi Text) Returns Bit As $EOSQL$ Select frowns.fp($1, 512, 7); $EOSQL$ Language SQL Immutable; Create or Replace FUNCTION frowns.contains(Bit, Bit) Returns Boolean As $EOSQL$ Select $2 = ($1 & $2); $EOSQL$ Language SQL Immutable; Comment On FUNCTION frowns.contains(bit, bit) Is 'does first bit string contain all the bits of second'; -- get all info from molfiles in one record for insert into a table -- see frowns.sql for an example of using frowns.molfile_mol() to -- insert into a table Drop Type frowns.mol Cascade; Create Type frowns.mol As (name Text, cansmiles Text, coords Numeric[][], atoms Integer[]); Create Or Replace Function frowns.molfile_mol(molfile Text) Returns frowns.mol As $EOPY$ from frowns import MDL from frowns import Smiles import StringIO fd = StringIO.StringIO(molfile + "\n$$$$") for mol, text, error in MDL.sdin(fd): if not mol: print error + text return None else: # sometimes mol.cansmiles emits [C] when C is proper, amol seems to fix that amol = Smiles.smilin(mol.cansmiles()) return (mol.name, amol.cansmiles(), \ "{" + ",".join(["{"+str(a.x)+","+str(a.y)+","+str(a.z)+"}" \ for a in mol.canonical_list[0][1]]) + "}" , \ "{" + ",".join([str(a.index+1) \ for a in mol.canonical_list[0][1]]) + "}" ) print "Error parsing molfile" #raise ValueError("Error parsing molfile") return None $EOPY$ Language plpythonu Immutable; Create Or Replace Function frowns.graph(smi Text) Returns Text As $EOPY$ from frowns import Smiles try: mol = Smiles.smilin(smi) except: return None hcount = 0 for b in mol.bonds: b.bondorder = b.bondtype = 1 b.aromatic = 0 for a in mol.atoms: hcount += a.hcount a.aromatic = 0 a.charge = 0 nbonds = len(a.bonds) if a.valences: a.imp_hcount = a.hcount = a.valences[0] - nbonds return mol.cansmiles() + '.H' + str(hcount) $EOPY$ Language plpythonu Immutable;