2009年12月25日金曜日

OpenBabel:SuperCanonicalizer()

前回はSmilesの/と\で表現される立体異性体の問題を解決してOKかと思ったのですが、またも落とし穴を発見。

それは@です。

@と@@は原子のChirality(鏡像異性)を表してあり、それぞれ反時計回り、時計回りのChiralを表します。

SuperCanonicalをするためにはこのChiralityを取り除く必要があります。

OpenBabelのOBMolクラスにはIsChiral()というMethodがあり原子がChiralかどうか判定できます。これがTrueのときにUnsetStereo()を適用することでChiralを消すことが出来ます。


2009年12月18日金曜日

OpenBabel : Frameworkerを作ろう

FrameWorkを作るには各Fragmentの結合の組み合わせをすべてもれなくPick Upする必要があります。

たとえば下記のFragment構造を持った分子の場合、



可能な組み合わせは
A,B,C,D,E,F
A-B,B-C,B-D,D-E,D-F
A-B-C,A-B-D,C-B-D,B-D-E,B-D-F,D-E-F
・・・
などと組み合わせていく必要があります。

6Fragmentからなる分子の場合で3Fragmentから成るFrameworkは6C3=6*5*4/(3*2*1) = 20通りのなかから連結したFragmentを探すことになります。これらを1~Fragment数分の組み合わせを探すことが必要です。

最初は各Fragmentの連結情報からFragment長にあう組み合わせを網羅的にかつ有機的に探していこうとしました。しかし、分岐問題をスマートに解決する手法がなかなか思いつかず、それならすべての組み合わせの中からちゃんと連結したFragmentを組み合わせを探して、それをFrameWorkとしよう、ということにしました。

これなら、ちょっとだけ時間はかかるけど漏れなくFrameWorkを探せるな、ということです。


2009年12月17日木曜日

OpenBabel:SuperCanonicalizer()

前回は価数の超過に対応して、もうこれで大丈夫と思ったのですが、またまた落とし穴を発見。

今回はStereo Isomerです。

Smilesでは/はUpper Bond、\はDown Bondを表します。これらもinchiで除けるかと思ったのですがだめでした。inchiをかえしてもUpper/Downはそのままでした。

これは一発のコマンドではどうしようもなかったので

foreach (OBBond oneBond in Mol.Bonds())
{
    if(OneBond.IsUp()){oneBond.UnsetUp();}
    if(OneBond.IsDown()){oneBond.UnsetDown();}
}

というような感じで、一個一個Bondをチェックして標準化しました。

しかし、SmilesのくせにStereo Isomerを表現するとは生意気だ。

まだ落とし穴があるかも・・・。

2009年12月16日水曜日

OpenBabel:Tautomer(互変異性)を標準化する

前回、Tautomer(互変異性)を標準化する関数を作ったのですが、落とし穴がありました。

よくあることなのですが、自動で部分構造をSmilesで切り出す際に、原子の価数が超過してしまうことがあります。たとえばこのような構造が出力されることがあります。



この分子の原子のうちSは価数を超えているのでS+と表記すべきですが、Smilesではそのような表現がされないまま出力されてしまいます。これを先日のTautomersStandardizerにかけても修正されません。修正されないどころか、場合によっては芳香性もなくなって変な脂溶性構造になることまであります。こわい。

しかし、変換前に水素を全部取ってやるとちゃんとした




になることがわかりました。

ついでに関数名も変えて、Canonicalで出力するようにしてます。



static string SuperCanonicalizer(string inSmiles)
{
OBMol mol = new OBMol();
OBConversion obconvSmiToInchi = new OBConversion();
OBConversion obconvInchiToSmi = new OBConversion();

obconvSmiToInchi.SetInFormat("smi");
obconvSmiToInchi.SetOutFormat("inchi");
obconvInchiToSmi.SetInFormat("inchi");
obconvInchiToSmi.SetOutFormat("can");

obconvSmiToInchi.ReadString(mol, inSmiles);
mol.DeleteHydrogens();
obconvInchiToSmi.ReadString(mol,obconvSmiToInchi.WriteString(mol));


return obconvInchiToSmi.WriteString(mol);
}



これでどんなSmilesもすべて標準化できそうです。

2009年12月10日木曜日

OpenBabel:Tautomer(互変異性)を標準化する

芳香環を持つ化合物は共鳴構造を取ることから、表記上複数の構造を取りえます。

しかし、実際はひとつの同じ化合物であり、コンピューター上で構造の重複処理をする際に問題となります。このような、表記上異なる構造であるが同一の構造であることをTautomer(互変異性)といいます。

