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
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; }
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; }
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
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; }
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)); }
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
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
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; }