Guest User

timvdm

a guest
Sep 29th, 2009
345
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.31 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <cassert>
  5.  
  6. #include <Eigen/Core>
  7.  
  8. #include <openbabel/mol.h>
  9. #include <openbabel/obconversion.h>
  10. #include <openbabel/graphsym.h>
  11.  
  12. #include <graph.hh>
  13.  
  14. #include "permutation.h"
  15. using namespace OpenBabel;
  16.  
  17. ////////////////////////////////////////////////////////////////////////////////
  18. //
  19. //
  20. // O P E N B A B E L S P E C I F I C C O D E
  21. //
  22. //
  23. ////////////////////////////////////////////////////////////////////////////////
  24.  
  25. OpenBabel::OBMol* ReadMolecule(const std::string &filename)
  26. {
  27. OpenBabel::OBConversion conv;
  28. OpenBabel::OBFormat *format = conv.FormatFromExt(filename.c_str());
  29. if (!format || !conv.SetInFormat(format)) {
  30. std::cout << "ERROR: Could not detect file format for: " << filename << std::endl;
  31. return 0;
  32. }
  33.  
  34. std::ifstream ifs;
  35. ifs.open(filename.c_str());
  36. if (!ifs) {
  37. std::cout << "ERROR: Could not open file: " << filename << std::endl;
  38. return 0;
  39. }
  40.  
  41. OpenBabel::OBMol *obmol = new OpenBabel::OBMol;
  42. if (!conv.Read(obmol, &ifs)) {
  43. std::cout << "ERROR: Could not read molecule from file: " << filename << std::endl;
  44. delete obmol;
  45. ifs.close();
  46. return 0;
  47. }
  48.  
  49. ifs.close();
  50. return obmol;
  51. }
  52.  
  53. ////////////////////////////////////////////////////////////////////////////////
  54. //
  55. //
  56. // U N I T T E S T S
  57. //
  58. //
  59. ////////////////////////////////////////////////////////////////////////////////
  60.  
  61.  
  62.  
  63. void testPermutation()
  64. {
  65. std::vector<unsigned int> e;
  66. e.push_back(1);
  67. e.push_back(2);
  68. e.push_back(3);
  69. e.push_back(4);
  70. Permutation p1(e), p2(e);
  71.  
  72. assert(p1 == p2);
  73. }
  74.  
  75. void testPermutationGroup()
  76. {
  77. Permutation p;
  78. p.map.push_back(1);
  79. p.map.push_back(2);
  80. p.map.push_back(3);
  81. p.map.push_back(4);
  82.  
  83. PermutationGroup group;
  84. assert( !group.contains(p) );
  85.  
  86. group.add(p);
  87. assert( group.contains(p) );
  88. }
  89.  
  90. void unitTests()
  91. {
  92. testPermutation();
  93. testPermutationGroup();
  94.  
  95. }
  96.  
  97.  
  98.  
  99.  
  100. void callback(void *param, unsigned int n, const unsigned int *aut)
  101. {
  102. assert(param);
  103. /*
  104. fprintf((FILE*)param, "Generator: ");
  105. bliss::print_permutation((FILE*)param, n, aut, 0);
  106. fprintf((FILE*)param, "\n");
  107. */
  108.  
  109. std::vector<unsigned int> elements;
  110. cout << "Generator: ";
  111. for (unsigned int i = 0; i < n; ++i) {
  112. cout << aut[i] + 1 << " ";
  113. elements.push_back(aut[i]+1);
  114. }
  115. cout << endl;
  116.  
  117. PermutationGroup *generators = static_cast<PermutationGroup*>(param);
  118. generators->add(Permutation(elements));
  119. }
  120.  
  121. void addInverses(PermutationGroup &G)
  122. {
  123. unsigned int size = G.permutations.size();
  124. for (unsigned int i = 0; i < size; ++i) {
  125. Permutation inv_p(G.permutations.at(i).matrix().transpose());
  126. if (!G.contains(inv_p))
  127. G.add(inv_p);
  128. }
  129. }
  130.  
  131. void addProducts(PermutationGroup &G)
  132. {
  133. for (unsigned int i = 0; i < G.permutations.size(); ++i) {
  134. for (unsigned int j = 0; j < G.permutations.size(); ++j) {
  135. if (i >= j)
  136. continue;
  137.  
  138. Permutation p = G.permutations.at(i) * G.permutations.at(j);
  139. if (!G.contains(p))
  140. G.add(p);
  141. }
  142. }
  143. }
  144.  
  145. PermutationGroup findAutomorphisms(OpenBabel::OBMol *obmol, const std::vector<unsigned int> &symClasses)
  146. {
  147. using OpenBabel::OBMolAtomIter;
  148. using OpenBabel::OBMolBondIter;
  149.  
  150. // construct the bliss graph
  151. bliss::Graph g;
  152. std::map<OpenBabel::OBAtom*, unsigned int> atom2index;
  153. FOR_ATOMS_OF_MOL (atom, obmol) {
  154. atom2index[&*atom] = g.add_vertex(symClasses.at(atom->GetIndex()));
  155. }
  156. FOR_BONDS_OF_MOL (bond, obmol) {
  157. g.add_edge(atom2index[bond->GetBeginAtom()], atom2index[bond->GetEndAtom()]);
  158. }
  159.  
  160. // use bliss to get the automorphism group generators
  161. PermutationGroup generators;
  162. bliss::Stats stats;
  163. g.find_automorphisms(stats, &callback, &generators);
  164.  
  165. cout << "# Automorphisms:" << stats.group_size_approx << endl;
  166. unsigned long nAut = stats.group_size_approx;
  167.  
  168. // construct the automorphism group
  169. PermutationGroup G;
  170.  
  171. // add identity permutation
  172. std::vector<unsigned int> eElements;
  173. for (unsigned int i = 0; i < obmol->NumAtoms(); ++i)
  174. eElements.push_back(i+1);
  175. Permutation e(eElements);
  176. if (!G.contains(e))
  177. G.add(e);
  178.  
  179. // add the generators
  180. for (unsigned int i = 0; i < generators.size(); ++i) {
  181. if (!G.contains(generators.at(i)))
  182. G.add(generators.at(i));
  183. }
  184.  
  185.  
  186. unsigned int counter = 0;
  187. unsigned int lastSize = 0;
  188. while (G.permutations.size() != lastSize) {
  189. lastSize = G.permutations.size();
  190.  
  191. addInverses(G);
  192. addProducts(G);
  193.  
  194. counter++;
  195. if (counter > 100)
  196. break;
  197. }
  198.  
  199. return G;
  200. }
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207. int main(int argc, char **argv)
  208. {
  209. unitTests();
  210.  
  211. if (argc < 2) {
  212. std::cout << "Usage: " << argv[0] << " <filename>" << std::endl;
  213. return -1;
  214. }
  215.  
  216. OpenBabel::OBMol *obmol = ReadMolecule(argv[1]);
  217. if (!obmol)
  218. return -1;
  219.  
  220. std::vector<unsigned int> elements;
  221. for (int i = 0; i < obmol->NumAtoms(); ++i) {
  222. elements.push_back(i+1);
  223. }
  224.  
  225. OpenBabel::OBGraphSym graphSym(obmol);
  226. std::vector<unsigned int> symClasses;
  227. graphSym.GetSymmetry(symClasses);
  228.  
  229.  
  230. PermutationGroup G = findAutomorphisms(obmol, symClasses);
  231.  
  232. std::cout << "Automorphisms:" << std::endl;
  233. for (unsigned int i = 0; i < G.size(); ++i)
  234. G.at(i).print();
  235.  
  236.  
  237. return 0;
  238. }
Advertisement
Add Comment
Please, Sign In to add comment