예제 #1
0
void testUFFBuilderSpecialCases(){
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing UFF special cases." << std::endl;

  RWMol *mol;
  std::string key;
  int needMore;
  RDGeom::Point3D v1,v2;
  ForceFields::ForceField *field;

  std::string pathName=getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data";
  // ----------
  //  Trigonal bipyramid
  // ----------
  mol = MolFileToMol(pathName+"/tbp.mol",false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);

  const Conformer &conf = mol->getConformer();
  field=UFF::constructForceField(*mol);
  TEST_ASSERT(field);
  field->initialize();
  needMore = field->minimize(200,1e-8,1e-4);
  TEST_ASSERT(!needMore);
  v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(1));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(2));
  TEST_ASSERT(feq(v1.dotProduct(v2),-1.0,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(3));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));

  v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(2));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(3));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));

  v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4));
  TEST_ASSERT(feq(v1.dotProduct(v2),-0.5,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5));
  TEST_ASSERT(feq(v1.dotProduct(v2),-0.5,1e-3));

  v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5));
  TEST_ASSERT(feq(v1.dotProduct(v2),-0.5,1e-3));

  
  delete mol;
  delete field;
  

  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #2
0
void runMol(ROMol *mol,int checkEvery=10,bool verbose=true){
  ForceFields::ForceField *field;

  std::cout << MolToMolBlock(*mol) << "$$$$" << std::endl;

  try{
    field=UFF::constructForceField(*mol,2.5);
  } catch (...) {
    field=0;
  }
  if(field){
    field->initialize();
    int needMore=1;
    int nPasses=0;
    while(needMore){
#if 1
      needMore = field->minimize(checkEvery);
      if(verbose) std::cerr << "\t" << ++nPasses << std::endl;
#else
      needMore = field->minimize(1);
      std::cout << MolToMolBlock(mol) << "$$$$" << std::endl;
#endif
    }
    std::cout << MolToMolBlock(*mol) << "$$$$" << std::endl;
    delete field;
  } else {
    std::cerr << "failed";
  }
  
}
예제 #3
0
void testIssue242()
{
// FIX: Changes to the forcefield (connected to Issue 408) have
// made it so that this particular problem no longer manifests
// in this molecule/embedding. A new test case is needed.
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing Issue242." << std::endl;

  RWMol *mol, *mol2;
  int needMore;
  ForceFields::ForceField *field = 0, *field2 = 0;
  std::string mb1,mb2;
  double e1,e2;

  std::string pathName = getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/MMFF/test_data";

  mol = MolFileToMol(pathName + "/Issue242-2.mol");
  TEST_ASSERT(mol);

  mol2 = MolFileToMol(pathName + "/Issue242-2.mol");
  TEST_ASSERT(mol2);

  TEST_ASSERT(DGeomHelpers::EmbedMolecule(*mol2, 30, 2370) >= 0);
  mb1 = MolToMolBlock(*mol);
  mb2 = MolToMolBlock(*mol2);

  //std::cout << mb1 << "------\n";
  //std::cout << mb2 << "------\n";

  field = MMFF::constructForceField(*mol);
  TEST_ASSERT(field);
  field->initialize();
  field2 = MMFF::constructForceField(*mol2);
  TEST_ASSERT(field2);
  field2->initialize();
  e1 = field->calcEnergy();
  e2 = field2->calcEnergy();
  BOOST_LOG(rdInfoLog) << "E1: " << e1 << std::endl;
  BOOST_LOG(rdInfoLog) << "E2: " << e2 << std::endl;
  //TEST_ASSERT(feq(e2,e1,0.1));

  needMore = field->minimize(200,1.0e-4);
  needMore = field2->minimize(200,1.0e-4);
  e1 = field->calcEnergy();
  e2 = field2->calcEnergy();
  BOOST_LOG(rdInfoLog) << "E1: " << e1 << std::endl;
  BOOST_LOG(rdInfoLog) << "E2: " << e2 << std::endl;
  TEST_ASSERT(feq(e2, e1, 0.1));

  delete mol;
  delete mol2;
  delete field;
  delete field2;
  

  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #4
0
void testUFFMultiThread(){
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Test UFF multithreading" << std::endl;

  ForceFields::ForceField *field;

  std::string pathName = getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data";
  SDMolSupplier suppl(pathName + "/bulk.sdf");
  std::vector<ROMol *> mols;
  while(!suppl.atEnd()&&mols.size()<100){
    ROMol *mol=0;
    try{
      mol=suppl.next();
    } catch(...){
      continue;
    }
    if(!mol) continue;
    mols.push_back(mol);
  }

  std::cerr<<"generating reference data"<<std::endl;
  std::vector<double> energies(mols.size(),0.0);
  for(unsigned int i=0;i<mols.size();++i){
    ROMol mol(*mols[i]);
    ForceFields::ForceField *field = 0;
    try {
      field = UFF::constructForceField(mol);
    } catch (...) {
      field = 0;
    }
    TEST_ASSERT(field);
    field->initialize();
    int failed = field->minimize(500);
    TEST_ASSERT(!failed);
    energies[i]=field->calcEnergy();
    delete field;
  }
  
  boost::thread_group tg;

  std::cerr<<"processing"<<std::endl;
  unsigned int count=4;
  for(unsigned int i=0;i<count;++i){
    std::cerr<<" launch :"<<i<<std::endl;std::cerr.flush();
    tg.add_thread(new boost::thread(runblock_uff,mols,energies,count,i));
  }
  tg.join_all();
  
  BOOST_FOREACH(ROMol *mol,mols){
    delete mol;
  }
  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #5
0
ForceFields::ForceField *construct3DImproperForceField(
    const BoundsMatrix &mmat, RDGeom::Point3DPtrVect &positions,
    const std::vector<std::vector<int> > &improperAtoms,
    const std::vector<int> &atomNums) {
  (void)atomNums;
  unsigned int N = mmat.numRows();
  CHECK_INVARIANT(N == positions.size(), "");
  ForceFields::ForceField *field =
      new ForceFields::ForceField(positions[0]->dimension());
  for (unsigned int i = 0; i < N; ++i) {
    field->positions().push_back(positions[i]);
  }

  // improper torsions / out-of-plane bend / inversion
  double oobForceScalingFactor = 10.0;
  for (unsigned int t = 0; t < improperAtoms.size(); ++t) {
    std::vector<int> n(4);
    for (unsigned int i = 0; i < 3; ++i) {
      n[1] = 1;
      switch (i) {
        case 0:
          n[0] = 0;
          n[2] = 2;
          n[3] = 3;
          break;

        case 1:
          n[0] = 0;
          n[2] = 3;
          n[3] = 2;
          break;

        case 2:
          n[0] = 2;
          n[2] = 3;
          n[3] = 0;
          break;
      }
      ForceFields::UFF::InversionContrib *contrib =
          new ForceFields::UFF::InversionContrib(
              field, improperAtoms[t][n[0]], improperAtoms[t][n[1]],
              improperAtoms[t][n[2]], improperAtoms[t][n[3]],
              improperAtoms[t][4], improperAtoms[t][5], oobForceScalingFactor);
      field->contribs().push_back(ForceFields::ContribPtr(contrib));
    }
  }

  return field;

} // construct3DImproperForceField
예제 #6
0
void testCrippenO3AConstraints() {
  ROMol *m = SmilesToMol("n1ccc(cc1)-c1ccccc1");
  TEST_ASSERT(m);
  ROMol *m1 = MolOps::addHs(*m);
  delete m;
  TEST_ASSERT(m1);
  DGeomHelpers::EmbedMolecule(*m1);
  MMFF::sanitizeMMFFMol((RWMol &)(*m1));
  MMFF::MMFFMolProperties mp(*m1);
  TEST_ASSERT(mp.isValid());
  ForceFields::ForceField *field = MMFF::constructForceField(*m1, &mp);
  field->initialize();
  field->minimize();
  RWMol *patt = SmartsToMol("nccc-cccc");
  MatchVectType matchVect;
  TEST_ASSERT(SubstructMatch(*m1, (ROMol &)*patt, matchVect));
  unsigned int nIdx = matchVect[0].second;
  unsigned int cIdx = matchVect[matchVect.size() - 1].second;
  MolTransforms::setDihedralDeg(m1->getConformer(), matchVect[2].second,
    matchVect[3].second, matchVect[4].second, matchVect[5].second, 0.0);
  ROMol m2(*m1);
  MolAlign::randomTransform(m2);
  ROMol m3(m2);
  unsigned int prbNAtoms = m2.getNumAtoms();
  std::vector<double> prbLogpContribs(prbNAtoms);
  std::vector<double> prbMRContribs(prbNAtoms);
  std::vector<unsigned int> prbAtomTypes(prbNAtoms);
  std::vector<std::string> prbAtomTypeLabels(prbNAtoms);
  Descriptors::getCrippenAtomContribs(m2, prbLogpContribs,
    prbMRContribs, true, &prbAtomTypes, &prbAtomTypeLabels);
  MolAlign::O3A *o3a = new MolAlign::O3A(m2, *m1,
    &prbLogpContribs, &prbLogpContribs, MolAlign::O3A::CRIPPEN);
  TEST_ASSERT(o3a);
  o3a->align();
  delete o3a;
  double d = (m2.getConformer().getAtomPos(cIdx)
    - m1->getConformer().getAtomPos(cIdx)).length();
  TEST_ASSERT(feq(d, 0.0, 1));
  MatchVectType constraintMap;
  constraintMap.push_back(std::make_pair(cIdx, nIdx));
  o3a = new MolAlign::O3A(m3, *m1, &prbLogpContribs, &prbLogpContribs,
    MolAlign::O3A::CRIPPEN, -1, -1, false, 50, 0, &constraintMap);
  TEST_ASSERT(o3a);
  o3a->align();
  delete o3a;
  d = (m3.getConformer().getAtomPos(cIdx)
    - m1->getConformer().getAtomPos(cIdx)).length();
  TEST_ASSERT(feq(d, 7.0, 1.0));
  delete m1;
}
예제 #7
0
void testGithub308()
{
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing github 308: crash during MMFF parameterization ." << std::endl;
  ROMol *mol = SmilesToMol("FF");
  TEST_ASSERT(DGeomHelpers::EmbedMolecule(*mol) >= 0);
  int needMore;
  ForceFields::ForceField *field = 0;
  TEST_ASSERT(mol);
  MMFF::MMFFMolProperties mmffMolProperties(*mol);
  TEST_ASSERT(mmffMolProperties.isValid());
  field = MMFF::constructForceField(*mol);
  TEST_ASSERT(field);
  field->initialize();
  needMore = field->minimize(200, 1.0e-6, 1.0e-3);
  TEST_ASSERT(!needMore);
}
예제 #8
0
 int MMFFOptimizeMolecule(ROMol &mol, std::string mmffVariant = "MMFF94",
   int maxIters = 200, double nonBondedThresh = 100.0, int confId = -1,
   bool ignoreInterfragInteractions = true)
 {
   int res = -1;
   
   MMFF::MMFFMolProperties mmffMolProperties(mol, mmffVariant);
   if (mmffMolProperties.isValid()) {
     ForceFields::ForceField *ff = MMFF::constructForceField(mol,
       &mmffMolProperties, nonBondedThresh, confId, ignoreInterfragInteractions);
     ff->initialize();
     res = ff->minimize(maxIters);
     delete ff;
   }
   
   return res;
 }
예제 #9
0
void testMMFFBatch() {
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog)
      << "    Testing bulk MMFF (regression to check that things run)."
      << std::endl;

  ROMol *mol;

  ForceFields::ForceField *field;

  std::string pathName = getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/MMFF/test_data";
  SDMolSupplier suppl(pathName + "/bulk.sdf");

  int count = 0;
  mol = suppl.next();
  while (mol && (!(suppl.atEnd()))) {
    ++count;
    std::string origMolBlock = MolToMolBlock(*mol);

    BOOST_LOG(rdErrorLog) << "Mol:" << count << std::endl;
    try {
      field = MMFF::constructForceField(*mol);
    } catch (...) {
      field = 0;
    }
    if (field) {
      field->initialize();
      int failed = field->minimize(500);
      if (failed) {
        BOOST_LOG(rdErrorLog) << " not converged (code = " << failed << ")"
                              << std::endl;
        std::cout << origMolBlock << "$$$$" << std::endl;
        std::cout << MolToMolBlock(*mol) << "$$$$" << std::endl;
      }
      delete field;
    }
    delete mol;
    mol = suppl.next();
  }

  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #10
0
void testIssue239(){
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing Issue239." << std::endl;

  RWMol *mol;
  int needMore;
  ForceFields::ForceField *field;
  double e1,e2;

  std::string pathName=getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data";
  mol = MolFileToMol(pathName+"/Issue239.mol",false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);

  field=UFF::constructForceField(*mol);
  TEST_ASSERT(field);
  field->initialize();
  needMore = field->minimize(200,1e-6,1e-3);
  e1 = field->calcEnergy();
  needMore = field->minimize(200,1e-6,1e-3);
  e2 = field->calcEnergy();
  TEST_ASSERT(feq(e2,e1,0.1));
  
  delete mol;
  delete field;
  

  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #11
0
ForceFields::ForceField *constructForceField(
    const BoundsMatrix &mmat, RDGeom::PointPtrVect &positions,
    const VECT_CHIRALSET &csets, double weightChiral, double weightFourthDim,
    std::map<std::pair<int, int>, double> *extraWeights, double basinSizeTol) {
  unsigned int N = mmat.numRows();
  CHECK_INVARIANT(N == positions.size(), "");
  ForceFields::ForceField *field =
      new ForceFields::ForceField(positions[0]->dimension());
  for (unsigned int i = 0; i < N; i++) {
    field->positions().push_back(positions[i]);
  }

  for (unsigned int i = 1; i < N; i++) {
    for (unsigned int j = 0; j < i; j++) {
      double w = 1.0;
      double l = mmat.getLowerBound(i, j);
      double u = mmat.getUpperBound(i, j);
      bool includeIt = false;
      if (extraWeights) {
        std::map<std::pair<int, int>, double>::const_iterator mapIt;
        mapIt = extraWeights->find(std::make_pair(i, j));
        if (mapIt != extraWeights->end()) {
          w = mapIt->second;
          includeIt = true;
        }
      }
      if (u - l <= basinSizeTol) {
        includeIt = true;
      }
      if (includeIt) {
        DistViolationContrib *contrib =
            new DistViolationContrib(field, i, j, u, l, w);
        field->contribs().push_back(ForceFields::ContribPtr(contrib));
      }
    }
  }

  // now add chiral constraints
  if (weightChiral > 1.e-8) {
    for (VECT_CHIRALSET::const_iterator csi = csets.begin(); csi != csets.end();
         csi++) {
      ChiralViolationContrib *contrib =
          new ChiralViolationContrib(field, csi->get(), weightChiral);
      field->contribs().push_back(ForceFields::ContribPtr(contrib));
    }
  }

  // finally the contribution from the fourth dimension if we need to
  if ((field->dimension() == 4) && (weightFourthDim > 1.e-8)) {
    for (unsigned int i = 1; i < N; i++) {
      FourthDimContrib *contrib =
          new FourthDimContrib(field, i, weightFourthDim);
      field->contribs().push_back(ForceFields::ContribPtr(contrib));
    }
  }
  return field;
}  // constructForceField
예제 #12
0
void testGitHubIssue62() {
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing GitHubIssue62." << std::endl;

  std::string pathName=getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data";
  {
    double energyValues[] =
      { 38.687, 174.698, 337.986, 115.248,
        2.482, 1.918, 10.165, 98.469, 39.078,
        267.236, 15.747, 202.121, 205.539,
        20.044, 218.986, 79.627 };
    SmilesMolSupplier smiSupplier(pathName + "/Issue62.smi");
    SDWriter *sdfWriter = new SDWriter(pathName + "/Issue62.sdf");
    for (unsigned int i = 0; i < smiSupplier.length(); ++i) {
      ROMol *mol = MolOps::addHs(*(smiSupplier[i]));
      TEST_ASSERT(mol);
      std::string molName = "";
      if (mol->hasProp(common_properties::_Name)) {
        mol->getProp(common_properties::_Name, molName);
      }
      DGeomHelpers::EmbedMolecule(*mol);
      ForceFields::ForceField *field = UFF::constructForceField(*mol);
      TEST_ASSERT(field);
      field->initialize();
      int needMore = field->minimize(200, 1.e-6, 1.e-3);
      TEST_ASSERT(!needMore);
      sdfWriter->write(*mol);
      double e = field->calcEnergy();
      BOOST_LOG(rdErrorLog) << molName << " " << e << std::endl;
      TEST_ASSERT(fabs(e - energyValues[i]) < 1.);
    }
    sdfWriter->close();
    BOOST_LOG(rdErrorLog) << "  done" << std::endl;
  }
}
예제 #13
0
void testSFIssue1653802(){
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing SFIssue1653802." << std::endl;

  RWMol *mol;
  int needMore;
  ForceFields::ForceField *field;

  std::string pathName=getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data";

  mol = MolFileToMol(pathName+"/cyclobutadiene.mol",false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);


  UFF::AtomicParamVect types;
  bool foundAll;
  boost::shared_array<boost::uint8_t> nbrMat;
  boost::tie(types,foundAll)=UFF::getAtomTypes(*mol);
  TEST_ASSERT(foundAll);
  TEST_ASSERT(types.size()==mol->getNumAtoms());
  field=new ForceFields::ForceField();
  UFF::Tools::addBonds(*mol,types,field);
  TEST_ASSERT(field->contribs().size()==8);

  nbrMat = UFF::Tools::buildNeighborMatrix(*mol);
  UFF::Tools::addAngles(*mol,types,field);
  TEST_ASSERT(field->contribs().size()==20);
  UFF::Tools::addTorsions(*mol,types,field);
  //std::cout << field->contribs().size() << std::endl;
  TEST_ASSERT(field->contribs().size()==36);
  UFF::Tools::addNonbonded(*mol,0,types,field,nbrMat);
  delete field;

  field = UFF::constructForceField(*mol);
  field->initialize();
  needMore = field->minimize(200,1e-6,1e-3);
  TEST_ASSERT(!needMore);
  
  delete mol;
  delete field;
  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #14
0
void testSFIssue1653802() {
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing SFIssue1653802." << std::endl;

  RWMol *mol;
  int needMore;
  ForceFields::ForceField *field;

  std::string pathName = getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/MMFF/test_data";

  mol = MolFileToMol(pathName + "/cyclobutadiene.mol", false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);
  MMFF::MMFFMolProperties *mmffMolProperties =
      new MMFF::MMFFMolProperties(*mol);
  TEST_ASSERT(mmffMolProperties);

  boost::shared_array<boost::uint8_t> nbrMat;
  field = new ForceFields::ForceField();
  MMFF::Tools::addBonds(*mol, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 8);

  nbrMat = MMFF::Tools::buildNeighborMatrix(*mol);
  MMFF::Tools::addAngles(*mol, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 20);
  MMFF::Tools::addTorsions(*mol, mmffMolProperties, field);
  // std::cout << field->contribs().size() << std::endl;
  TEST_ASSERT(field->contribs().size() == 36);
  MMFF::Tools::addVdW(*mol, 0, mmffMolProperties, field, nbrMat);
  delete field;

  field = MMFF::constructForceField(*mol);
  field->initialize();
  needMore = field->minimize(200, 1.0e-6, 1.0e-3);
  TEST_ASSERT(!needMore);

  delete mol;
  delete field;
  delete mmffMolProperties;
  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #15
0
void testUFFBuilder2(){
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing UFF builder+minimization." << std::endl;

  RWMol *mol;
  std::string key;
  int needMore;

  ForceFields::ForceField *field;

  std::string pathName=getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data";
  mol = MolFileToMol(pathName+"/small1.mol",false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);

  field=UFF::constructForceField(*mol);
  TEST_ASSERT(field);
  field->initialize();
  needMore = field->minimize();
  TEST_ASSERT(!needMore);
  //std::cout << MolToMolBlock(mol);
  delete mol;
  delete field;

  mol = MolFileToMol(pathName+"/small2.mol",false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);

  field=UFF::constructForceField(*mol);
  TEST_ASSERT(field);
  field->initialize();
  needMore = field->minimize(150);
  TEST_ASSERT(!needMore);
  //std::cout << MolToMolBlock(mol);
  delete mol;
  delete field;

  mol = MolFileToMol(pathName+"/benzene.mol",false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);

  field=UFF::constructForceField(*mol);
  TEST_ASSERT(field);
  field->initialize();
  needMore = field->minimize();
  TEST_ASSERT(!needMore);
  //std::cout << MolToMolBlock(mol);
  delete mol;
  delete field;
  
  mol = MolFileToMol(pathName+"/toluene.mol",false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);

  field=UFF::constructForceField(*mol);
  TEST_ASSERT(field);
  field->initialize();
  needMore = field->minimize();
  TEST_ASSERT(!needMore);
  //std::cout << MolToMolBlock(mol);
  delete mol;
  delete field;

  mol = MolFileToMol(pathName+"/complex1.mol",false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);

  field=UFF::constructForceField(*mol);
  TEST_ASSERT(field);
  field->initialize();
  needMore = field->minimize();
  TEST_ASSERT(!needMore);
  //std::cout << MolToMolBlock(mol);
  delete mol;
  delete field;

  

  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #16
0
void testUFFBuilder1(){
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing UFF builder tools." << std::endl;

  ROMol *mol,*mol2;
  std::string key;

  UFF::AtomicParamVect types;
  bool foundAll;
  ForceFields::ForceField *field;
  boost::shared_array<boost::uint8_t> nbrMat;

  mol = SmilesToMol("CC(O)C");
  Conformer *conf = new Conformer(mol->getNumAtoms());
  int cid = static_cast<int>(mol->addConformer(conf, true));
  TEST_ASSERT(mol);
  boost::tie(types,foundAll)=UFF::getAtomTypes(*mol);
  TEST_ASSERT(foundAll);
  TEST_ASSERT(types.size()==mol->getNumAtoms());
  field=new ForceFields::ForceField();
  UFF::Tools::addBonds(*mol,types,field);

  TEST_ASSERT(field->contribs().size()==3);

  nbrMat = UFF::Tools::buildNeighborMatrix(*mol);
  TEST_ASSERT(UFF::Tools::getTwoBitCell(nbrMat,0)==UFF::Tools::RELATION_1_X);
  TEST_ASSERT(UFF::Tools::getTwoBitCell(nbrMat,1)==UFF::Tools::RELATION_1_2);
  TEST_ASSERT(UFF::Tools::getTwoBitCell(nbrMat,2)==UFF::Tools::RELATION_1_3);
  TEST_ASSERT(UFF::Tools::getTwoBitCell(nbrMat,3)==UFF::Tools::RELATION_1_3);

  UFF::Tools::addAngles(*mol,types,field);
  TEST_ASSERT(field->contribs().size()==6);

  // there are no non-bonded terms here:
  UFF::Tools::addNonbonded(*mol,cid,types,field,nbrMat);
  TEST_ASSERT(field->contribs().size()==6);

  // and no torsions either, until we add Hs:
  UFF::Tools::addTorsions(*mol,types,field);
  TEST_ASSERT(field->contribs().size()==6);

  delete mol;
  delete field;
  mol = SmilesToMol("CCOC");
  Conformer *conf2 = new Conformer(mol->getNumAtoms());
  cid = static_cast<int>(mol->addConformer(conf2, true));
  TEST_ASSERT(mol);
  boost::tie(types,foundAll)=UFF::getAtomTypes(*mol);
  TEST_ASSERT(foundAll);
  TEST_ASSERT(types.size()==mol->getNumAtoms());
  field=new ForceFields::ForceField();
  UFF::Tools::addBonds(*mol,types,field);

  TEST_ASSERT(field->contribs().size()==3);

  nbrMat = UFF::Tools::buildNeighborMatrix(*mol);
  TEST_ASSERT(UFF::Tools::getTwoBitCell(nbrMat,0)==UFF::Tools::RELATION_1_X);
  TEST_ASSERT(UFF::Tools::getTwoBitCell(nbrMat,1)==UFF::Tools::RELATION_1_2);
  TEST_ASSERT(UFF::Tools::getTwoBitCell(nbrMat,2)==UFF::Tools::RELATION_1_3);
  TEST_ASSERT(UFF::Tools::getTwoBitCell(nbrMat,3)==UFF::Tools::RELATION_1_X);

  UFF::Tools::addAngles(*mol,types,field);
  TEST_ASSERT(field->contribs().size()==5);
  UFF::Tools::addNonbonded(*mol,cid,types,field,nbrMat);
  TEST_ASSERT(field->contribs().size()==6);
  UFF::Tools::addTorsions(*mol,types,field);
  TEST_ASSERT(field->contribs().size()==7);



  delete mol;
  delete field;
  mol = SmilesToMol("CO");
  Conformer *conf3 = new Conformer(mol->getNumAtoms());
  cid = static_cast<int>(mol->addConformer(conf3, true));
  TEST_ASSERT(mol);
  boost::tie(types,foundAll)=UFF::getAtomTypes(*mol);
  TEST_ASSERT(foundAll);
  TEST_ASSERT(types.size()==mol->getNumAtoms());

  field=new ForceFields::ForceField();
  UFF::Tools::addBonds(*mol,types,field);

  TEST_ASSERT(field->contribs().size()==1);

  nbrMat = UFF::Tools::buildNeighborMatrix(*mol);
  TEST_ASSERT(UFF::Tools::getTwoBitCell(nbrMat,0)==UFF::Tools::RELATION_1_X);
  TEST_ASSERT(UFF::Tools::getTwoBitCell(nbrMat,1)==UFF::Tools::RELATION_1_2);

  UFF::Tools::addAngles(*mol,types,field);
  TEST_ASSERT(field->contribs().size()==1);
  UFF::Tools::addNonbonded(*mol,cid,types,field,nbrMat);
  TEST_ASSERT(field->contribs().size()==1);
  UFF::Tools::addTorsions(*mol,types,field);
  TEST_ASSERT(field->contribs().size()==1);

  
  mol2 = MolOps::addHs(*mol);
  TEST_ASSERT(mol2->getNumAtoms()==6);
  delete field;
  
  boost::tie(types,foundAll)=UFF::getAtomTypes(*mol2);
  TEST_ASSERT(foundAll);
  TEST_ASSERT(types.size()==mol2->getNumAtoms());

  field=new ForceFields::ForceField();
  UFF::Tools::addBonds(*mol2,types,field);
  TEST_ASSERT(field->contribs().size()==5);

  nbrMat = UFF::Tools::buildNeighborMatrix(*mol2);
  UFF::Tools::addAngles(*mol2,types,field);
  TEST_ASSERT(field->contribs().size()==12);
  UFF::Tools::addNonbonded(*mol2,cid,types,field,nbrMat);
  TEST_ASSERT(field->contribs().size()==15);
  UFF::Tools::addTorsions(*mol2,types,field);
  TEST_ASSERT(field->contribs().size()==18);
  delete mol2;

  delete mol;
  delete field;
  
  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #17
0
void testMMFFBuilder1() {
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing MMFF builder tools." << std::endl;

  ROMol *mol, *mol2;

  ForceFields::ForceField *field;
  boost::shared_array<boost::uint8_t> nbrMat;

  mol = SmilesToMol("CC(O)C");
  Conformer *conf = new Conformer(mol->getNumAtoms());
  int cid = static_cast<int>(mol->addConformer(conf, true));
  TEST_ASSERT(mol);
  MMFF::MMFFMolProperties *mmffMolProperties =
      new MMFF::MMFFMolProperties(*mol);
  TEST_ASSERT(mmffMolProperties);
  TEST_ASSERT(mmffMolProperties->isValid());
  field = new ForceFields::ForceField();
  MMFF::Tools::addBonds(*mol, mmffMolProperties, field);

  TEST_ASSERT(field->contribs().size() == 3);

  nbrMat = MMFF::Tools::buildNeighborMatrix(*mol);
  // the neighbor matrix is an upper triangular matrix
  // position indices are as follows:
  //  0  1  2  3
  //     4  5  6
  //        7  8
  //           9
  TEST_ASSERT(MMFF::Tools::twoBitCellPos(mol->getNumAtoms(), 1, 1) == 4);
  TEST_ASSERT(MMFF::Tools::twoBitCellPos(mol->getNumAtoms(), 2, 1) == 5);
  TEST_ASSERT(MMFF::Tools::twoBitCellPos(mol->getNumAtoms(), 1, 2) == 5);
  TEST_ASSERT(MMFF::Tools::getTwoBitCell(nbrMat, 0) ==
              MMFF::Tools::RELATION_1_X);
  TEST_ASSERT(MMFF::Tools::getTwoBitCell(nbrMat, 1) ==
              MMFF::Tools::RELATION_1_2);
  TEST_ASSERT(MMFF::Tools::getTwoBitCell(nbrMat, 2) ==
              MMFF::Tools::RELATION_1_3);
  TEST_ASSERT(MMFF::Tools::getTwoBitCell(nbrMat, 3) ==
              MMFF::Tools::RELATION_1_3);

  MMFF::Tools::addAngles(*mol, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 6);

  // there are no non-bonded terms here:
  MMFF::Tools::addVdW(*mol, cid, mmffMolProperties, field, nbrMat);
  TEST_ASSERT(field->contribs().size() == 6);

  // and no torsions either, until we add Hs:
  MMFF::Tools::addTorsions(*mol, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 6);

  delete mol;
  delete field;
  delete mmffMolProperties;
  mol = SmilesToMol("CCOC");
  Conformer *conf2 = new Conformer(mol->getNumAtoms());
  cid = static_cast<int>(mol->addConformer(conf2, true));
  TEST_ASSERT(mol);
  mmffMolProperties = new MMFF::MMFFMolProperties(*mol);
  TEST_ASSERT(mmffMolProperties);
  TEST_ASSERT(mmffMolProperties->isValid());
  field = new ForceFields::ForceField();
  MMFF::Tools::addBonds(*mol, mmffMolProperties, field);

  TEST_ASSERT(field->contribs().size() == 3);

  nbrMat = MMFF::Tools::buildNeighborMatrix(*mol);
  TEST_ASSERT(MMFF::Tools::getTwoBitCell(nbrMat, 0) ==
              MMFF::Tools::RELATION_1_X);
  TEST_ASSERT(MMFF::Tools::getTwoBitCell(nbrMat, 1) ==
              MMFF::Tools::RELATION_1_2);
  TEST_ASSERT(MMFF::Tools::getTwoBitCell(nbrMat, 2) ==
              MMFF::Tools::RELATION_1_3);
  TEST_ASSERT(MMFF::Tools::getTwoBitCell(nbrMat, 3) ==
              MMFF::Tools::RELATION_1_4);

  MMFF::Tools::addAngles(*mol, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 5);
  MMFF::Tools::addVdW(*mol, cid, mmffMolProperties, field, nbrMat);
  TEST_ASSERT(field->contribs().size() == 6);
  MMFF::Tools::addTorsions(*mol, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 7);

  delete mol;
  delete field;
  delete mmffMolProperties;
  mol = SmilesToMol("CO");
  Conformer *conf3 = new Conformer(mol->getNumAtoms());
  cid = static_cast<int>(mol->addConformer(conf3, true));
  TEST_ASSERT(mol);
  mmffMolProperties = new MMFF::MMFFMolProperties(*mol);
  TEST_ASSERT(mmffMolProperties);
  TEST_ASSERT(mmffMolProperties->isValid());

  field = new ForceFields::ForceField();
  MMFF::Tools::addBonds(*mol, mmffMolProperties, field);

  TEST_ASSERT(field->contribs().size() == 1);

  nbrMat = MMFF::Tools::buildNeighborMatrix(*mol);
  TEST_ASSERT(MMFF::Tools::getTwoBitCell(nbrMat, 0) ==
              MMFF::Tools::RELATION_1_X);
  TEST_ASSERT(MMFF::Tools::getTwoBitCell(nbrMat, 1) ==
              MMFF::Tools::RELATION_1_2);

  MMFF::Tools::addAngles(*mol, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 1);
  MMFF::Tools::addVdW(*mol, cid, mmffMolProperties, field, nbrMat);
  TEST_ASSERT(field->contribs().size() == 1);
  MMFF::Tools::addTorsions(*mol, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 1);

  mol2 = MolOps::addHs(*mol);
  TEST_ASSERT(mol2->getNumAtoms() == 6);
  delete field;
  delete mmffMolProperties;

  mmffMolProperties = new MMFF::MMFFMolProperties(*mol2);
  TEST_ASSERT(mmffMolProperties);
  TEST_ASSERT(mmffMolProperties->isValid());

  field = new ForceFields::ForceField();
  MMFF::Tools::addBonds(*mol2, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 5);

  nbrMat = MMFF::Tools::buildNeighborMatrix(*mol2);
  MMFF::Tools::addAngles(*mol2, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 12);
  MMFF::Tools::addVdW(*mol2, cid, mmffMolProperties, field, nbrMat);
  TEST_ASSERT(field->contribs().size() == 15);
  MMFF::Tools::addTorsions(*mol2, mmffMolProperties, field);
  TEST_ASSERT(field->contribs().size() == 18);
  delete mol2;

  delete mol;
  delete field;
  delete mmffMolProperties;

  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #18
0
ForceFields::ForceField *construct3DForceField(
    const BoundsMatrix &mmat, RDGeom::Point3DPtrVect &positions,
    const std::vector<std::pair<int, int> > &bonds,
    const std::vector<std::vector<int> > &angles,
    const std::vector<std::vector<int> > &expTorsionAtoms,
    const std::vector<std::pair<std::vector<int>, std::vector<double> > > &
        expTorsionAngles,
    const std::vector<std::vector<int> > &improperAtoms,
    const std::vector<int> &atomNums) {
  (void)atomNums;
  unsigned int N = mmat.numRows();
  CHECK_INVARIANT(N == positions.size(), "");
  CHECK_INVARIANT(expTorsionAtoms.size() == expTorsionAngles.size(), "");
  ForceFields::ForceField *field =
      new ForceFields::ForceField(positions[0]->dimension());
  for (unsigned int i = 0; i < N; ++i) {
    field->positions().push_back(positions[i]);
  }

  // keep track which atoms are 1,2- or 1,3-restrained
  boost::dynamic_bitset<> atomPairs(N * N);

  // torsion constraints
  for (unsigned int t = 0; t < expTorsionAtoms.size(); ++t) {
    int i = expTorsionAtoms[t][0];
    int j = expTorsionAtoms[t][1];
    int k = expTorsionAtoms[t][2];
    int l = expTorsionAtoms[t][3];
    if (i < j)
      atomPairs[i * N + j] = 1;
    else
      atomPairs[j * N + i] = 1;
    // expTorsionAngles[t][0] = (signs, V's)
    ForceFields::CrystalFF::TorsionAngleContribM6 *contrib =
        new ForceFields::CrystalFF::TorsionAngleContribM6(
            field, i, j, k, l, expTorsionAngles[t].second,
            expTorsionAngles[t].first);
    field->contribs().push_back(ForceFields::ContribPtr(contrib));
  }  // torsion constraints

  // improper torsions / out-of-plane bend / inversion
  double oobForceScalingFactor = 10.0;
  for (unsigned int t = 0; t < improperAtoms.size(); ++t) {
    std::vector<int> n(4);
    for (unsigned int i = 0; i < 3; ++i) {
      n[1] = 1;
      switch (i) {
        case 0:
          n[0] = 0;
          n[2] = 2;
          n[3] = 3;
          break;

        case 1:
          n[0] = 0;
          n[2] = 3;
          n[3] = 2;
          break;

        case 2:
          n[0] = 2;
          n[2] = 3;
          n[3] = 0;
          break;
      }
      ForceFields::UFF::InversionContrib *contrib =
          new ForceFields::UFF::InversionContrib(
              field, improperAtoms[t][n[0]], improperAtoms[t][n[1]],
              improperAtoms[t][n[2]], improperAtoms[t][n[3]],
              improperAtoms[t][4], improperAtoms[t][5], oobForceScalingFactor);
      field->contribs().push_back(ForceFields::ContribPtr(contrib));
    }
  }

  double fdist = 100.0;  // force constant
  // 1,2 distance constraints
  std::vector<std::pair<int, int> >::const_iterator bi;
  for (bi = bonds.begin(); bi != bonds.end(); ++bi) {
    unsigned int i = bi->first;
    unsigned int j = bi->second;
    if (i < j)
      atomPairs[i * N + j] = 1;
    else
      atomPairs[j * N + i] = 1;
    double d = ((*positions[i]) - (*positions[j])).length();
    double l = d - 0.01;
    double u = d + 0.01;
    ForceFields::UFF::DistanceConstraintContrib *contrib =
        new ForceFields::UFF::DistanceConstraintContrib(field, i, j, l, u,
                                                        fdist);
    field->contribs().push_back(ForceFields::ContribPtr(contrib));
  }

  // 1,3 distance constraints
  for (unsigned int a = 0; a < angles.size(); ++a) {
    unsigned int i = angles[a][0];
    unsigned int j = angles[a][1];
    unsigned int k = angles[a][2];
    if (i < j)
      atomPairs[i * N + j] = 1;
    else
      atomPairs[j * N + i] = 1;
    // check for triple bonds
    if (angles[a][3]) {
      ForceFields::UFF::AngleConstraintContrib *contrib =
          new ForceFields::UFF::AngleConstraintContrib(field, i, j, k, 179.0,
                                                       180.0, fdist);
      field->contribs().push_back(ForceFields::ContribPtr(contrib));
    } else {
      double d = ((*positions[i]) - (*positions[k])).length();
      double l = d - 0.01;
      double u = d + 0.01;
      ForceFields::UFF::DistanceConstraintContrib *contrib =
          new ForceFields::UFF::DistanceConstraintContrib(field, i, k, l, u,
                                                          fdist);
      field->contribs().push_back(ForceFields::ContribPtr(contrib));
    }
  }

  // minimum distance for all other atom pairs
  fdist = 10.0;
  for (unsigned int i = 1; i < N; ++i) {
    for (unsigned int j = 0; j < i; ++j) {
      if (!atomPairs[j * N + i]) {
        double l = mmat.getLowerBound(i, j);
        double u = mmat.getUpperBound(i, j);
        ForceFields::UFF::DistanceConstraintContrib *contrib =
            new ForceFields::UFF::DistanceConstraintContrib(field, i, j, l, u,
                                                            fdist);
        field->contribs().push_back(ForceFields::ContribPtr(contrib));
      }
    }
  }

  return field;
}  // construct3DForceField
예제 #19
0
파일: DistGeom.cpp 프로젝트: Acpharis/rdkit
  PyObject *embedBoundsMatrix(python::object boundsMatArg,int maxIters=10,
                              bool randomizeOnFailure=false,int numZeroFail=2,
                              python::list weights=python::list(),
                              int randomSeed=-1){
    PyObject *boundsMatObj = boundsMatArg.ptr();
    if(!PyArray_Check(boundsMatObj))
      throw_value_error("Argument isn't an array");
    
    PyArrayObject *boundsMat=reinterpret_cast<PyArrayObject *>(boundsMatObj);
    // get the dimensions of the array
    unsigned int nrows = boundsMat->dimensions[0];
    unsigned int ncols = boundsMat->dimensions[1];
    if(nrows!=ncols)
      throw_value_error("The array has to be square");
    if(nrows<=0)
      throw_value_error("The array has to have a nonzero size");
    if (boundsMat->descr->type_num != PyArray_DOUBLE)
      throw_value_error("Only double arrays are currently supported");

    unsigned int dSize = nrows*nrows;
    double *cData = new double[dSize];
    double *inData = reinterpret_cast<double *>(boundsMat->data);
    memcpy(static_cast<void *>(cData), 
           static_cast<const void *>(inData),
           dSize*sizeof(double));

    DistGeom::BoundsMatrix::DATA_SPTR sdata(cData);
    DistGeom::BoundsMatrix bm(nrows,sdata);

    RDGeom::Point3D *positions=new RDGeom::Point3D[nrows];
    std::vector<RDGeom::Point *> posPtrs;
    for (unsigned int i = 0; i < nrows; i++) {
      posPtrs.push_back(&positions[i]);
    }

    RDNumeric::DoubleSymmMatrix distMat(nrows, 0.0);

    // ---- ---- ---- ---- ---- ---- ---- ---- ---- 
    // start the embedding:
    bool gotCoords=false;
    for(int iter=0;iter<maxIters && !gotCoords;iter++){
      // pick a random distance matrix
      DistGeom::pickRandomDistMat(bm,distMat,randomSeed);

      // and embed it:
      gotCoords=DistGeom::computeInitialCoords(distMat,posPtrs,randomizeOnFailure,
                                               numZeroFail,randomSeed);

      // update the seed:
      if(randomSeed>=0) randomSeed+=iter*999;
    }

    if(gotCoords){
      std::map<std::pair<int,int>,double> weightMap;
      unsigned int nElems=PySequence_Size(weights.ptr());
      for(unsigned int entryIdx=0;entryIdx<nElems;entryIdx++){
        PyObject *entry=PySequence_GetItem(weights.ptr(),entryIdx);
        if(!PySequence_Check(entry) || PySequence_Size(entry)!=3){
          throw_value_error("weights argument must be a sequence of 3-sequences");
        }
        int idx1=PyInt_AsLong(PySequence_GetItem(entry,0));
        int idx2=PyInt_AsLong(PySequence_GetItem(entry,1));
        double w=PyFloat_AsDouble(PySequence_GetItem(entry,2));
        weightMap[std::make_pair(idx1,idx2)]=w;
      }
      DistGeom::VECT_CHIRALSET csets;
      ForceFields::ForceField *field = DistGeom::constructForceField(bm,posPtrs,csets,0.0, 0.0,
                                                                     &weightMap);
      CHECK_INVARIANT(field,"could not build dgeom force field");
      field->initialize();
      if(field->calcEnergy()>1e-5){
        int needMore=1;
        while(needMore){
          needMore=field->minimize();
        }
      }
      delete field;
    } else {
      throw_value_error("could not embed matrix");
    }

    // ---- ---- ---- ---- ---- ---- ---- ---- ---- 
    // construct the results matrix:
    npy_intp dims[2];
    dims[0] = nrows;
    dims[1] = 3;
    PyArrayObject *res = (PyArrayObject *)PyArray_SimpleNew(2,dims,NPY_DOUBLE);
    double *resData=reinterpret_cast<double *>(res->data);
    for(unsigned int i=0;i<nrows;i++){
      unsigned int iTab=i*3;
      for (unsigned int j = 0; j < 3; ++j) {
        resData[iTab + j]=positions[i][j]; //.x;
      }
    }
    delete [] positions;

    return PyArray_Return(res);
  }
예제 #20
0
void testSFIssue2378119() {
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing SFIssue2378119." << std::endl;

  std::string pathName = getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/MMFF/test_data";
  {
    RWMol *mol = MolFileToMol(pathName + "/Issue2378119.mol");
    TEST_ASSERT(mol);
    ForceFields::ForceField *field = MMFF::constructForceField(*mol);
    TEST_ASSERT(field);
    field->initialize();
    double e1 = field->calcEnergy();
    TEST_ASSERT(e1 > 0.0 && e1 < 1.0e12);

    int needMore = field->minimize(200, 1.0e-6, 1.0e-3);
    TEST_ASSERT(!needMore);
    double e2 = field->calcEnergy();
    TEST_ASSERT(e2 < e1);

    delete mol;
    delete field;
  }
  {
    RWMol *mol = MolFileToMol(pathName + "/Issue2378119.2.mol");
    TEST_ASSERT(mol);
    ForceFields::ForceField *field = MMFF::constructForceField(*mol);
    TEST_ASSERT(field);
    field->initialize();
    double e1 = field->calcEnergy();
    TEST_ASSERT(e1 == 0.0);

    int needMore = field->minimize(200, 1.0e-6, 1.0e-3);
    TEST_ASSERT(!needMore);
    double e2 = field->calcEnergy();
    TEST_ASSERT(e2 == e1);

    delete mol;
    delete field;
  }
  {
    RWMol *mol = MolFileToMol(pathName + "/Issue2378119.2.mol");
    TEST_ASSERT(mol);
    ForceFields::ForceField *field =
        MMFF::constructForceField(*mol, 100.0, -1, false);
    TEST_ASSERT(field);
    field->initialize();
    double e1 = field->calcEnergy();
    TEST_ASSERT(e1 > 0.0 && e1 < 1.0e12);

    int needMore = field->minimize(200, 1.0e-6, 1.0e-3);
    TEST_ASSERT(!needMore);
    double e2 = field->calcEnergy();
    TEST_ASSERT(e2 < e1);

    delete mol;
    delete field;
  }
  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
예제 #21
0
ForceFields::ForceField *constructPlain3DForceField(
    const BoundsMatrix &mmat, RDGeom::Point3DPtrVect &positions,
    const std::vector<std::pair<int, int> > &bonds,
    const std::vector<std::vector<int> > &angles,
    const std::vector<std::vector<int> > &expTorsionAtoms,
    const std::vector<std::pair<std::vector<int>, std::vector<double> > > &
        expTorsionAngles,
    const std::vector<int> &atomNums) {
  (void)atomNums;
  unsigned int N = mmat.numRows();
  CHECK_INVARIANT(N == positions.size(), "");
  CHECK_INVARIANT(expTorsionAtoms.size() == expTorsionAngles.size(), "");
  ForceFields::ForceField *field =
      new ForceFields::ForceField(positions[0]->dimension());
  for (unsigned int i = 0; i < N; ++i) {
    field->positions().push_back(positions[i]);
  }

  // keep track which atoms are 1,2- or 1,3-restrained
  boost::dynamic_bitset<> atomPairs(N * N);

  // torsion constraints
  for (unsigned int t = 0; t < expTorsionAtoms.size(); ++t) {
    int i = expTorsionAtoms[t][0];
    int j = expTorsionAtoms[t][1];
    int k = expTorsionAtoms[t][2];
    int l = expTorsionAtoms[t][3];
    if (i < j)
      atomPairs[i * N + j] = 1;
    else
      atomPairs[j * N + i] = 1;
    // expTorsionAngles[t][0] = (signs, V's)
    ForceFields::CrystalFF::TorsionAngleContribM6 *contrib =
        new ForceFields::CrystalFF::TorsionAngleContribM6(
            field, i, j, k, l, expTorsionAngles[t].second,
            expTorsionAngles[t].first);
    field->contribs().push_back(ForceFields::ContribPtr(contrib));
  }  // torsion constraints

  double fdist = 100.0;  // force constant
  // 1,2 distance constraints
  std::vector<std::pair<int, int> >::const_iterator bi;
  for (bi = bonds.begin(); bi != bonds.end(); ++bi) {
    unsigned int i = bi->first;
    unsigned int j = bi->second;
    if (i < j)
      atomPairs[i * N + j] = 1;
    else
      atomPairs[j * N + i] = 1;
    double d = ((*positions[i]) - (*positions[j])).length();
    double l = d - 0.01;
    double u = d + 0.01;
    ForceFields::UFF::DistanceConstraintContrib *contrib =
        new ForceFields::UFF::DistanceConstraintContrib(field, i, j, l, u,
                                                        fdist);
    field->contribs().push_back(ForceFields::ContribPtr(contrib));
  }

  // 1,3 distance constraints
  for (unsigned int a = 1; a < angles.size(); ++a) {
    unsigned int i = angles[a][0];
    unsigned int j = angles[a][2];
    if (i < j)
      atomPairs[i * N + j] = 1;
    else
      atomPairs[j * N + i] = 1;
    double d = ((*positions[i]) - (*positions[j])).length();
    double l = d - 0.01;
    double u = d + 0.01;
    ForceFields::UFF::DistanceConstraintContrib *contrib =
        new ForceFields::UFF::DistanceConstraintContrib(field, i, j, l, u,
                                                        fdist);
    field->contribs().push_back(ForceFields::ContribPtr(contrib));
  }

  // minimum distance for all other atom pairs
  fdist = 10.0;
  for (unsigned int i = 1; i < N; ++i) {
    for (unsigned int j = 0; j < i; ++j) {
      if (!atomPairs[j * N + i]) {
        double l = mmat.getLowerBound(i, j);
        double u = mmat.getUpperBound(i, j);
        ForceFields::UFF::DistanceConstraintContrib *contrib =
            new ForceFields::UFF::DistanceConstraintContrib(field, i, j, l, u,
                                                            fdist);
        field->contribs().push_back(ForceFields::ContribPtr(contrib));
      }
    }
  }

  return field;
}  // constructPlain3DForceField
예제 #22
0
void testTorsionAngleM6() {
  std::cerr << "-------------------------------------" << std::endl;
  std::cerr << " Test CrystalFF torsional term." << std::endl;

  ForceFields::ForceField ff;
  Point3D p1, p2, p3, p4;
  RDGeom::PointPtrVect &ps = ff.positions();
  ps.push_back(&p1);
  ps.push_back(&p2);
  ps.push_back(&p3);
  ps.push_back(&p4);

  ForceFields::CrystalFF::TorsionAngleContribM6 *contrib;
  // ------- ------- ------- ------- ------- ------- -------
  // Basic SP3 - SP3
  // ------- ------- ------- ------- ------- ------- -------

  // [!#1:1][CX4H2:2]!@[CX4H2:3][!#1:4] 1 0.0 1 0.0 1 4.0 1 0.0 1 0.0 1 0.0
  std::vector<int> signs(6, 1);
  std::vector<double> v(6, 0.0);
  v[2] = 4.0;

  contrib = new ForceFields::CrystalFF::TorsionAngleContribM6(&ff, 0, 1, 2, 3,
                                                              v, signs);
  ff.contribs().push_back(ForceFields::ContribPtr(contrib));

  p1.x = 0;
  p1.y = 1.5;
  p1.z = 0;

  p2.x = 0.0;
  p2.y = 0.0;
  p2.z = 0.0;

  p3.x = 1.5;
  p3.y = 0.0;
  p3.z = 0.0;

  p4.x = 1.5;
  p4.y = 0.0;
  p4.z = 1.5;

  ff.initialize();
  ff.minimize(10, 1e-8, 1e-8);
  double cosPhi = ForceFields::MMFF::Utils::calcTorsionCosPhi(
      *(RDGeom::Point3D *)ff.positions()[0],
      *(RDGeom::Point3D *)ff.positions()[1],
      *(RDGeom::Point3D *)ff.positions()[2],
      *(RDGeom::Point3D *)ff.positions()[3]);
  TEST_ASSERT(RDKit::feq(cosPhi, 0.5, 1e-4));

  // ------- ------- ------- ------- ------- ------- -------
  // Basic SP2 - SP2
  // ------- ------- ------- ------- ------- ------- -------

  signs[1] = -1;
  v[2] = 0.0;
  v[1] = 7.0;

  ff.contribs().pop_back();
  contrib = new ForceFields::CrystalFF::TorsionAngleContribM6(&ff, 0, 1, 2, 3,
                                                              v, signs);
  ff.contribs().push_back(ForceFields::ContribPtr(contrib));

  p1.x = 0;
  p1.y = 1.5;
  p1.z = 0.1;

  p2.x = 0.0;
  p2.y = 0.0;
  p2.z = 0.0;

  p3.x = 1.5;
  p3.y = 0.0;
  p3.z = 0.0;

  p4.x = 1.5;
  p4.y = 0.2;
  p4.z = 1.5;

  ff.initialize();
  ff.minimize(10, 1e-8, 1e-8);
  cosPhi = ForceFields::MMFF::Utils::calcTorsionCosPhi(
      *(RDGeom::Point3D *)ff.positions()[0],
      *(RDGeom::Point3D *)ff.positions()[1],
      *(RDGeom::Point3D *)ff.positions()[2],
      *(RDGeom::Point3D *)ff.positions()[3]);
  TEST_ASSERT(RDKit::feq(cosPhi, 1.0, 1e-4));
}