예제 #1
0
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);
}
예제 #2
0
  void OBForceField::SystematicRotorSearch() 
  {
    OBRotorList rl;
    OBRotamerList rotamers;

    rl.Setup(_mol);
    rotamers.SetBaseCoordinateSets(_mol);
    rotamers.Setup(_mol, rl);
    
    IF_OBFF_LOGLVL_LOW {
      OBFFLog("\nS Y S T E M A T I C   R O T O R   S E A R C H\n\n");
      sprintf(logbuf, "  NUMBER OF ROTATABLE BONDS: %d\n", rl.Size());
      OBFFLog(logbuf);
    }

    if (!rl.Size()) { // only one conformer
      IF_OBFF_LOGLVL_LOW
        OBFFLog("  GENERATED ONLY ONE CONFORMER\n\n");
 
      ConjugateGradients(2500); // final energy minimizatin for best conformation
      
      return;
    }

    std::vector<int> rotorKey(rl.Size() + 1, 0); // indexed from 1

    OBRotorIterator ri;
    OBRotor *rotor = rl.BeginRotor(ri);
    for (int i = 1; i < rl.Size() + 1; ++i, rotor = rl.NextRotor(ri)) { // foreach rotor
      for (unsigned int j = 0; j < rotor->GetResolution().size(); j++) { // foreach torsion
        rotorKey[i] = j;
        rotamers.AddRotamer(rotorKey);
      }
    }

    rotamers.ExpandConformerList(_mol, _mol.GetConformers());
      
    IF_OBFF_LOGLVL_LOW {
      sprintf(logbuf, "  GENERATED %d CONFORMERS\n\n", _mol.NumConformers());
      OBFFLog(logbuf);
      OBFFLog("CONFORMER     ENERGY\n");
      OBFFLog("--------------------\n");
    }
    
    // Calculate energy for all conformers
    char logbuf[100];
    std::vector<double> energies(_mol.NumConformers(), 0.0);
    for (int i = 0; i < _mol.NumConformers(); i++) {
      _mol.SetConformer(i); // select conformer

      energies[i] = Energy(); // calculate and store energy
      
      IF_OBFF_LOGLVL_LOW {
        sprintf(logbuf, "   %3d      %8.3f\n", (i + 1), energies[i]);
        OBFFLog(logbuf);
      }
    }

    // Select conformer with lowest energy
    int best_conformer = 0;
    for (int i = 1; i < _mol.NumConformers(); i++) {
      if (energies[i] < energies[best_conformer])
        best_conformer = i;
    }
  
    IF_OBFF_LOGLVL_LOW {
      sprintf(logbuf, "\n  CONFORMER %d HAS THE LOWEST ENERGY\n\n",  best_conformer + 1);
      OBFFLog(logbuf);
    }

    _mol.SetConformer(best_conformer);
    current_conformer = best_conformer;
  }
예제 #3
0
int OBForceField::DiverseConfGen(double rmsd, unsigned int nconfs, double energy_gap, bool verbose)
  {
    _energies.clear(); // Wipe any energies from previous conformer generators

    // Remove all conformers (e.g. from previous conformer generators) even the current conformer
    double *initialCoord = new double [_mol.NumAtoms() * 3]; // initial state
    double *store_initial = new double [_mol.NumAtoms() * 3]; // store the initial state
    memcpy((char*)initialCoord,(char*)_mol.GetCoordinates(),sizeof(double)*3*_mol.NumAtoms());
    memcpy((char*)store_initial,(char*)_mol.GetCoordinates(),sizeof(double)*3*_mol.NumAtoms());
    std::vector<double *> newConfs(1, initialCoord);
    _mol.SetConformers(newConfs);

    if (_mol.NumRotors() == 0) {
      SetupPointers();
      _energies.push_back(Energy(false));
      delete [] store_initial;
      return 0;
    }

    // Get estimate of lowest energy conf using FastRotorSearch
    FastRotorSearch(true);
    double lowest_energy = Energy(false);

    OBRotorList rl;
    OBBitVec fixed = _constraints.GetFixedBitVec();
    rl.SetFixAtoms(fixed);
    if (_loglvl == 0)
      rl.SetQuiet(); // Don't print info on symmetry removal
    rl.Setup(_mol);

    OBRotorIterator ri;
    OBRotamerList rotamerlist;
    rotamerlist.SetBaseCoordinateSets(_mol);
    rotamerlist.Setup(_mol, rl);

    // Can take shortcut later, as 4 components of the energy will be constant
    SetupPointers();
    double energy_offset = E_Bond(false) + E_Angle(false) + E_StrBnd(false) + E_OOP(false);
    lowest_energy -= energy_offset;
    _energies.push_back(lowest_energy);

    OBRotorKeys rotorKeys;
    OBRotor* rotor = rl.BeginRotor(ri);
    unsigned int combinations = 1;
    vector<size_t> rotor_sizes;
    for (unsigned int i = 1; i < rl.Size() + 1; ++i, rotor = rl.NextRotor(ri)) { // foreach rotor
      size_t size = rotor->GetResolution().size();
      rotorKeys.AddRotor(size);
      combinations *= size;
      rotor_sizes.push_back(size);
      if(verbose) {
        cout << "....rotor " << i << " from " << rotor->GetBond()->GetBeginAtomIdx() << " to "
             << rotor->GetBond()->GetEndAtomIdx() << " has " << size << " values" << endl;
      }
    }
    if (rotor_sizes.size() > 0 && combinations == 0) { // Overflow!
      combinations = UINT_MAX;
    }
    cout << "..tot conformations = " << combinations << "\n";

    if (nconfs == 0)
      nconfs = 1 << 20;
    unsigned int max_combinations = min<unsigned int>(nconfs , combinations);
    LFSR lfsr(max_combinations); // Systematic random number generator
    if (verbose && combinations > max_combinations) {
      cout << "....Using a cutoff of "
           << nconfs << " we will only explore " << std::fixed << setprecision(1)
           << static_cast<float>(nconfs * 100)/static_cast<float>(combinations) << "% of these\n";
    }

    unsigned int combination;
    OBDiversePoses divposes(_mol, rmsd, false);
    vector<int> my_rotorkey(rotor_sizes.size() + 1, 0);
    unsigned int counter = 0;

    // Main loop over rotamers
    unsigned int N_low_energy = 0;
    do {
      _mol.SetCoordinates(store_initial);

      combination = lfsr.GetNext();
      unsigned int t = combination;
      // Convert the combination number into a rotorkey
      for (unsigned int i = 0 ; i < rotor_sizes.size(); ++i) {
        my_rotorkey[i + 1] = t % rotor_sizes[i];
        t /= rotor_sizes[i];
      }

      rotamerlist.SetCurrentCoordinates(_mol, my_rotorkey);
      SetupPointers();
      double currentE = E_VDW(false) + E_Torsion(false) + E_Electrostatic(false);
      if (currentE < lowest_energy + energy_gap) { // Don't retain high energy poses
        divposes.AddPose(_mol.GetCoordinates(), currentE);
        N_low_energy++;
        if (currentE < lowest_energy)
          lowest_energy = currentE;
      }
      counter++;
    } while (combination != 1 && counter < nconfs); // The LFSR always terminates with a 1
    cout << "..tot confs tested = " << counter << "\n..below energy threshold = " << N_low_energy << "\n";

    // Reset the coordinates to those of the initial structure
    _mol.SetCoordinates(store_initial);

    // Get results from the tree
    UpdateConformersFromTree(&_mol, _energies, &divposes, verbose);

    // Add back the energy offset
    transform(_energies.begin(), _energies.end(), _energies.begin(), bind2nd(plus<double>(), energy_offset));

    // Clean up
    delete [] store_initial;

    return 0;
 }
