bool OBConformerSearch::Setup(const OBMol &mol, int numConformers, int numChildren, int mutability, int convergence) { // copy some variables m_mol = mol; m_numConformers = numConformers; m_numChildren = numChildren; m_mutability = mutability; m_convergence = convergence; if (m_mol.GetCoordinates() == NULL) return false; // Initialize the OBRotorList m_rotorList.SetFixedBonds(m_fixedBonds); m_rotorList.Setup(m_mol); if (!m_rotorList.Size()) { // only one conformer return false; } // create initial population OBRandom generator; generator.TimeSeed(); RotorKey rotorKey(m_rotorList.Size() + 1, 0); // indexed from 1 if (IsGood(rotorKey)) m_rotorKeys.push_back(rotorKey); else { cout << "Initial conformer does not pass filter!" << endl; } int tries = 0; while (m_rotorKeys.size() < m_numConformers && tries < numConformers * 1000) { tries++; // perform random mutation(s) OBRotorIterator ri; OBRotor *rotor = m_rotorList.BeginRotor(ri); for (int i = 1; i < m_rotorList.Size() + 1; ++i, rotor = m_rotorList.NextRotor(ri)) { if (generator.NextInt() % m_mutability == 0) rotorKey[i] = generator.NextInt() % rotor->GetResolution().size(); } // duplicates are always rejected if (!IsUniqueKey(m_rotorKeys, rotorKey)) continue; // execute filter(s) if (!IsGood(rotorKey)) continue; // add the key m_rotorKeys.push_back(rotorKey); } // print out initial conformers cout << "Initial conformer count: " << m_rotorKeys.size() << endl; for (unsigned int i = 0; i < m_rotorKeys.size(); ++i) { for (unsigned int j = 1; j < m_rotorKeys[i].size(); ++j) std::cout << m_rotorKeys[i][j] << " "; std::cout << std::endl; } return true; }
void OBConformerSearch::NextGeneration() { // create next generation population OBRandom generator; generator.TimeSeed(); // generate the children int numConformers = m_rotorKeys.size(); for (int c = 0; c < numConformers; ++c) { for (int child = 0; child < m_numChildren; ++child) { bool foundKey = false; int tries = 0; while (!foundKey) { tries++; if (tries > 1000) foundKey = true; RotorKey rotorKey = m_rotorKeys[c]; // copy parent gene // perform random mutation(s) OBRotorIterator ri; OBRotor *rotor = m_rotorList.BeginRotor(ri); for (int i = 1; i < m_rotorList.Size() + 1; ++i, rotor = m_rotorList.NextRotor(ri)) { if (generator.NextInt() % m_mutability == 0) rotorKey[i] = generator.NextInt() % rotor->GetResolution().size(); // permutate gene } // duplicates are always rejected if (!IsUniqueKey(m_rotorKeys, rotorKey)) continue; // execute the filter(s) if (!IsGood(rotorKey)) continue; // add the key m_rotorKeys.push_back(rotorKey); // append child to population // set foundKey to generate the next child foundKey = true; } } } }
int main(int argc,char *argv[]) { if (argc != 2) { cout << "Usage: obrotamer <file>" << endl; cout << " Outputs the number of rotable bonds and generate a random" << " rotamer" << endl; return(-1); } ifstream ifs(argv[1]); if (!ifs) { cerr << "Error! Cannot read input file!" << endl; return(-1); } OBConversion conv(&ifs, &cout); OBFormat* pFormat; pFormat = conv.FormatFromExt(argv[1]); if ( pFormat == NULL ) { cerr << "Error! Cannot read file format!" << endl; return(-1); } // Finally, we can do some work! OBMol mol; if (! conv.SetInAndOutFormats(pFormat, pFormat)) { cerr << "Error! File format isn't loaded" << endl; return (-1); } OBRotorList rl; OBRotamerList rotamers; int *rotorKey = NULL; OBRandom rand; rand.TimeSeed(); while(ifs.peek() != EOF && ifs.good()) { mol.Clear(); conv.Read(&mol); rl.Setup(mol); cerr << " Number of rotatable bonds: " << rl.Size() << endl; // indexed from 1, rotorKey[0] = 0 std::vector<int> rotorKey(rl.Size() + 1, 0); // each entry represents the configuration of a rotor // e.g. indexes into OBRotor::GetResolution() // (the different angles to sample from the OBRotorRules database) OBRotorIterator ri; OBRotor *rotor = rl.BeginRotor(ri); for (int i = 1; i < rl.Size() + 1; ++i, rotor = rl.NextRotor(ri)) rotorKey[i] = rand.NextInt() % rotor->GetResolution().size(); rotamers.SetBaseCoordinateSets(mol); rotamers.Setup(mol, rl); rotamers.AddRotamer(rotorKey); // This is more useful when you have added many rotamers // rather than the one in this example rotamers.ExpandConformerList(mol, mol.GetConformers()); // Change the molecule conformation -- from 0 .. rotamers.NumRotamers() mol.SetConformer(0); conv.Write(&mol); } // while reading molecules return(0); }