Smilesで処理するとどうしてもこのTautomer(互変異性)を標準化・同一化することが出来ません。お金を出して専用ソフトを買うとたいていこのTautomer処理機能はついています。

しかしOpenBabelでもその機能を組み合わせるとこのTautomer(互変異性)標準化ができます。

OpenBabelはさまざまな化合物形式をサポートしていますので、これを使ってやってみます。使うのがInChIという構造フォーマットです。

InChIは、立体構造を含めた化合物の構造を一意的に記述することを目的にIUPACと米国の国立標準技術研究所(NIST)が策定した標準。また、機械処理のための短い識別子であるInChIKeyも各化合物に付与される。既に普及している米国化学会のCAS登録番号と異なり、誰でも自由に使えることが特徴。・・・とのことです。

SmilesをいったんInChIに変換するとTautomer(互変異性)は同一の記述になります。そこでそのあとでまたSmilesに戻してやると同じSmilesになるというわけです。

using System;
using OpenBabel;

namespace SmilesTest
{
class Program
{
static OBConversion obconvSmiToInchi = new OBConversion();
static OBConversion obconvInchiToSmi = new OBConversion();

static void Main(string[] args)
{
OBMol tautomer1 = new OBMol();
OBMol tautomer2 = new OBMol();

string smiles1 = "Oc1ccccn1";
string smiles2 = "O=c1cccc[nH]1";

Console.WriteLine(smiles1);
Console.WriteLine(smiles2);

Console.WriteLine(TautomersStandardizer(smiles1));
Console.WriteLine(TautomersStandardizer(smiles2));

Console.In.ReadLine();
}
/// <summary>
/// Tautomers Standardizer
/// 互変異性標準化する関数
/// tautomerの構造の違いをStandarlizeする
/// </summary>
/// <param name="inSmiles">Smiles文字列</param>
/// <returns>標準化Smiles文字列</returns>
static string TautomersStandardizer(string inSmiles)
{
OBMol mol = new OBMol();
OBConversion obconvSmiToInchi = new OBConversion();
OBConversion obconvInchiToSmi = new OBConversion();

obconvSmiToInchi.SetInFormat("smi");
obconvSmiToInchi.SetOutFormat("inchi");
obconvInchiToSmi.SetInFormat("inchi");
obconvInchiToSmi.SetOutFormat("smi");

obconvSmiToInchi.ReadString(mol, inSmiles);
obconvInchiToSmi.ReadString(mol,obconvSmiToInchi.WriteString(mol));


return obconvInchiToSmi.WriteString(mol);
}
}
}

これを実行すると下記のようになります。



やっぱOpenBabeは便利やわ。



2009年12月8日火曜日

OpenBabel:OBMol.Bonds()とDeleteBond()の関係

OpenBabelの分子を表現するClassにOBMolがあります。OpenBabelの最も重要なClassです。

化合物の構造を変換するときなどはOBMolに含まれるMethodをいろいろ使うわけですが、その中のBonds()というMethodがあります。このMethodはMolに含まれるBondすべてのIEnumerableリストを返します。

例えば、その中の特定のBondを切断したければ

foreach(IEnumerable<OBBond> oneBond in inMol.Bonds())
{
if(・・・条件式・・・)
{inMol.DeleteBond(oneBond);}
}

などとやりますが、これでは実は正常に動きません。

DeleteBond()を呼ぶとBonds()で取得できるIEnumerable<OBBond>の中身がどうも変わってしまうようで、一度に複数回DeleteBondをCallすると予期せぬBondが切れてしまいます。

よって、DeleteBondを呼んだあとで、今一度
IEnumerable<OBBond> oneBond in inMol.Bonds()
などでリストを再構築する必要があります。

この原因がわかるのに1日を費やしました(涙)。

2009年12月6日日曜日

卑弥呼の宮へ

今日は卑弥呼に会いに纏向に行きました。

まずは黒塚古墳へ。ここは1997年に三角縁神獣鏡がものすごい数出たということで、三大紙のトップニュースになるほどの大騒ぎになったところです。

これだけまとまった数の神獣鏡が出るのは、間違いなく邪馬台国と関係があるはず、と思われたのですが、やはり鏡しか出なかったということで、邪馬台国大和説の決定的な証拠にはできませんでした。

私も当時現説(現地説明会)に行って、寒空の中3時間並んで、2~3分あっという間通り過ぎるなか、発掘したばかりの古墳を見ました。見たとき、これは間違いなくこの近くに邪馬台国があるはず、とわくわくしたのを思い出します。

