12012010 chemoinformatics Python
というエントリをケモインフォクックブックにのせておきました。
12012010 chemoinformatics Python
というエントリをケモインフォクックブックにのせておきました。
12012010 chemoinformatics bioinformatics Python
AMMOSというinduced fitを考慮したドッキングツールがopen sourceででるそうです。
AMMOS: Automated Molecular Mechanics Optimization tool for in silico Screening
ダウンロードできるようになったら試してみよう。DUDみたいなドッキングシミュレーションのベンチマーク用のデータベースもそろってきてるし、そろそろ今時のインターフェースで使いやすいドッキングシミュレーションツールのプロジェクトなど立ち上がりそうな気もしますが(もうなにか動いてるのかな)。
12012010 chemoinformatics Python
openbabelだったらobgenをつかえばいい。
pythonバインディングからやりたかったので、obgen.cppをよんだらOBBuilderクラスのインスタンスを生成すればいいらしいのだが、pythonからは現状OBBuilderのインスタンスをつくれないらしい。
MLを検索すると似たようなやりとりがあって、ラッパーを使えばいいらしく、pybelのソース見ろやーって書いてあったのでみた。
OPSってのは新たに導入された簡易プラグインシステムらしい。
で、ケモインフォクックブックにコードのせといた。
IPアドレスに応じて色を変えられるのであれば、アクセスログをLEDで光らせればいいんではなかろうか?と思ったので。
参考
Gainerのほうは秋月で買ったカソードのフルカラーLEDを刺した。抵抗は全て330Ω(それしかなかった)でピンポン球はダイソーかどっかで買った6個入り100円のヤツを錐とドライバーでぐりぐりした。