예제 #4
0
  void OBRotamerList::Setup(OBMol &mol,OBRotorList &rl)
  {
    //clear the old stuff out if necessary
    _vres.clear();
    vector<unsigned char*>::iterator j;
    for (j = _vrotamer.begin();j != _vrotamer.end();++j)
      delete [] *j;
    _vrotamer.clear();

    vector<pair<OBAtom**,vector<int> > >::iterator k;
    for (k = _vrotor.begin();k != _vrotor.end();++k)
      delete [] k->first;
    _vrotor.clear();
    _vrings.clear();
    _vringTors.clear();

    //create the new list
    OBRotor *rotor;
    vector<OBRotor*>::iterator i;
    vector<int> children;

    int ref[4];
    OBAtom **atomlist;
    for (rotor = rl.BeginRotor(i);rotor;rotor = rl.NextRotor(i))
      {
        atomlist = new OBAtom* [4];
        rotor->GetDihedralAtoms(ref);
        atomlist[0] = mol.GetAtom(ref[0]);
        atomlist[1] = mol.GetAtom(ref[1]);
        atomlist[2] = mol.GetAtom(ref[2]);
        atomlist[3] = mol.GetAtom(ref[3]);
        mol.FindChildren(children,ref[1],ref[2]);
        _vrotor.push_back(pair<OBAtom**,vector<int> > (atomlist,children));
        _vres.push_back(rotor->GetResolution());
      }

    // if the rotor list has ring bonds, build up an index
    if (rl.HasRingRotors()){
      // go through rings
      // for each step of the path, see if there's a matching rotor
      vector<int> path;
      int pSize;
      vector<double> ringTorsions;
      vector<int> ringRotors;
      FOR_RINGS_OF_MOL(r, mol)
      {
        ringTorsions.clear();
        ringRotors.clear();

        pSize = r->Size();
        if (pSize < 4)
          continue; // not rotatable

        path = r->_path;
        for (int j = 0; j < pSize; ++j) {
          double torsion = mol.GetTorsion(path[(j + pSize - 1) % pSize],
                                       path[(j + pSize) % pSize],
                                       path[(j + pSize + 1) % pSize],
                                       path[(j + pSize + 2) % pSize]);
          ringTorsions.push_back(torsion);

          // now check to see if any of these things are rotors
          int rotorIndex = -1; // not a rotor
          OBBond *bond = mol.GetBond(path[(j + pSize) % pSize], path[(j + pSize + 1) % pSize]);
          for (rotor = rl.BeginRotor(i);rotor;rotor = rl.NextRotor(i))
            {
              if (bond != rotor->GetBond())
                continue; // no match at all

              // Central bond matches, make sure 1..4 atoms are in the path
              rotor->GetDihedralAtoms(ref);
              if ( (ref[0] == path[(j + pSize - 1) % pSize] &&
                    ref[3] == path[(j + pSize + 2) % pSize])
                   ||
                   (ref[3] == path[(j + pSize - 1) % pSize] &&
                    ref[0] == path[(j + pSize + 2) % pSize]) ) {
                rotorIndex = rotor->GetIdx();
              }
            } // end checking all the rotors
          ringRotors.push_back(rotorIndex); // could be -1 if it's not rotatable
        }

        _vringTors.push_back(ringTorsions);
        _vrings.push_back(ringRotors);
      } // finished with the rings