その後、資料館が出来て、「鹿男あおによし」でもロケに使われたのは知っていて、今回は古墳は二度目、資料館は初めて行きました。近くの国道のサークルKの裏に専用駐車場もあり、行きやすくなってます。



すごくきれいになっていて、ちゃんと復元された石室が見れます。しかも無料!地域住民の皆さんで運営されているとのこと。感謝です>住民の皆さん。

展示されている三角縁神獣鏡はレプリカですが、近くまで見て写真も取れます。本物は橿原考古学研究所に保管されています(展示はされていないとのことでしたが、あとで行くと何枚か展示されていました)。





三輪そうめん「山本」でお昼を取って、お店お人に車を置きっぱなしにすることをお断りして散策に出かけました。纏向石塚古墳やら纏向勝山古墳を見て、いよいよ今回の「纏向遺跡第166次調査地」へ。先月の巨大施設跡の発掘で大ニュースになった、卑弥呼の宮殿跡です。





説明会は先月に終わってしまっていましたが、桜井市教育委員会の方がいて、たぶん見張りでいるんだと思いますが、一通り説明してくれました。ラッキー!ビニールシート越しでしたが、ここに卑弥呼がいたんだな、ここが大和政権の発祥の地なんだと思うと、感動しきり。


桜井市の人いわく。
  •  現地は個人所有の土地。市が買い上げて史跡公園にするほどの予算はない。
  •  来週には埋め戻して地主に返す。
  •  6月には隣接する土地を調査する予定。
埋め戻して民家かアパートがたってしまうのは非常に残念。国が買い上げて公園化するなどの対応がどうして取れないのか、悲しくなりました。民主党、たばこ税上げてもいいから、保存せよ!


その後は箸墓古墳、橿原考古学研究所を見ました。橿原考古学研究所でも研究所の人と思われる解説ガイドのおじさんが纏向遺跡の発掘に触れながら弥生時代から奈良時代までの展示品を説明してくれて、これまたラッキー!


しかも、前回行った時は藤ノ木古墳の金の装飾品などの副葬品はレプリカだったのが、今回はなんと本物を展示してました。しかも国宝指定なので間違いなく本物!これには感動!


今回はいろいろ「もうかった」ミニ旅行でした。


2009年12月5日土曜日

さかりは過ぎましたが・・・

今日は永観堂~南禅寺~知恩院を散策しました。

出発したときは冷たい雨に凍えましたが、そのうち晴れてきてよかった。

紅葉はさかりを過ぎてはいましたが、人でが少なかったのでゆっくり見れたし、まだ少し紅葉が残っていて、意外とよかったわ。



南禅寺を散策した後、定番の湯豆腐へ。

「奥丹」は混んでたので、「順正」へ。実は順正は初めてだったのですが、庭も見れるしお豆腐はおいしいし、ちょっと儲かった気分。



んでもって、知恩院・青蓮院門跡に国宝の「青不動明王」を見に行きました。

これが混んでるわ、グッズを売りまくってるわ、祈祷受付まくってるわで、さしずめ「仏教テーマパーク」化していて、ちょっとがっかり。

青不動はちゃんと見れましたが、あまりの商売根性丸出しイベントに↓でした。

2009年12月4日金曜日

OpenBabel:Aromaticity

分子がAromaticかどうか知りたいときがありますよね。
そんなときのお気楽関数「Aromaticity」です。

原理は単純。Aromatic原子数/全原子数だけです。
完全Aromatic分子なら1、Aliphaticなら0になるというわけです。

using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Diagnostics;

using OpenBabel;

・・・・・・・

/// <summary>
/// Aromaticity:Aromatic原子数/全原子数
/// </summary>
/// <param name="inMol">OBMolインスタンス</param>
/// <returns>0~1の数値</returns>
public static double Aromaticity(OBMol inMol)
{
int atomCount = 0;
int aromaticAtomCount = 0;
foreach (OBAtom item in inMol.Atoms())
{
if (item.IsAromatic()) { aromaticAtomCount += 1; }
atomCount += 1;
}
return aromaticAtomCount / atomCount;
}

OpenBabel : Frameworkerを作ろう

先日の投稿のフローチャートで致命的な欠点に気付いてしまいました。

先の構想では
  1. 化合物をSmilesで表記する
  2. Smartsを「aA」とする
  3. 化合物をこのSmartsにかけると、Aromatic any atom - Aliphatic any atomで切れる。つまり芳香環とLinkerまたは側鎖の間が切れる
という流れだったのですが、これだと













こんなことになってしまって、せっかくの環構造が切れてしまう。