という単純な配線。
アクセスログは自宅サーバーに直接アクセスしてIPアドレスを返すようなCGIを用意した。 今回初めてPyGainerを使ってみた。
import sha,struct,urllib2,time,sys
from time import sleep
from PyGainer import PyGainer
#from random import randint
p = '/dev/cu.usbserial-A2002mCa'
g = PyGainer()
config = { 'baudrate' : 38400, 'timeout' : 5 }
#def rand_rgb():
# return(randint(0,255),randint(0,255),randint(0,255))
def get_rgb():
ip = urllib2.urlopen('http://myserver/taillog.cgi').read()
print ''.join(ip.split('.'))
s = sha.new(ip).digest()
code = struct.unpack('5L',s)[0]
blue = int((code >> 6) & 0x0ff)
green = int((code >> 15) & 0x0ff)
red = int((code >> 24) & 0x0ff)
return (blue,green,red)
if g.open(p, config) == 0:
if g.reset() == True:
print "RESET"
else:
print "ERROR"
sleep(0.1)
g.version()
g.configuration(1)
sleep(0.1)
for i in range(100):
(blue,green,red) = get_rgb()
g.set_specified_analog_output_port(0, green) # G
g.set_specified_analog_output_port(1, blue ) # B
g.set_specified_analog_output_port(3, red ) # R
sleep(3)
g.set_specified_analog_output_port(0,0)
g.set_specified_analog_output_port(1,0)
g.set_specified_analog_output_port(3,0)
g.close()
動かした。うしろでカチャカチャうるさいのは犬が晩ご飯を催促している音。
Identiconでいうところのパターンのようなものの表現は点滅で実装しようかと思ったが、それって分かりにくいよなと。もう少し面白そうなデバイスはなかろうか。
12012010 chemoinformatics perl Python
bioinformaticsの学習道路はそこそこ充実している。
でも、chemoinformaticsだってオープンソースで色々できるし、独学でも結構いけるよ!なんて思うんだけど情報が足りないなぁと思った。
というわけで、ちょっと小道でも。
特にperl,pythonでちょっとした化学情報をいじるコードをクックブック形式で書いていけたらなぁなんて思ってる。
週に一回くらいは更新するつもりで。
12012010 chemoinformatics Python
MolBlasterは細切れにして、頻度を返さないといけないんだが、Separateメソッドがバグッてるらしいので、canonical smilesで出してpythonのほうで.でsplitして頻度をみてみた
import openbabel as ob
from random import sample
def randomsplit(mol,cutnum=5):
cutlist = sample(range(mol.NumBonds()),cutnum)
delbonds = []
for i,bond in enumerate(ob.OBMolBondIter(mol)):
if i in cutlist: delbonds.append(bond)
for b in delbonds: mol.DeleteBond(b)
return mol
def molblast(smi,iter=100,cutnum=5):
obc = ob.OBConversion()
obc.SetInAndOutFormats('smi','smi')
obc.AddOption('c',ob.OBConversion.OUTOPTIONS)
freq = {}
for i in range(iter):
mol = ob.OBMol()
obc.ReadString(mol,smi)
for fragment in obc.WriteString(randomsplit(mol,cutnum=cutnum))[:-2].split('.'):
freq[fragment] = freq.get(fragment,0) + 1
return freq
if __name__ == "__main__":
smiles = 'CCC(C)C(=O)OC1CC(C=C2C1C(C(C=C2)C)CCC(CC(CC(=O)O)O)O)O'
print molblast(smiles,iter=1000,cutnum=20)
こんな感じ。
{'CCCCC=CC': 2, 'O=COCCC': 1, 'CCC=C(C)C(C)CC': 1, 'CCC(=O)O': 26, 'CCCCC(C)O':
2, 'CCO': 459, 'CC=CCC(C)C': 2, 'CCC=CC(C)O': 2, 'CCCCC(C)C': 4, 'CCC': 705,
'CCC=CC=CCC': 1, 'OCCCCC': 10, 'OCCC(C)OC': 1, 'C=CC=CCC': 2, 'CCCC(=C)C': 3,
...
細切れにしないと頻度が稼げないし、細切れにするとファーマコフォア的な構造特徴が失われてしまう感じだ。というわけで、やってみて分かったけど、多分この方法だと実用的じゃないなぁ。Fragment Dependency Graphとかは面白そうなんだけどなぁ。
12012010 chemoinformatics Python openbabel
Molblasterっていうのは化学構造をランダムに切断していくっていう試行を何度か繰り返す方法で、その後フラグメントの頻度をシャノンエントロピーで評価したりするらしい。
シャノンエントロピーのほうに興味があったのとちょっと簡単に実装できそうだったのでpython+openbabelでやってみた。
まぁでも、構造活性相関にもっていくんだったら普通はベイズの方にいくよなぁ。多分著者の論文あると思うんだけど調べてない。
12012010 chemoinformatics Python
Topological Fragment Indexというものが気になったので。
論文はこれでToFIを尤度として捉えているらしい。
式は

ここで、nは全ボンド数。kはフラグメントについてる余計なボンド。lをフラグメントのボンド数としてm=k+lとなっている。
def combination(n,m):
if m == 0:
return 1.0
else:
return reduce(lambda x,y:x*y,range(n-m+1,n+1)) / float(reduce(lambda x,y:x*y,range(1,m+1)))
def tofi(n,m,k):
sum = 0.0
for i in range(n-m+1):
sum += combination(n-m,i) / combination(n,k+i)
return sum/(n+1)
で、整数にするために1*10^6という定数をかけるらしいのだが、なにがしたいのかよくわからん。
lが一定でkが増えるとToFIが減る
>>> tofi.tofi(23,17,5) * 1000000
8.9779501544207427
>>> tofi.tofi(23,18,6) * 1000000
2.8351421540276029
>>> tofi.tofi(23,19,7) * 1000000
0.99229975390966119
kが一定でlが減るとToFIが増える
>>> tofi.tofi(23,17,5) * 1000000
8.9779501544207427
>>> tofi.tofi(23,16,5) * 1000000
13.466925231631114
>>> tofi.tofi(23,15,5) * 1000000
20.812520812520813
後者はなんとなく理解できるけど、切断面が大きくなるほどToFIが減るってのがわからん。
計算間違ってるのかなぁ。
12012010 chemoinformatics bioinformatics Python
NMFを追っかけてたらMetagenes and molecular pattern discovery using matrix factorizationという論文を見つけたので、週末はこの論文を読みながら色々やってみた。NMFの便利なところは元の特徴(この論文の場合は遺伝子発現量)からより少ない任意の特徴量(論文中ではmetagene)に変換できるところであり、さらにそのままクラスターの分割に利用できる。
たとえば2つのmetageneで表現した場合、より発現量の大きいmetageneで分割すれば2つのクラスに分けられる。(QSARだったらdescriptorからmeta discriptorが導かれてそれに基づいてクラス分類ができるでしょう)
続いて、重要なのがクラスの安定性である。要するに最適なクラスタの数はいくつなのかということである。これに対して、この論文ではConsensus Clusteringというリサンプリングと隣接行列(connectivity matrix)を利用する方法をモディファイした方法を使っている。
ここで隣接行列はi番目のサンプルとj番目のサンプルが同じクラスなら1、それ以外なら0である。この行列のn回の平均値をコンセンサスマトリックスとする。コンセンサスマトリックスの値は0-1の間をとり、サンプルi,jが常に同じクラスになる場合は1、常に異なるクラスの場合は0である。フラフラするばあいはその間の値をとる。元の論文のconsensus clusteringアルゴリズムはデータの80%をランダムサンプリングして評価するのに対し、NMFの場合、初期値の行列はランダムな数字にしているので適当にループ(n)をまわすだけでよい。
NMFの実装は集合知プログラミングのものを用い、コンセンサスマトリックスを評価するコードをnumpyを使ってかいた。
import nmf
from numpy import *
def consensus(a,kstart,kend,nloop):
""" calculate consensus matrix
"""
(n,m) = a.shape
consensus = zeros((kend+1,m,m))
conn = zeros((m,m))
#i = 0
for j in range(kstart,kend+1):
connac = zeros((m,m))
for l in range(nloop):
#i += 1
(w,h) = nmf.factorize(a,pc=j)
conn = nmfconnectivity(h)
connac = connac + conn
consensus[j] = connac / float(nloop)
return consensus
def nmfconnectivity(h):
""" calculate connective matrix
"""
(k,m) = h.shape
ar = []
for i in range(m):
max_i = 0
max_v = 0
for index,v in enumerate(h[:,i]):
if v > max_v :
max_v = v
max_i = index
ar.append(max_i)
mat1 = tile(matrix(ar),(m,1))
mat2 = tile(matrix(ar).T,(1,m))
return array(mat1 == mat2, dtype=int)
これをcc.pyという名前で保存しテスト用のセットを適当に用意して実行。
from numpy import *
from pylab import *
import cc
kstart = 2
kend = 4
testarray = array([[0,0,1,1,1,0,0,0,0],
[0,0,1,1,0,0,0,0,0],
[1,1,0,0,1,1,0,0,1],
[1,1,0,0,0,0,0,1,0],
[1,1,0,1,0,0,0,0,0],
[0,0,0,0,0,1,1,1,1],
[1,0,0,0,0,1,1,1,0],
[0,0,0,0,0,0,1,1,1],
[0,0,0,1,0,1,1,1,1]
])
cons = cc.consensus(testarray.T,kstart,kend+1,20)
for i in range(kstart,kend+1):
pcolormesh(cons[i])
if i == kstart:
colorbar()
savefig('ccr' + str(i) + '.png')
見ればすぐ分かるが3つにクラスタリングできそうなマトリックス。
結果
2クラスタで分けた場合。

3クラスタで分けた場合

4クラスタで分けた場合

もうちょっと実際のデータでやってみないとあれだなぁ。それとConsensus ClusteringのCDFプロットみたいなのが欲しいところ。
参考書籍
参考論文
12012010 Python matplotlib
ちょっと描きたいものがあったので調べたらpcolormeshを使えばいいだけだった。
from numpy import *
from pylab import *
a = rand(100,100)
pcolormesh(a)
colorbar()
savefig('colour.png')
