OBMolからAtomを一つ削除してみる

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

今回試すことは、「生成されたOBMolから一つAtomを削除するとどうなるか」。

今回も実験で使っているのは以下の化合物
![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/84317/ce6c6e31-3ace-9786-2095-57ddcaa36656.png)


##Atomの変化について

```cpp:testAtom.cc
#include <iostream>
#include <string>

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

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

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

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

  std::cout << "========before deletion========" << std::endl;
  ShowDetail(mol);
  std::cout << "===============================" << std::endl;

  std::cout << std::endl;
  std::cout << "DeleteAtom Id:9" << std::endl; 
  mol.DeleteAtom(mol.GetAtomById(9));
  std::cout << std::endl;

  std::cout << "========after deletion ========" << std::endl;
  ShowDetail(mol);
  std::cout << "===============================" << std::endl;
  return 0;  
}
```

結果は以下の通り。

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

DeleteAtom Id:9

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

ちゃんとAtomId=9が消えていることがわかる。
一方、Idxは10が消えた分を詰めている。

##Bondの変化について

Atomの変化はわかったので、こんどはBondの変化を見てみる。

```cpp:testBond.cc
#include <iostream>
#include <string>

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

void ShowBondDetail(OpenBabel::OBMol& mol){
  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;
  }
}

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

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

  std::cout << "========before deletion========" << std::endl;
  ShowBondDetail(mol);
  std::cout << "===============================" << std::endl;
  std::cout << std::endl;

  std::cout << "DeleteAtom Id:9" << std::endl; 
  mol.DeleteAtom(mol.GetAtomById(9));

  std::cout << std::endl;
  std::cout << "========after deletion ========" << std::endl;
  ShowBondDetail(mol);
  std::cout << "===============================" << std::endl;
  return 0;  
}
```

結果は以下のようになった。

```bash
========before deletion========
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
===============================

DeleteAtom Id:9

========after deletion ========
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
10 11   0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1
11 12   0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 1
11 13   0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 1
10 14   0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1
14 15   0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1
15 16   0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1
9 16    1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
16 17   1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 17    1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
===============================
```

BondにフックされているのはAtomIdxのため、こちらも間を詰めるようになっている。
また、今回削除した原子に関係するBondも削除されている。
さらにさらに、```IsAromatic()```などの結果も変化している。

Deleteって結構いろんなことをしてるんだなあ、がすごく簡単な感想。