ということで作戦を修正。








  1. 化合物をSmilesで表記する
  2. 化合物からSSSRを取得し、さらに縮合環をまとめてRing構造を抽出
  3. Ring構造から伸びるBondのうち、Ring外に伸びるBondをすべて切断する。このとき構造を完全に切ってしまうのではなく、「切れ目」の状態で化合物を保持しておく
  4. 切れ目を参考にして、化合物を「Fragment」に分ける
  5. 切れ目を参考にして、FragmentとFragmentを連続的につないでいく。このとき、Fragmentと隣り合うFragmentを管理しておくと、一つのFragmentから連続的につながった部分構造が取れる
  6. Aromatic Ringをスタートとして奇数セット(3Fragment、5Fragment・・・)とつないでいけばAromatic ~Aliphatic ~Aromatic の順で部分構造が取れる。すなわちこれがひとつの「Framework」になる
  7. 重原子の種類を無視する場合は、処理後にすべての原子をa,Aなどに置き換えれば、あとですぐSmartsに変更できる


ということで、来週から一部修正作業をしなきゃ。





2009年12月3日木曜日

マイケルを知らなかった頃

「マイケル」というといまどきは「ジャクソン」と来るんでしょうが、私は「ブレッカー」です。

大学のジャズ研に入ったとき、実はマイケルのことは知りませんでした。といいながら無意識に一度ライブで聴いているはずなのですが全く記憶にも眼中にもありませんでした。横浜球場で昔やってた「Aurexジャズフェスティバル」で見て聴いているはずです。

そのときは私もまだ若く、そのとき流行の「フュージョン」を軽蔑していて、「やっぱジャズはモダンだよな」とわかったようなことを言いつつ、マイケルがせっかくすばらしい演奏をした「ストラップハンギン」も記憶にありません。

そのときは死にかけで車椅子のベニー・グッドマンを聞いて、「スウィングもいいね」などとほざいていたわけで。

あの時、マイケルをちゃんと知っていたら、「Smok'n the Pit」を生で見れたかもしれないし、深町純とのコラボも見れたかもしれないと、いまさらですが後悔しきり。

あの頃の私のアイドルはコルトレーンでした。

私が初めて買ったジャズLPがコルトレーンの「ジャイアント・ステップス」とビル・エヴァンスの「ストレート・ノー・チェイサー(Flのジェレミー・ステイグと共演)です。ジャイアント・ステップスが最初のジャズとの出会いなんてできすぎていると思いますが、ホンマです。

・・・続く

OpenBabel : AtomのIndexリストからOBMolオブジェクトを再構築する

OpenBabelでSMARTSを使ったSmilesの部分構造検索をすると、結果がMapListと呼ばれる原子のIndexのリストで帰ってきます。OpenBabelではこのIndexを使うことを推奨していません。なぜならこのIndexは分子をModify(一部構造を切り取る、原子・分子を付加するなど)するとIndexが再作成されてしまうので、永続的に保持されないからです。


といってもこの原子Indexは元の分子をいじらない限りは変更されないので、元の分子の一部分を記憶させるには使いやすいです。検索結果や部分構造を別途Indexとして持っていればいろいろ使えます。ようは元の構造を一切いじらなければOKです。


しかも、これはやってみたのですが、DeleteBondするだけではIndexは変更されずちゃんと保持されます。つまり切断Bondとしての情報をもったままの分子として原子Indexがそのまま保持されます。Separateメソッドで元の分子をばらばらにしてしまうと、各部分構造分子の原子Indexは再作成されて、1から順番に振られます。


で、元の分子をいじらずに、取得した原子Indexから部分構造を再構築したいことはよくあります。なんでお気軽関数を作りました。コードはC#です。


新しいOBMolインスタンスに元の分子から原子をAddしていくのですが、Addしてしまうと新しい分子上のAddした原子のIndexはやはり1から順番に振られてしますので、別途新しいIndexと元のIndexの対応表をHashtableで管理しています。この情報を使ってあとでOBBondをAddしていきます。







using System.Collections.Generic;
using System.Collections;


using OpenBabel;

