OBBondのIs関数群

[前回: OpenBabelをc++からいじってみる](http://qiita.com/yanagi3150/items/d83fa3f25210e6a5c4af)の続き。
インストールとかは前回を見てね。

今回はもう少し細かく機能を見てみる。

OBBondは以下のIs関数を持っている。

```cpp
IsAromatic()           //芳香族環の中のBondかどうか
IsInRing()             //環の中のBondかどうか
IsRotor()              //回転可能なBondかどうか
IsAmide()              //アミド結合かどうか
IsPrimaryAmide()       //
IsSecondaryAmide()     //
IsTertiaryAmide()      //
IsEster()              //エステル結合かどうか
IsCarbonyl()           //カルボニル基の二重結合かどうか
IsSingle()             //単結合かどうか
IsDouble()             //二重結合かどうか
IsTriple()             //三重結合かどうか
IsKSingle()            //ケクレ的に単結合かどうか(IsSingle + IsAromaticだと1になったりならなかったりする)
IsKDouble()            //ケクレ的に二重結合かどうか(IsDouble + IsAromaticだと1になったりならなかったりする)
IsKTriple()            //ケクレ的に三重結合かどうか(IsTripleと変わらなくね？)
IsClosure()            //smilesで表現するときに切るべき場所かどうか（後述）
IsUp()                 // Cis/Trans関係（平面に横向きに置いた時にななめ上方向に伸びているか、かな？未チェック）
IsDown()               // Cis/Trans関係（同様にななめ下方向？未チェック）
IsWedge()              // 立体的に「手前に来る」結合かどうか
IsHash()               // 立体的に「奥に行く」結合かどうか
IsWedgeOrHash()        // IsWedge||IsHash
IsCisOrTrans()         // CisかTransを構成するBondかどうか
IsDoubleBondGeometry() // return whether the geometry around this bond "looks" unsaturated
```

わかるものもあればわからないものもある。
IsDoubleBondGeometryの意味をちゃんと理解しようとしていないのは秘密
まあとりあえず試してみよう。

```cpp:test.cc
#include <iostream>
#include <string>
#include <sstream>

#include <openbabel/mol.h>
#include <openbabel/obconversion.h>

int main(int argc, char** argv){

  // input molecule using smiles
  std::string smiles = "c1cc(C(=O)N(C)C)c2cc(C(=O)N)ccc2c1";
  std::stringstream ss(smiles);
  OpenBabel::OBConversion conv(&ss);
  conv.SetInFormat("smi");
  OpenBabel::OBMol mol;
  conv.Read(&mol);

  std::cout << "Atom information" << std::endl;
  std::cout << "AtomIdx AtomType" << std::endl;
  for(OpenBabel::OBAtomIterator ait = mol.BeginAtoms(); ait!=mol.EndAtoms(); ++\
ait){
    std::cout << (*ait)->GetIdx()
              << " "
              << (*ait)->GetType()
              << std::endl;
  }
  std::cout << std::endl;

  std::cout << "Bond information" << std::endl;
  std::cout << "BeginAtomIdx EndAtomIdx" << std::endl;
  for(OpenBabel::OBBondIterator bit = mol.BeginBonds(); bit!=mol.EndBonds(); ++\
bit){
    std::cout << (*bit)->GetBeginAtomIdx()      << " "
              << (*bit)->GetEndAtomIdx()        << "\t"
              << (*bit)->IsAromatic()           << " "
              << (*bit)->IsInRing()             << " "
              << (*bit)->IsRotor()              << " "
              << (*bit)->IsAmide()              << " "
              << (*bit)->IsPrimaryAmide()       << " "
              << (*bit)->IsSecondaryAmide()     << " "
              << (*bit)->IsTertiaryAmide()      << " "
              << (*bit)->IsEster()              << " "
              << (*bit)->IsCarbonyl()           << " "
              << (*bit)->IsSingle()             << " "
              << (*bit)->IsDouble()             << " "
              << (*bit)->IsTriple()             << " "
              << (*bit)->IsKSingle()            << " "
              << (*bit)->IsKDouble()            << " "
              << (*bit)->IsKTriple()            << " "
              << (*bit)->IsClosure()            << " "
              << (*bit)->IsDoubleBondGeometry() << " "
              << std::endl;
  }
  return 0;
}
```

入力はこれ。

![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/84317/ce6c6e31-3ace-9786-2095-57ddcaa36656.png)


で、結果はこれ。

```
Atom information
AtomIdx AtomType
1 Car
2 Car
3 Car
4 C2
5 O2
6 Nam
7 C3
8 C3
9 Car
10 Car
11 Car
12 C2
13 O2
14 Nam
15 Car
16 Car
17 Car
18 Car

Bond information
BeginAtomIdx EndAtomIdx
1 2     1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
2 3     1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
3 4     0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1
4 5     0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 1
4 6     0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 0 1
6 7     0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1
6 8     0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1
3 9     1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1
9 10    1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
10 11   1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1
11 12   0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1
12 13   0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 1
12 14   0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 1
11 15   1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
15 16   1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
16 17   1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
9 17    1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
17 18   1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 18    1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
```

この結果について少し考察

- 4-6のIsRotor()=1 ... 三級アミドの場合二重結合性持たないんだっけ・・・？
- 6-7, 6-8のIsRotor()=0 ... これはどうやら回転させても意味がない、ということらしい。
- Single,Double,Triple,Aromaticは計算など用、KSingle,KDouble,KTripleは描画用、といった所だろうか。
- 3-9, 10-11でIsClosure()=1 ... ようするに環を閉じている場所を判定しているっぽい。Smilesを出力するときに必要な情報なのかな。
- IsDoubleBondGeometry()=1 ... 謎。

個人的にはIsRotorが提供されるのがとてもありがたい。