namespace OpenHabel
{
    static class OHUtil
    {
        /// <summary>
        /// ParentのMolと原子のIndexからMolを再構築
        /// </summary>
        /// <param name="parentMol"></param>
        /// <param name="atomIndex"></param>
        /// <returns></returns>
        public static OBMol GetMol(OBMol parentMol, List<uint> atomIndex)
        {
            Hashtable atomIdxTable = new Hashtable();
            OBMol newMol = new OBMol();
            IEnumerable<OBAtom> atoms = parentMol.Atoms();

            int atomCount = 0;
            foreach (OBAtom oneAtom in atoms)
            {
                if (OHUtil.IsThereItemInList(atomIndex, oneAtom.GetIdx()))
                {
                    OBAtom newAtom = new OBAtom();
                    newAtom.Duplicate(oneAtom);
                    int idx = int.Parse(oneAtom.GetIdx().ToString());
                    atomCount += 1;
                    atomIdxTable[idx.ToString()] = atomCount;

                    newMol.AddAtom(newAtom);

                    //Console.Write(obconv.WriteString(newMol));
                }
            }
            IEnumerable<OBBond> bonds = parentMol.Bonds();
            foreach (OBBond oneBond in bonds)
            {
                if (
                 OHUtil.IsThereItemInList(atomIndex, oneBond.GetBeginAtomIdx()) &&
                 OHUtil.IsThereItemInList(atomIndex, oneBond.GetEndAtomIdx())
                )
                {
                    int startAtomKey = (int)oneBond.GetBeginAtomIdx();
                    int startAtomIdx = (int)atomIdxTable[startAtomKey.ToString()];

                    int endAtomKey = (int)oneBond.GetEndAtomIdx();
                    int endAtomIdx = (int)atomIdxTable[endAtomKey.ToString()];

                    int order = (int)oneBond.GetBondOrder();

                    newMol.AddBond(startAtomIdx, endAtomIdx, order);
                }
            }
            return newMol;
        }

        /// <summary>
        /// atomList中に特定のatomIndexが含まれるかどうか
        /// </summary>
        /// <param name="atomList">List:uint</param>
        /// <param name="atomIndex">uint</param>
        /// <returns>見つかったらTrue</returns>
        public static bool IsThereItemInList(List<uint> atomList, uint atomIndex)
        {
            foreach (uint item in atomList)
            {
                if (item == atomIndex) { return true; }
            }
            return false;
        }
    }
}

2009年12月2日水曜日

野呂一生

BSフジで野呂さんのライブをやってたのを録画して今日見ました。

相変わらず、といえばそれまでですが、ヘタといえばヘタ、変わっていないといえば数十年前から全く変わっていない。

変わらずにいれるというのはすごいことだな。

OpenBabel : Frameworkerを作ろう

Frameworkを作るためには化合物の「Ring」と「Linker」を明確に分ける必要があります。
でも私の環境でこの「Linker」を認識するのはISIS Baseしかなく、他のシステムへの実装がちょっと難しい。

で、OpenBabel+VisualStudio2008(C#)でこの「FrameWorker」を作っています。

考え方としてはこんな感じ。


  1. 化合物をSmilesで表記する
  2. Smartsを「aA」とする
  3. 化合物をこのSmartsにかけると、Aromatic any atom - Aliphatic any atomで切れる。つまり芳香環とLinkerまたは側鎖の間が切れる
  4. 構造を完全に切ってしまうのではなく、「切れ目」の状態で化合物を保持しておく
  5. 切れ目を参考にして、化合物を「Fragment」に分ける
  6. 切れ目を参考にして、FragmentとFragmentを連続的につないでいく。このとき、Fragmentと隣り合うFragmentを管理しておくと、一つのFragmentから連続的につながった部分構造が取れる
  7. Aromatic Ringをスタートとして奇数セット(3Fragment、5Fragment・・・)とつないでいけばAromatic ~Aliphatic ~Aromatic の順で部分構造が取れる。すなわちこれがひとつの「Framework」になる
  8. 重原子の種類を無視する場合は、処理後にすべての原子をa,Aなどに置き換えれば、あとですぐSmartsに変更できる
この考え方でOpenBabelを使ったFrameworkerを作りつつあります。今のところ6.の途中までできました。明日は7.まで行って動作確認します。

でも、ちょっと問題が・・・。化合物の構造を舐めまくるのでforeachの嵐になってます。実運用したときに処理時間が結構長くなりそうで怖い。

2009年12月1日火曜日

最近はまっている仕事

OpenBabel
PerlMol


いずれもオープンソースツールで、化合物の構造をハンドリングする環境。
お金がないわけではなくて、ただでいろいろ試せるところがすごいね。




京都の秋


京都は紅葉のさかりで、各地で人だらけ。
京都に住んでいてもなかなか行けません(-.-;)

SoftBank 820T


子供に使わしている携帯:SoftBank 820T

メニュー「設定→制限機能→発信先設定」で、「電話発信」、「メール送信」が”制限なし”以外にしてあると、アドレス帳の編集ができない。


なんでやねん。めんどくさ。