Example #1
0
double AlignMolecule(ROMol &prbMol, const ROMol &refMol, int prbCid = -1,
                     int refCid = -1, python::object atomMap = python::list(),
                     python::object weights = python::list(),
                     bool reflect = false, unsigned int maxIters = 50) {
    MatchVectType *aMap = _translateAtomMap(atomMap);
    unsigned int nAtms;
    if (aMap) {
        nAtms = aMap->size();
    } else {
        nAtms = prbMol.getNumAtoms();
    }
    RDNumeric::DoubleVector *wtsVec = _translateWeights(weights);
    if (wtsVec) {
        if (wtsVec->size() != nAtms) {
            throw_value_error("Incorrect number of weights specified");
        }
    }

    double rmsd;
    {
        NOGIL gil;
        rmsd = MolAlign::alignMol(prbMol, refMol, prbCid, refCid, aMap, wtsVec,
                                  reflect, maxIters);
    }
    if (aMap) {
        delete aMap;
    }
    if (wtsVec) {
        delete wtsVec;
    }
    return rmsd;
}
Example #2
0
void testMMFFO3AConstraintsAndLocalOnly() {
  std::string rdbase = getenv("RDBASE");
  std::string sdf = rdbase + "/Code/GraphMol/MolAlign/test_data/ref_e2.sdf";
  SDMolSupplier supplier(sdf, true, false);
  const int refNum = 23;
  const int prbNum = 32;
  ROMol *refMol = supplier[refNum];
  ROMol *prbMol = supplier[prbNum];
  unsigned int refNAtoms = refMol->getNumAtoms();
  std::vector<double> refLogpContribs(refNAtoms);
  std::vector<double> refMRContribs(refNAtoms);
  std::vector<unsigned int> refAtomTypes(refNAtoms);
  std::vector<std::string> refAtomTypeLabels(refNAtoms);
  Descriptors::getCrippenAtomContribs(*refMol, refLogpContribs,
    refMRContribs, true, &refAtomTypes, &refAtomTypeLabels);
  unsigned int prbNAtoms = prbMol->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(*prbMol, prbLogpContribs,
    prbMRContribs, true, &prbAtomTypes, &prbAtomTypeLabels);
  RWMol *patt = SmartsToMol("S");
  MatchVectType matchVect;
  TEST_ASSERT(SubstructMatch(*refMol, (ROMol &)*patt, matchVect));
  delete patt;
  unsigned int refSIdx = matchVect[0].second;
  matchVect.clear();
  patt = SmartsToMol("O");
  TEST_ASSERT(SubstructMatch(*prbMol, (ROMol &)*patt, matchVect));
  delete patt;
  unsigned int prbOIdx = matchVect[0].second;
  std::vector<double> distOS(2);
  distOS[0] = 2.7;
  distOS[1] = 0.4;
  std::vector<double> weights(2);
  weights[0] = 0.1;
  weights[1] = 100.0;
  for (unsigned int i = 0; i < 2; ++i) {
    MatchVectType constraintMap;
    constraintMap.push_back(std::make_pair(prbOIdx, refSIdx));
    RDNumeric::DoubleVector constraintWeights(1);
    constraintWeights[0] = weights[i];
    MolAlign::O3A *o3a = new MolAlign::O3A(*prbMol, *refMol,
      &prbLogpContribs, &refLogpContribs, MolAlign::O3A::CRIPPEN,
      -1, -1, false, 50, 0, &constraintMap, &constraintWeights);
    TEST_ASSERT(o3a);
    o3a->align();
    delete o3a;
    o3a = new MolAlign::O3A(*prbMol, *refMol, &prbLogpContribs,
      &refLogpContribs, MolAlign::O3A::CRIPPEN, -1, -1,
      false, 50, MolAlign::O3_LOCAL_ONLY);
    TEST_ASSERT(o3a);
    o3a->align();
    delete o3a;
    double d = (prbMol->getConformer().getAtomPos(prbOIdx)
      - refMol->getConformer().getAtomPos(refSIdx)).length();
    TEST_ASSERT(feq(d, distOS[i], 0.1));
  }
}
Example #3
0
void testDativeMatch() {
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Test dative-bond matching" << std::endl;
  {
    std::string smi = "[Cu]->[Fe]";
    ROMol *mol = SmilesToMol(smi);
    TEST_ASSERT(mol);

    // make sure a self-match works
    MatchVectType match;
    TEST_ASSERT(SubstructMatch(*mol, *mol, match));
    TEST_ASSERT(match.size() == mol->getNumAtoms());

    {  // reverse the order and make sure that works
      std::string sma = "[Fe]<-[Cu]";
      ROMol *qmol = SmilesToMol(sma);
      TEST_ASSERT(qmol);
      MatchVectType match;
      TEST_ASSERT(SubstructMatch(*mol, *qmol, match));
      TEST_ASSERT(match.size() == qmol->getNumAtoms());
      delete qmol;
    }
    {  // reverse the direction and make sure that does not work.
      std::string sma = "[Fe]->[Cu]";
      ROMol *qmol = SmilesToMol(sma);
      TEST_ASSERT(qmol);
      MatchVectType match;
      TEST_ASSERT(!SubstructMatch(*mol, *qmol, match));
      delete qmol;
    }

    delete mol;
  }
  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
Example #4
0
PyObject *getMolAlignTransform(const ROMol &prbMol, const ROMol &refMol,
                               int prbCid = -1, int refCid = -1,
                               python::object atomMap = python::list(),
                               python::object weights = python::list(),
                               bool reflect = false,
                               unsigned int maxIters = 50) {
    MatchVectType *aMap = _translateAtomMap(atomMap);
    unsigned int nAtms;
    if (aMap) {
        nAtms = aMap->size();
    } else {
        nAtms = prbMol.getNumAtoms();
    }
    RDNumeric::DoubleVector *wtsVec = _translateWeights(weights);
    if (wtsVec) {
        if (wtsVec->size() != nAtms) {
            throw_value_error("Incorrect number of weights specified");
        }
    }
    RDGeom::Transform3D trans;
    double rmsd;
    {
        NOGIL gil;
        rmsd = MolAlign::getAlignmentTransform(
                   prbMol, refMol, trans, prbCid, refCid, aMap, wtsVec, reflect, maxIters);
    }
    if (aMap) {
        delete aMap;
    }
    if (wtsVec) {
        delete wtsVec;
    }

    return generateRmsdTransPyTuple(rmsd, trans);
}
Example #5
0
void test4() {
  std::cout << " ----------------- Test 4" << std::endl;
  MatchVectType matchV;
  std::vector<MatchVectType> matches;
  int n;
  bool updateLabel = true;
  bool takeOwnership = true;

  RWMol *m, *q1, *q2;
  auto *a6 = new Atom(6);
  auto *a8 = new Atom(8);
  m = new RWMol();
  m->addAtom(a6);
  m->addAtom(a6);
  m->addAtom(a8);
  m->addAtom(a6);
  m->addAtom(a6);
  m->addBond(1, 0, Bond::SINGLE);
  m->addBond(1, 2, Bond::SINGLE);
  m->addBond(1, 3, Bond::SINGLE);
  m->addBond(2, 4, Bond::SINGLE);

  // this will be the recursive query
  q1 = new RWMol();
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addAtom(new QueryAtom(8), updateLabel, takeOwnership);
  q1->addBond(0, 1, Bond::UNSPECIFIED);

  // here's the main query
  q2 = new RWMol();
  auto *qA = new QueryAtom(6);
  auto *rsq = new RecursiveStructureQuery(q1);
  qA->expandQuery(rsq, Queries::COMPOSITE_AND);
  // std::cout << "post expand: " << qA->getQuery() << std::endl;
  q2->addAtom(qA, true, true);
  // std::cout << "mol: " << q2->getAtomWithIdx(0)->getQuery() << std::endl;
  q2->addAtom(new QueryAtom(6), true, true);
  q2->addBond(0, 1, Bond::UNSPECIFIED);

  bool found = SubstructMatch(*m, *q2, matchV);
  CHECK_INVARIANT(found, "");
  CHECK_INVARIANT(matchV.size() == 2, "");
  TEST_ASSERT(matchV[0].first == 0);
  TEST_ASSERT(matchV[0].second == 1);
  TEST_ASSERT(matchV[1].first == 1);
  TEST_ASSERT(matchV[1].second == 0 || matchV[1].second == 3);
  n = SubstructMatch(*m, *q2, matches, true);
  TEST_ASSERT(n == 2);
  TEST_ASSERT(matches.size() == (size_t)n);
  TEST_ASSERT(matches[0].size() == 2);
  TEST_ASSERT(matches[1].size() == 2);
  TEST_ASSERT(matches[0][0].second == matches[1][0].second);
  TEST_ASSERT(matches[0][1].second != matches[1][1].second);
  delete m;
  delete a6;
  delete a8;
  delete q2;

  std::cout << "Done\n" << std::endl;
}
Example #6
0
void testSubstructMatchDMAP() {
  BOOST_LOG(rdInfoLog) << "-----------------------\n"
                       << "testSubstructMatchDMAP" << std::endl;
  RWMol *mol = SmilesToMol("C(C)Nc1cc[nH+]cc1");
  RWMol *query = SmartsToMol("[#7+]");
  ResonanceMolSupplier *resMolSuppl;
  unsigned int n;
  MatchVectType p;

  resMolSuppl = new ResonanceMolSupplier((ROMol &)*mol);
  std::vector<MatchVectType> matchVect;
  n = SubstructMatch(*mol, *query, matchVect, false, true, false, false);
  TEST_ASSERT((n == 1) && (matchVect.size() == 1));
  p = matchVect[0];
  TEST_ASSERT((p.size() == 1) && (p[0].second == 6));
  matchVect.clear();
  n = SubstructMatch(*resMolSuppl, *query, matchVect, false, true, false,
                     false);
  TEST_ASSERT((n == 2) && (matchVect.size() == 2));
  std::vector<unsigned int> v;
  p = matchVect[0];
  TEST_ASSERT(p.size() == 1);
  v.push_back(p[0].second);
  p = matchVect[1];
  TEST_ASSERT(p.size() == 1);
  v.push_back(p[0].second);
  std::sort(v.begin(), v.end());
  TEST_ASSERT(v[0] == 2);
  TEST_ASSERT(v[1] == 6);
  delete mol;
  delete query;
  delete resMolSuppl;
}
Example #7
0
 double getAlignmentTransform(const ROMol &prbMol, const ROMol &refMol,
                                      RDGeom::Transform3D &trans,
                                      int prbCid, int refCid, 
                                      const MatchVectType *atomMap, 
                                      const RDNumeric::DoubleVector *weights, bool reflect,
                                      unsigned int maxIterations) {
   RDGeom::Point3DConstPtrVect refPoints, prbPoints;
   const Conformer &prbCnf = prbMol.getConformer(prbCid);
   const Conformer &refCnf = refMol.getConformer(refCid);
   if (atomMap == 0) {
     // we have to figure out the mapping between the two molecule
     MatchVectType match;
     if (SubstructMatch(refMol, prbMol, match)) {
       MatchVectType::const_iterator mi;
       for (mi = match.begin(); mi != match.end(); mi++) {
         prbPoints.push_back(&prbCnf.getAtomPos(mi->first));
         refPoints.push_back(&refCnf.getAtomPos(mi->second));
       }
     } else {
       throw MolAlignException("No sub-structure match found between the probe and query mol");
     } 
   } else {
     MatchVectType::const_iterator mi;
     for (mi = atomMap->begin(); mi != atomMap->end(); mi++) {
       prbPoints.push_back(&prbCnf.getAtomPos(mi->first));
       refPoints.push_back(&refCnf.getAtomPos(mi->second));
     }
   }
   double ssr = RDNumeric::Alignments::AlignPoints(refPoints, prbPoints, 
                                                   trans, weights, reflect, maxIterations);
   ssr /= (prbPoints.size());
   return sqrt(ssr);
 }
  ROMol *prepareMol(const ROMol &mol, const FragCatParams *fparams,
		    MatchVectType &aToFmap) {
    PRECONDITION(fparams,"");
    
    // get a mapping of the functional groups onto the molecule
    INT_VECT fgBonds;
    MatchVectType aidToFid = findFuncGroupsOnMol(mol, fparams, fgBonds);
    
    // get the core piece of molecule (i.e. the part of the molecule 
    // without the functional groups). This basically the part of the molecule
    // that does not contain the function group bonds given by "fgBonds"
    INT_VECT cBonds;
    int bid, nbds = mol.getNumBonds();

    for (bid = 0; bid < nbds; bid++) {
      if (std::find(fgBonds.begin(), fgBonds.end(), bid) == fgBonds.end()) {
	cBonds.push_back(bid);
      }
    }

    INT_MAP_INT aIdxMap; // a map from atom id in mol to the new atoms id in coreMol
    
    ROMol *coreMol = Subgraphs::pathToSubmol(mol, cBonds, false, aIdxMap);
    
    // now map the functional groups on mol to coreMol using aIdxMap
    MatchVectType::iterator mati;
    
    int newID;
    for (mati = aidToFid.begin(); mati != aidToFid.end(); mati++) {
      newID = aIdxMap[mati->first];
      aToFmap.push_back(std::pair<int, int>(newID, mati->second));
    }
    
    return coreMol;
  }
Example #9
0
  //*************************************************************************************
  //
  //  Adds 2D coordinates to a molecule using the Depict.dll
  //
  //  ARGUMENTS:
  //    mol:          the molecule to be altered
  //    tempFilename: (OPTIONAL) the name of the temporary file 
  //
  //  RETURNS:
  //   1 on success, 0 otherwise
  //
  //  Here's the process by which this works (it's kind of contorted):
  //   1) convert the mol to SMILES
  //   2) use the DLL to convert the SMILES to a mol file (on disk)
  //   3) parse the mol file into a temporary molecule
  //   4) do a substructure match from the old molecule to the
  //      temp one (which may have a different atom numbering or additional
  //      atoms added).
  //   5) Update the positions of the atoms on the old molecule.
  //   6) Free the temp molecule.
  //
  //  NOTES:
  //   - *FIX:* at the moment we're not doing anything to clear up the
  //     temp file created in this process.  It'll always have the same
  //     name unless the user explicitly asks that we do something different.
  //   - To use the DLL, it's essential that the COMBICHEM_ROOT and COMBICHEM_RELEASE
  //     environment variables be set.  If this isn't done, this whole process
  //     will fail.
  //   - See the notes above about failures when opening the DLL.
  //
  //*************************************************************************************
  int Add2DCoordsToMolDLL(ROMol &mol,std::string tempFilename){
    std::string smi=MolToSmiles(mol,true);
    int tmp = SmilesToMolFileDLL(smi,tempFilename);
    int res = -1;
    if(tmp){
      // build another mol from that mol file:
      RWMol *tmpMol = MolFileToMol(tempFilename,false);
      // match it up with the starting mol:
      //  (We need to do this because the depict.dll conversion
      //   to a mol file may have added Hs)
      MatchVectType matchVect;
      bool hasMatch=SubstructMatch(tmpMol,&mol,matchVect);
      if(hasMatch){
        const Conformer &conf = tmpMol->getCoformer(0);
        Coformer *nconf = new Coformer(mol.getNumAtoms());
	for(MatchVectType::const_iterator mvi=matchVect.begin();
	    mvi!=matchVect.end();mvi++){
	  
          nconf->setAtomPos(conf.getAtomPos(mvi->first));
	}
        confId = (int)mol.addConformer(nconf, true);
      }
      delete tmpMol;
    }
    return res;
  }
Example #10
0
bool StructCheckTautomer::applyTautomer(unsigned it) {
  if (Options.FromTautomer.size() <= it || Options.ToTautomer.size() <= it) {
    if (Options.Verbose)
      BOOST_LOG(rdInfoLog) << "ERROR: incorrect Tautomer index it=" << it
                           << "\n";
    return false;
  }
  const ROMol &fromTautomer = *Options.FromTautomer[it];
  const ROMol &toTautomer = *Options.ToTautomer[it];
  if (toTautomer.getNumAtoms() != fromTautomer.getNumAtoms()) {
    if (Options.Verbose)
      BOOST_LOG(rdInfoLog) << "ERROR: incorrect data toTautomer.getNumAtoms() "
                              "!= fromTautomer.getNumAtoms()\n";
    // incorrect data
    // throw(.....);
    return false;
  }
  const unsigned nta = toTautomer.getNumAtoms();
  const unsigned ntb = toTautomer.getNumBonds();
  MatchVectType match;  // The format is (queryAtomIdx, molAtomIdx)
  std::vector<unsigned> atomIdxMap(
      Mol.getNumAtoms());  // matched tau atom indeces

  if (!SubstructMatch(Mol, *Options.FromTautomer[it],
                      match))  // SSMatch(mp, from_tautomer, SINGLE_MATCH);
    return false;
  if (Options.Verbose)
    BOOST_LOG(rdInfoLog) << "found match for from_tautomer with " << nta
                         << " atoms\n";
  // init
  for (unsigned i = 0; i < Mol.getNumAtoms(); i++) atomIdxMap[i] = -1;
  for (MatchVectType::const_iterator mit = match.begin(); mit != match.end();
       mit++) {
    unsigned tai = mit->first;   // From and To Tautomer Atom index
    unsigned mai = mit->second;  // Mol Atom index
    atomIdxMap[mai] = tai;
  }
  // scan for completely mapped bonds and replace bond order with mapped bond
  // from to_tautomer
  for (RDKit::BondIterator_ bond = Mol.beginBonds(); bond != Mol.endBonds();
       bond++) {
    unsigned ti = atomIdxMap[(*bond)->getBeginAtomIdx()];
    unsigned tj = atomIdxMap[(*bond)->getEndAtomIdx()];
    if (-1 == ti || -1 == tj) continue;
    const Bond *tb = toTautomer.getBondBetweenAtoms(ti, tj);
    if (tb && (*bond)->getBondType() != tb->getBondType()) {
      (*bond)->setBondType(tb->getBondType());
    }
  }
  // apply charge/radical fixes if any
  for (unsigned i = 0; i < match.size(); i++) {
    Atom &atom = *Mol.getAtomWithIdx(match[i].second);
    const Atom &ta = *toTautomer.getAtomWithIdx(match[i].first);
    atom.setFormalCharge(ta.getFormalCharge());
    atom.setNumRadicalElectrons(ta.getNumRadicalElectrons());
  }

  return true;
}
Example #11
0
void test2(){
  std::cout << " ----------------- Test 2" << std::endl;
  MatchVectType matchV;
  std::vector< MatchVectType > matches;
  unsigned int n;

  RWMol *m,*q1;
  m = new RWMol();
  m->addAtom(new Atom(6));
  m->addAtom(new Atom(6));
  m->addAtom(new Atom(8));
  m->addBond(0,1,Bond::SINGLE);
  m->addBond(1,2,Bond::SINGLE);

  q1 = new RWMol();
  q1->addAtom(new QueryAtom(6));
  q1->addAtom(new QueryAtom(8));
  q1->addBond(0,1,Bond::SINGLE);

  n = SubstructMatch(*m,*q1,matchV);
  TEST_ASSERT(n);
  TEST_ASSERT(matchV.size()==2);
  TEST_ASSERT(matchV[0].first==0);
  TEST_ASSERT(matchV[0].second==1);
  TEST_ASSERT(matchV[1].first==1);
  TEST_ASSERT(matchV[1].second==2);

  n = SubstructMatch(*m,*q1,matches,false);
  CHECK_INVARIANT(n==1,"");
  CHECK_INVARIANT(matches.size()==n,"");
  CHECK_INVARIANT(matches[0].size()==2,"");
  n = SubstructMatch(*m,*q1,matches,true);
  CHECK_INVARIANT(n==1,"");
  CHECK_INVARIANT(matches.size()==n,"");
  CHECK_INVARIANT(matches[0].size()==2,"");

  CHECK_INVARIANT(SubstructMatch(*m,*q1,matchV),"");
  CHECK_INVARIANT(matchV.size()==2,"");

  delete m;
  m = new RWMol();
  m->addAtom(new Atom(6));
  m->addAtom(new Atom(6));
  m->addAtom(new Atom(8));
  m->addBond(0,1,Bond::SINGLE);
  m->addBond(1,2,Bond::DOUBLE);

  matches.clear();
  n = SubstructMatch(*m,*q1,matches,false);
  CHECK_INVARIANT(n==0,"");
  CHECK_INVARIANT(matches.size()==n,"");
  n = SubstructMatch(*m,*q1,matches,true);
  CHECK_INVARIANT(n==0,"");
  CHECK_INVARIANT(matches.size()==n,"");
  CHECK_INVARIANT(!SubstructMatch(*m,*q1,matchV),"");

  std::cout << "Done\n" << std::endl;

}
Example #12
0
void testRecursiveSerialNumbers(){
  std::cout << " ----------------- Testing serial numbers on recursive queries" << std::endl;
  MatchVectType matchV;
  std::vector< MatchVectType > matches;
  int n;

  RWMol *m,*q1,*q2;
  Atom *a6 = new Atom(6);
  Atom *a8 = new Atom(8);
  m = new RWMol();
  m->addAtom(a6);
  m->addAtom(a6);
  m->addAtom(a8);
  m->addAtom(a6);
  m->addAtom(a6);
  m->addBond(1,0,Bond::SINGLE);
  m->addBond(1,2,Bond::SINGLE);
  m->addBond(1,3,Bond::SINGLE);
  m->addBond(2,4,Bond::SINGLE);

  {
    // this will be the recursive query
    q1 = new RWMol();
    q1->addAtom(new QueryAtom(6),true);
    q1->addAtom(new QueryAtom(8),true);
    q1->addBond(0,1,Bond::UNSPECIFIED);

    // here's the main query
    q2 = new RWMol();
    QueryAtom *qA = new QueryAtom(6);
    RecursiveStructureQuery *rsq = new RecursiveStructureQuery(new RWMol(*q1),1);
    qA->expandQuery(rsq,Queries::COMPOSITE_AND);
    //std::cout << "post expand: " << qA->getQuery() << std::endl;
    q2->addAtom(qA,true,true);
    //std::cout << "mol: " << q2->getAtomWithIdx(0)->getQuery() << std::endl;
    q2->addAtom(new QueryAtom(8),true,true);
    q2->addBond(0,1,Bond::UNSPECIFIED);

    qA = new QueryAtom(6);
    rsq = new RecursiveStructureQuery(new RWMol(*q1),1);
    qA->expandQuery(rsq,Queries::COMPOSITE_AND);
    q2->addAtom(qA,true,true);
    q2->addBond(1,2,Bond::UNSPECIFIED);

    bool found = SubstructMatch(*m,*q2,matchV);
    CHECK_INVARIANT(found,"");
    CHECK_INVARIANT(matchV.size()==3,"");
    n = SubstructMatch(*m,*q2,matches,true);
    TEST_ASSERT(n==1);
    TEST_ASSERT(matches.size()==1);
    TEST_ASSERT(matches[0].size()==3);

    delete q1;
    delete q2;
  }
  delete m;
  std::cout << "Done\n" << std::endl;
}
Example #13
0
void test4() {
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "FeatureDef functionality testing." << std::endl;

  ROMol *testMol;
  MatchVectType mv;
  std::string inText;
  int res;
  MolChemicalFeatureDef::CollectionType featureDefs;
  MolChemicalFeatureDef::CollectionType::const_iterator featDefIt;
  MolChemicalFeatureDef::CollectionType::value_type featDef;

  inText =
      "DefineFeature HDonor1 [N,O;!H0]\n"
      "  Family HBondDonor\n"
      "  Weights 1.0\n"
      "EndFeature\n"
      "DefineFeature HAcceptor1 [N,O]\n"
      "  Family HAcceptor\n"
      "  Weights 1.0\n"
      "EndFeature\n";
  res = parseFeatureData(inText, featureDefs);
  TEST_ASSERT(!res);
  TEST_ASSERT(featureDefs.size() == 2);
  featDefIt = featureDefs.begin();
  featDef = *featDefIt;
  TEST_ASSERT(featDef->getSmarts() == "[N,O;!H0]");
  TEST_ASSERT(featDef->getPattern());
  TEST_ASSERT(featDef->getPattern()->getNumAtoms() == 1);
  TEST_ASSERT(featDef->getNumWeights() == 1);

  featDef = *(++featureDefs.begin());
  TEST_ASSERT(featDef->getSmarts() == "[N,O]");
  TEST_ASSERT(featDef->getPattern());
  TEST_ASSERT(featDef->getPattern()->getNumAtoms() == 1);
  TEST_ASSERT(featDef->getNumWeights() == 1);

  testMol = SmilesToMol("COCN");
  TEST_ASSERT(testMol);
  featDef = *featureDefs.begin();
  TEST_ASSERT(SubstructMatch(*testMol, *featDef->getPattern(), mv));
  TEST_ASSERT(mv.size() == 1);
  TEST_ASSERT(mv[0].first == 0);
  TEST_ASSERT(mv[0].second == 3);
  featDef = *(++featureDefs.begin());
  TEST_ASSERT(SubstructMatch(*testMol, *featDef->getPattern(), mv));
  TEST_ASSERT(mv.size() == 1);
  TEST_ASSERT(mv[0].first == 0);
  TEST_ASSERT(mv[0].second == 1 || mv[0].second == 3);
  delete testMol;

  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
Example #14
0
void test5QueryRoot() {
  std::cout << " ----------------- Test 5 QueryRoot" << std::endl;
  MatchVectType matchV;
  std::vector<MatchVectType> matches;
  int n;
  bool updateLabel = true;
  bool takeOwnership = true;

  RWMol *m, *q1, *q2;
  auto *a6 = new Atom(6);
  auto *a8 = new Atom(8);
  // CC(OC)C
  m = new RWMol();
  m->addAtom(a6);
  m->addAtom(a6);
  m->addAtom(a8);
  m->addAtom(a6);
  m->addAtom(a6);
  m->addBond(0, 1, Bond::SINGLE);
  m->addBond(1, 2, Bond::SINGLE);
  m->addBond(1, 4, Bond::SINGLE);
  m->addBond(2, 3, Bond::SINGLE);

  // this will be the recursive query
  q1 = new RWMol();
  q1->addAtom(new QueryAtom(8), updateLabel, takeOwnership);
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addBond(0, 1, Bond::UNSPECIFIED);
  q1->setProp(common_properties::_queryRootAtom, 1);

  // here's the main query
  q2 = new RWMol();
  auto *qA = new QueryAtom();
  auto *rsq = new RecursiveStructureQuery(q1);
  qA->setQuery(rsq);
  q2->addAtom(qA, true, true);
  q2->addAtom(new QueryAtom(6), true, true);
  q2->addBond(0, 1, Bond::UNSPECIFIED);

  bool found = SubstructMatch(*m, *q2, matchV);
  CHECK_INVARIANT(found, "");
  CHECK_INVARIANT(matchV.size() == 2, "");
  n = SubstructMatch(*m, *q2, matches, true);
  CHECK_INVARIANT(n == 2, "");
  CHECK_INVARIANT(matches[0].size() == 2, "");
  delete m;
  delete a6;
  delete a8;
  delete q2;

  std::cout << "Done\n" << std::endl;
}
Example #15
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;
}
Example #16
0
void testCrippenO3AConstraintsAndLocalOnly() {
  std::string rdbase = getenv("RDBASE");
  std::string sdf = rdbase + "/Code/GraphMol/MolAlign/test_data/ref_e2.sdf";
  SDMolSupplier supplier(sdf, true, false);
  const int refNum = 23;
  const int prbNum = 32;
  ROMol *refMol = supplier[refNum];
  ROMol *prbMol = supplier[prbNum];
  MMFF::MMFFMolProperties refMP(*refMol);
  TEST_ASSERT(refMP.isValid());
  MMFF::MMFFMolProperties prbMP(*prbMol);
  TEST_ASSERT(prbMP.isValid());
  RWMol *patt = SmartsToMol("S");
  MatchVectType matchVect;
  TEST_ASSERT(SubstructMatch(*refMol, (ROMol &)*patt, matchVect));
  delete patt;
  unsigned int refSIdx = matchVect[0].second;
  matchVect.clear();
  patt = SmartsToMol("O");
  TEST_ASSERT(SubstructMatch(*prbMol, (ROMol &)*patt, matchVect));
  delete patt;
  unsigned int prbOIdx = matchVect[0].second;
  std::vector<double> distOS(2);
  distOS[0] = 3.2;
  distOS[1] = 0.3;
  std::vector<double> weights(2);
  weights[0] = 10.0;
  weights[1] = 100.0;
  for (unsigned int i = 0; i < 2; ++i) {
    MatchVectType constraintMap;
    constraintMap.push_back(std::make_pair(prbOIdx, refSIdx));
    RDNumeric::DoubleVector constraintWeights(1);
    constraintWeights[0] = weights[i];
    MolAlign::O3A *o3a = new MolAlign::O3A(*prbMol, *refMol, &prbMP, &refMP,
      MolAlign::O3A::MMFF94, -1, -1, false, 50, 0, &constraintMap, &constraintWeights);
    TEST_ASSERT(o3a);
    o3a->align();
    delete o3a;
    o3a = new MolAlign::O3A(*prbMol, *refMol, &prbMP, &refMP,
      MolAlign::O3A::MMFF94, -1, -1, false, 50, MolAlign::O3_LOCAL_ONLY);
    TEST_ASSERT(o3a);
    o3a->align();
    delete o3a;
    double d = (prbMol->getConformer().getAtomPos(prbOIdx)
      - refMol->getConformer().getAtomPos(refSIdx)).length();
    TEST_ASSERT(feq(d, distOS[i], 0.1));
  }
}
Example #17
0
void test6() {
  std::cout << " ----------------- Test 6 (Issue71 related)" << std::endl;
  MatchVectType matchV;
  std::vector<MatchVectType> matches;
  int n;
  bool updateLabel = true;
  bool takeOwnership = true;

  RWMol *m, *q1;
  auto *a6 = new Atom(6);

  m = new RWMol();
  m->addAtom(a6);
  m->addAtom(a6);
  m->addAtom(a6);
  m->addBond(0, 1, Bond::SINGLE);
  m->addBond(1, 2, Bond::SINGLE);
  m->addBond(0, 2, Bond::SINGLE);

  q1 = new RWMol();
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addBond(0, 1, Bond::UNSPECIFIED);
  q1->addBond(1, 2, Bond::UNSPECIFIED);

  bool found = SubstructMatch(*m, *q1, matchV);
  CHECK_INVARIANT(found, "");
  CHECK_INVARIANT(matchV.size() == 3, "");
  n = SubstructMatch(*m, *q1, matches, true);
  CHECK_INVARIANT(n == 1, "");
  CHECK_INVARIANT(matches[0].size() == 3, "");

  // close the loop and try again (we should still match)
  q1->addBond(0, 2, Bond::UNSPECIFIED);
  found = SubstructMatch(*m, *q1, matchV);
  CHECK_INVARIANT(found, "");
  CHECK_INVARIANT(matchV.size() == 3, "");
  n = SubstructMatch(*m, *q1, matches, true);
  CHECK_INVARIANT(n == 1, "");
  CHECK_INVARIANT(matches[0].size() == 3, "");
  delete m;
  delete a6;
  delete q1;

  std::cout << "Done\n" << std::endl;
}
Example #18
0
void test5QueryRoot(){
  std::cout << " ----------------- Test 5 QueryRoot" << std::endl;
  MatchVectType matchV;
  std::vector< MatchVectType > matches;
  int n;

  RWMol *m,*q1,*q2;
  Atom *a6 = new Atom(6);
  Atom *a8 = new Atom(8);
  // CC(OC)C
  m = new RWMol();
  m->addAtom(a6);
  m->addAtom(a6);
  m->addAtom(a8);
  m->addAtom(a6);
  m->addAtom(a6);
  m->addBond(0,1,Bond::SINGLE);
  m->addBond(1,2,Bond::SINGLE);
  m->addBond(1,4,Bond::SINGLE);
  m->addBond(2,3,Bond::SINGLE);

  // this will be the recursive query
  q1 = new RWMol();
  q1->addAtom(new QueryAtom(8),true);
  q1->addAtom(new QueryAtom(6),true);
  q1->addBond(0,1,Bond::UNSPECIFIED);
  q1->setProp("_queryRootAtom",1);
  
  // here's the main query
  q2 = new RWMol();
  QueryAtom *qA = new QueryAtom();
  RecursiveStructureQuery *rsq = new RecursiveStructureQuery(q1);
  qA->setQuery(rsq);
  q2->addAtom(qA,true,true);
  q2->addAtom(new QueryAtom(6),true,true);
  q2->addBond(0,1,Bond::UNSPECIFIED);

  bool found = SubstructMatch(*m,*q2,matchV);
  CHECK_INVARIANT(found,"");
  CHECK_INVARIANT(matchV.size()==2,"");
  n = SubstructMatch(*m,*q2,matches,true);
  CHECK_INVARIANT(n==2,"");
  CHECK_INVARIANT(matches[0].size()==2,"");


  std::cout << "Done\n" << std::endl;
}
Example #19
0
void test2AtomMap() {
  std::string rdbase = getenv("RDBASE");
  std::string fname1 = rdbase + "/Code/GraphMol/MolAlign/test_data/1oir.mol";
  ROMol *m1 = MolFileToMol(fname1);
  std::string fname2 = rdbase + "/Code/GraphMol/MolAlign/test_data/1oir_conf.mol";
  ROMol *m2 = MolFileToMol(fname2);
  MatchVectType atomMap;
  atomMap.push_back(std::pair<int, int>(18, 27));
  atomMap.push_back(std::pair<int, int>(13, 23));
  atomMap.push_back(std::pair<int, int>(21, 14));
  atomMap.push_back(std::pair<int, int>(24, 7));
  atomMap.push_back(std::pair<int, int>(9, 19));
  atomMap.push_back(std::pair<int, int>(16, 30));
  double rmsd = MolAlign::alignMol(*m2, *m1, 0, 0, &atomMap);
  TEST_ASSERT(RDKit::feq(rmsd, 0.8525));
  delete m1;
  delete m2;
  
}
Example #20
0
MatchVectType *_translateAtomMap(python::object atomMap) {
    PySequenceHolder<python::object> aMapSeq(atomMap);
    MatchVectType *aMap;
    aMap = 0;
    unsigned int i, nAtms = aMapSeq.size();
    if (nAtms > 0) {
        aMap = new MatchVectType;
        for (i = 0; i < nAtms; ++i) {
            PySequenceHolder<int> item(aMapSeq[i]);
            if (item.size() != 2) {
                delete aMap;
                aMap = 0;
                throw_value_error("Incorrect format for atomMap");
            }
            aMap->push_back(std::pair<int, int>(item[0], item[1]));
        }
    }
    return aMap;
}
Example #21
0
void test7() {
  std::cout << " ----------------- Test 7 (leak check)" << std::endl;
  MatchVectType matchV;
  int n;

  RWMol *m, *q1;
  auto *a6 = new Atom(6);
  bool updateLabel = true;
  bool takeOwnership = true;

  m = new RWMol();
  m->addAtom(a6);
  m->addAtom(a6);
  m->addAtom(a6);
  m->addBond(0, 1, Bond::SINGLE);
  m->addBond(1, 2, Bond::SINGLE);
  m->addBond(0, 2, Bond::SINGLE);

  q1 = new RWMol();
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addBond(0, 1, Bond::UNSPECIFIED);
  q1->addBond(1, 2, Bond::UNSPECIFIED);

  bool found = SubstructMatch(*m, *q1, matchV);
  CHECK_INVARIANT(found, "");
  CHECK_INVARIANT(matchV.size() == 3, "");
  std::vector<MatchVectType> matches;
  for (int i = 0; i < 300000; i++) {
    n = SubstructMatch(*m, *q1, matches, true, true);
    CHECK_INVARIANT(n == 1, "");
    CHECK_INVARIANT(matches[0].size() == 3, "");
    if (!(i % 500)) std::cout << i << std::endl;
  }
  delete m;
  delete a6;
  delete q1;

  std::cout << "Done\n" << std::endl;
}
Example #22
0
bool check(MatchVectType v, MatchVectType match) {
  dump("v", v);
  dump("match", match);
  for (size_t i = 0; i < v.size(); ++i) {
    if (v[i].first != match[i].first) {
      return false;
    }
    if (v[i].second != match[i].second) {
      return false;
    }
  }
  return true;
}
Example #23
0
void test3Weights() {
  std::string rdbase = getenv("RDBASE");
  std::string fname1 = rdbase + "/Code/GraphMol/MolAlign/test_data/1oir.mol";
  ROMol *m1 = MolFileToMol(fname1);
  std::string fname2 = rdbase + "/Code/GraphMol/MolAlign/test_data/1oir_conf.mol";
  ROMol *m2 = MolFileToMol(fname2);
  MatchVectType atomMap;
  atomMap.push_back(std::pair<int, int>(18, 27));
  atomMap.push_back(std::pair<int, int>(13, 23));
  atomMap.push_back(std::pair<int, int>(21, 14));
  atomMap.push_back(std::pair<int, int>(24, 7));
  atomMap.push_back(std::pair<int, int>(9, 19));
  atomMap.push_back(std::pair<int, int>(16, 30));
  
  RDNumeric::DoubleVector wts(6);
  wts.setVal(0, 1.0); wts.setVal(1, 1.0);
  wts.setVal(2, 1.0); wts.setVal(3, 1.0);
  wts.setVal(4, 1.0); wts.setVal(5, 2.0);
  double rmsd = MolAlign::alignMol(*m2, *m1, 0, 0, &atomMap, &wts);
  TEST_ASSERT(RDKit::feq(rmsd, 0.9513));
  delete m1;
  delete m2;
}
Example #24
0
void test8(){
  std::cout << " ----------------- Test 8 (molgraph cache)" << std::endl;
  MatchVectType matchV;
  int n;

  RWMol *m,*q1;
  Atom *a6 = new Atom(6);

  m = new RWMol();
  m->addAtom(a6);
  m->addAtom(a6);
  m->addAtom(a6);
  m->addBond(0,1,Bond::SINGLE);
  m->addBond(1,2,Bond::SINGLE);
  m->addBond(0,2,Bond::SINGLE);

  q1 = new RWMol();
  q1->addAtom(new QueryAtom(6),true);
  q1->addAtom(new QueryAtom(6),true);
  q1->addAtom(new QueryAtom(6),true);
  q1->addBond(0,1,Bond::UNSPECIFIED);
  q1->addBond(1,2,Bond::UNSPECIFIED);


  bool found = SubstructMatch(*m,*q1,matchV);
  CHECK_INVARIANT(found,"");
  CHECK_INVARIANT(matchV.size()==3,"");
  std::vector< MatchVectType > matches;
  for(int i=0;i<30000;i++){
    n = SubstructMatch(*m,*q1,matches,true,true);
    CHECK_INVARIANT(n==1,"");
    CHECK_INVARIANT(matches[0].size()==3,"");
    if(! (i%500) ) std::cout << i << std::endl;
  }
  std::cout << "Done\n" << std::endl;
}
  MatchVectType findFuncGroupsOnMol(const ROMol &mol, 
				    const FragCatParams *params,
				    INT_VECT &fgBonds) {
    PRECONDITION(params,"bad params");

    fgBonds.clear();
    
    std::pair<int, int> amat;
    MatchVectType aidFgrps;
    std::vector<MatchVectType> fgpMatches;
    std::vector<MatchVectType>::const_iterator mati;
    MatchVectType::const_iterator mi;
    int aid;
    //const ROMol *fgrp;

    INT_VECT_CI bi;
    aidFgrps.clear();
    
    int fid = 0;
    const MOL_SPTR_VECT &fgrps = params->getFuncGroups();
    MOL_SPTR_VECT::const_iterator fgci;
    
    for (fgci = fgrps.begin(); fgci != fgrps.end(); fgci++) {
      const ROMol *fgrp = fgci->get();
      std::string fname;
      (*fgci)->getProp(common_properties::_Name, fname);
      //std::cout << "Groups number: " << fname << "\n";
      //(*fgci)->debugMol(std::cout);
      //mol->debugMol(std::cout);
      // match this functional group onto the molecule
      SubstructMatch(mol, *fgrp, fgpMatches);

      // loop over all the matches we get for this fgroup
      for (mati = fgpMatches.begin(); mati != fgpMatches.end(); mati++) {
	//FIX: we will assume that the first atom in fgrp is always the connection
	// atom
	amat = mati->front();
	aid = amat.second; //FIX: is this correct - the second entry in the pair is the atom ID from mol

	// grab the list of atom Ids from mol that match the functional group 
	INT_VECT bondIds, maids;
	for (mi = mati->begin(); mi != mati->end(); mi++) {
	  maids.push_back(mi->second);
	}

	// create a list of bond IDs from these atom ID 
	// these are the bond in mol that are part of portion that matches the 
	// functional group
	bondIds = Subgraphs::bondListFromAtomList(mol, maids);
	
	// now check if all these bonds have been covered as part of larger 
	// functional group that was dealt with earlier
	// FIX: obviously we assume here that the function groups in params 
	// come in decreasing order of size.
	bool allDone = true;
	for (bi = bondIds.begin(); bi != bondIds.end(); bi++) {
	  if (std::find(fgBonds.begin(), fgBonds.end(), (*bi)) == fgBonds.end()) {
	    allDone = false;
	    fgBonds.push_back(*bi);
	  }
	}
	
	if (!allDone) {
	  // this functional group mapping onto mol is not part of a larger func
	  // group mapping so record it
	  aidFgrps.push_back(std::pair<int, int>(aid, fid));
	}
      }
      fid++;

    }

    
    return aidFgrps;
  }
Example #26
0
void testGitHubIssue688() {
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Test GitHub issue 688: partially specified "
                           "chiral substructure queries don't work properly"
                        << std::endl;
  {
    std::string smi = "C1CC[C@](Cl)(N)O1";
    ROMol *mol = SmilesToMol(smi);
    TEST_ASSERT(mol);
    // mol->debugMol(std::cerr);
    std::string sma = "C1CC[C@](N)O1";
    ROMol *qmol = SmartsToMol(sma);
    TEST_ASSERT(qmol);
    // qmol->updatePropertyCache();
    // qmol->debugMol(std::cerr);

    MatchVectType match;
    TEST_ASSERT(SubstructMatch(*mol, *qmol, match, true, false));
    TEST_ASSERT(match.size() == qmol->getNumAtoms());

    TEST_ASSERT(SubstructMatch(*mol, *qmol, match, true, true));
    TEST_ASSERT(match.size() == qmol->getNumAtoms());

    delete mol;
    delete qmol;
  }
  {
    std::string smi = "C1CC[C@](Cl)(N)O1";
    ROMol *mol = SmilesToMol(smi);
    TEST_ASSERT(mol);
    // mol->debugMol(std::cerr);
    std::string sma = "C1CC[C@@](N)O1";
    ROMol *qmol = SmartsToMol(sma);
    TEST_ASSERT(qmol);
    // qmol->updatePropertyCache();
    // qmol->debugMol(std::cerr);

    MatchVectType match;
    TEST_ASSERT(SubstructMatch(*mol, *qmol, match, true, false));
    TEST_ASSERT(match.size() == qmol->getNumAtoms());

    TEST_ASSERT(!SubstructMatch(*mol, *qmol, match, true, true));

    delete mol;
    delete qmol;
  }
  {
    std::string smi = "N[C@]1(Cl)CCCO1";
    ROMol *mol = SmilesToMol(smi);
    TEST_ASSERT(mol);
    // mol->debugMol(std::cerr);
    std::string sma = "N[C@]1CCCO1";
    ROMol *qmol = SmartsToMol(sma);
    TEST_ASSERT(qmol);
    // qmol->updatePropertyCache();
    // qmol->debugMol(std::cerr);
    // std::cerr << MolToSmiles(*qmol, true) << std::endl;

    MatchVectType match;
    TEST_ASSERT(SubstructMatch(*mol, *qmol, match, true, false));
    TEST_ASSERT(match.size() == qmol->getNumAtoms());

    TEST_ASSERT(SubstructMatch(*mol, *qmol, match, true, true));
    TEST_ASSERT(match.size() == qmol->getNumAtoms());

    delete mol;
    delete qmol;
  }
  {
    std::string smi = "N[C@]1(Cl)CCCO1";
    ROMol *mol = SmilesToMol(smi);
    TEST_ASSERT(mol);
    // mol->debugMol(std::cerr);
    std::string sma = "N[C@@]1CCCO1";
    ROMol *qmol = SmartsToMol(sma);
    TEST_ASSERT(qmol);
    // qmol->updatePropertyCache();
    // qmol->debugMol(std::cerr);
    // std::cerr << MolToSmiles(*qmol, true) << std::endl;

    MatchVectType match;
    TEST_ASSERT(SubstructMatch(*mol, *qmol, match, true, false));
    TEST_ASSERT(match.size() == qmol->getNumAtoms());

    TEST_ASSERT(!SubstructMatch(*mol, *qmol, match, true, true));

    delete mol;
    delete qmol;
  }
  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
Example #27
0
void test5() {
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "FeatureFactory testing." << std::endl;

  ROMol *testMol;
  MatchVectType mv;
  std::string inText;
  FeatSPtrList featSPtrs;
  boost::shared_ptr<MolChemicalFeature> featSPtr;

  MolChemicalFeatureFactory *factory;

  MolChemicalFeatureDef::CollectionType::value_type featDef;

  inText =
      "DefineFeature HDonor1 [N,O;!H0]\n"
      "  Family HBondDonor\n"
      "  Weights 1.0\n"
      "EndFeature\n"
      "DefineFeature HAcceptor1 [N,O]\n"
      "  Family HBondAcceptor\n"
      "  Weights 1.0\n"
      "EndFeature\n";

  factory = buildFeatureFactory(inText);
  TEST_ASSERT(factory);
  TEST_ASSERT(factory->getNumFeatureDefs() == 2);

  testMol = SmilesToMol("COCN");
  TEST_ASSERT(testMol);
  featDef = *factory->beginFeatureDefs();
  TEST_ASSERT(SubstructMatch(*testMol, *featDef->getPattern(), mv));
  BOOST_LOG(rdErrorLog) << "1" << std::endl;
  TEST_ASSERT(mv.size() == 1);
  TEST_ASSERT(mv[0].first == 0);
  TEST_ASSERT(mv[0].second == 3);
  featDef = *(++factory->beginFeatureDefs());
  TEST_ASSERT(SubstructMatch(*testMol, *featDef->getPattern(), mv));
  BOOST_LOG(rdErrorLog) << "2" << std::endl;
  TEST_ASSERT(mv.size() == 1);
  TEST_ASSERT(mv[0].first == 0);
  TEST_ASSERT(mv[0].second == 1 || mv[0].second == 3);

  // Test using the factory to find features:
  featSPtrs = factory->getFeaturesForMol(*testMol);
  BOOST_LOG(rdErrorLog) << "3" << std::endl;
  TEST_ASSERT(featSPtrs.size() == 3);
  featSPtr = *featSPtrs.begin();
  TEST_ASSERT(featSPtr->getFamily() == "HBondDonor");
  TEST_ASSERT(featSPtr->getType() == "HDonor1");
  featSPtr = *(++featSPtrs.begin());
  TEST_ASSERT(featSPtr->getFamily() == "HBondAcceptor");
  TEST_ASSERT(featSPtr->getType() == "HAcceptor1");
  featSPtr = *(++featSPtrs.begin());
  TEST_ASSERT(featSPtr->getFamily() == "HBondAcceptor");
  TEST_ASSERT(featSPtr->getType() == "HAcceptor1");

  // Test limiting stuff with includeOnly
  featSPtrs = factory->getFeaturesForMol(*testMol, "HBondAcceptor");
  BOOST_LOG(rdErrorLog) << "4" << std::endl;
  TEST_ASSERT(featSPtrs.size() == 2);
  featSPtr = *featSPtrs.begin();
  TEST_ASSERT(featSPtr->getFamily() == "HBondAcceptor");
  TEST_ASSERT(featSPtr->getType() == "HAcceptor1");
  featSPtr = *(++featSPtrs.begin());
  TEST_ASSERT(featSPtr->getFamily() == "HBondAcceptor");
  TEST_ASSERT(featSPtr->getType() == "HAcceptor1");

  featSPtrs = factory->getFeaturesForMol(*testMol, "HBondDonor");
  BOOST_LOG(rdErrorLog) << "5" << std::endl;
  TEST_ASSERT(featSPtrs.size() == 1);
  featSPtr = *featSPtrs.begin();
  TEST_ASSERT(featSPtr->getFamily() == "HBondDonor");
  TEST_ASSERT(featSPtr->getType() == "HDonor1");

  featSPtrs = factory->getFeaturesForMol(*testMol, "NotPresent");
  BOOST_LOG(rdErrorLog) << "6" << std::endl;
  TEST_ASSERT(featSPtrs.size() == 0);

  delete testMol;
  delete factory;

  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
Example #28
0
void test3() {
  std::cout << " ----------------- Test 3" << std::endl;
  MatchVectType matchV;
  std::vector<MatchVectType> matches;
  unsigned int n;

  RWMol *m, *q1;
  m = new RWMol();
  bool updateLabel = true;
  bool takeOwnership = true;
  m->addAtom(new Atom(6), updateLabel, takeOwnership);
  m->addAtom(new Atom(6), updateLabel, takeOwnership);
  m->addAtom(new Atom(8), updateLabel, takeOwnership);
  m->addBond(0, 1, Bond::SINGLE);
  m->addBond(1, 2, Bond::SINGLE);

  q1 = new RWMol();
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addAtom(new QueryAtom(8), updateLabel, takeOwnership);
  q1->addBond(0, 1, Bond::UNSPECIFIED);
  n = SubstructMatch(*m, *q1, matches, false);
  CHECK_INVARIANT(n == 1, "");
  CHECK_INVARIANT(matches.size() == n, "");
  CHECK_INVARIANT(matches[0].size() == 2, "");
  n = SubstructMatch(*m, *q1, matches, true);
  CHECK_INVARIANT(n == 1, "");
  CHECK_INVARIANT(matches.size() == n, "");
  CHECK_INVARIANT(matches[0].size() == 2, "");

  CHECK_INVARIANT(SubstructMatch(*m, *q1, matchV), "");
  CHECK_INVARIANT(matchV.size() == 2, "");

  delete m;
  m = new RWMol();
  m->addAtom(new Atom(6), updateLabel, takeOwnership);
  m->addAtom(new Atom(6), updateLabel, takeOwnership);
  m->addAtom(new Atom(8), updateLabel, takeOwnership);
  m->addBond(0, 1, Bond::SINGLE);
  m->addBond(1, 2, Bond::DOUBLE);

  matches.clear();
  n = SubstructMatch(*m, *q1, matches, false);
  CHECK_INVARIANT(n == 1, "");
  CHECK_INVARIANT(matches.size() == n, "");
  CHECK_INVARIANT(matches[0].size() == 2, "");
  n = SubstructMatch(*m, *q1, matches, true);
  CHECK_INVARIANT(n == 1, "");
  CHECK_INVARIANT(matches.size() == n, "");
  CHECK_INVARIANT(matches[0].size() == 2, "");

  CHECK_INVARIANT(SubstructMatch(*m, *q1, matchV), "");
  CHECK_INVARIANT(matchV.size() == 2, "");

  delete q1;
  q1 = new RWMol();
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addAtom(new QueryAtom(6), updateLabel, takeOwnership);
  q1->addBond(0, 1, Bond::UNSPECIFIED);
  n = SubstructMatch(*m, *q1, matches, false);
  TEST_ASSERT(n == 2);
  TEST_ASSERT(matches.size() == n);
  TEST_ASSERT(matches[0].size() == 2);
  TEST_ASSERT(matches[1].size() == 2);
  TEST_ASSERT(matches[0][0].second != matches[1][0].second);
  TEST_ASSERT(matches[0][1].second != matches[1][1].second);
  n = SubstructMatch(*m, *q1, matches, true);
  TEST_ASSERT(n == 1);
  TEST_ASSERT(matches.size() == n);

  delete m;
  delete q1;
  std::cout << "Done\n" << std::endl;
}
Example #29
0
void test1(){
  std::cout << " ----------------- Test 1" << std::endl;
  MatchVectType matchV;
  std::vector< MatchVectType > matches;
  unsigned int n;

  RWMol *m,*q1;
  m = new RWMol();
  m->addAtom(new Atom(8));
  m->addAtom(new Atom(6));
  m->addAtom(new Atom(6));
  m->addBond(0,1,Bond::SINGLE);
  m->addBond(1,2,Bond::SINGLE);

  q1 = new RWMol();
  q1->addAtom(new QueryAtom(6));
  q1->addAtom(new QueryAtom(6));
  q1->addBond(0,1,Bond::SINGLE);
  n = SubstructMatch(*m,*q1,matches,false);
  CHECK_INVARIANT(n==2,"");
  CHECK_INVARIANT(matches.size()==n,"");
  CHECK_INVARIANT(matches[0].size()==2,"");
  TEST_ASSERT(matches[0][0].first==0);
  TEST_ASSERT(matches[0][0].second==1||matches[0][0].second==2);
  TEST_ASSERT(matches[0][1].first==1);
  TEST_ASSERT(matches[0][1].second!=matches[0][0].second);

  TEST_ASSERT(matches[1][1].second==1||matches[0][1].second==2);
  TEST_ASSERT(matches[1][0].first==0);
  TEST_ASSERT(matches[1][0].second==1||matches[1][0].second==2);
  TEST_ASSERT(matches[1][0].second!=matches[0][0].second);
  TEST_ASSERT(matches[1][0].second==matches[0][1].second);
  TEST_ASSERT(matches[1][1].first==1);
  TEST_ASSERT(matches[1][1].second!=matches[1][0].second);
  TEST_ASSERT(matches[1][1].second==matches[0][0].second);

  n = SubstructMatch(*m,*q1,matches,true);
  CHECK_INVARIANT(n==1,"");
  CHECK_INVARIANT(matches.size()==n,"");
  CHECK_INVARIANT(matches[0].size()==2,"");
  TEST_ASSERT(matches[0][0].first==0);
  TEST_ASSERT(matches[0][0].second==1||matches[0][0].second==2);
  TEST_ASSERT(matches[0][1].first==1);
  TEST_ASSERT(matches[0][1].second!=matches[0][0].second);
  TEST_ASSERT(matches[0][1].second==1||matches[0][1].second==2);
  
  CHECK_INVARIANT(SubstructMatch(*m,*q1,matchV),"");
  CHECK_INVARIANT(matchV.size()==2,"");

  // make sure we reset the match vectors.
  // build a query we won't match:
  q1->addAtom(new QueryAtom(6));
  q1->addBond(1,2,Bond::SINGLE);
  q1->addAtom(new QueryAtom(6));
  q1->addBond(2,3,Bond::SINGLE);

  TEST_ASSERT(!SubstructMatch(*m,*q1,matchV));
  TEST_ASSERT(matchV.size()==0);

  n = SubstructMatch(*m,*q1,matches,false);
  TEST_ASSERT(n==0);
  TEST_ASSERT(matches.size()==0);
  
  std::cout << "Done\n" << std::endl;
}
Example #30
0
void addTorsions(const ROMol &mol, MMFFMolProperties *mmffMolProperties,
                 ForceFields::ForceField *field,
                 const std::string &torsionBondSmarts) {
  PRECONDITION(field, "bad ForceField");
  PRECONDITION(mmffMolProperties, "bad MMFFMolProperties");
  PRECONDITION(mmffMolProperties->isValid(),
               "missing atom types - invalid force-field");

  std::ostream &oStream = mmffMolProperties->getMMFFOStream();
  ROMol::ADJ_ITER nbr1Idx;
  ROMol::ADJ_ITER end1Nbrs;
  ROMol::ADJ_ITER nbr2Idx;
  ROMol::ADJ_ITER end2Nbrs;
  double totalTorsionEnergy = 0.0;
  RDGeom::PointPtrVect points;
  if (mmffMolProperties->getMMFFVerbosity()) {
    if (mmffMolProperties->getMMFFVerbosity() == MMFF_VERBOSITY_HIGH) {
      oStream << "\n"
                 "T O R S I O N A L\n\n"
                 "--------------ATOMS---------------      ---ATOM TYPES---     "
                 "FF     TORSION              -----FORCE Params-----\n"
                 "  I        J        K        L          I    J    K    L   "
                 "CLASS     ANGLE    ENERGY       V1        V2        V3\n"
                 "-------------------------------------------------------------"
                 "-----------------------------------------------------"
              << std::endl;
    }
    points = field->positions();
  }
  std::vector<MatchVectType> matchVect;
  const ROMol *defaultQuery = DefaultTorsionBondSmarts::query();
  const ROMol *query = (torsionBondSmarts == DefaultTorsionBondSmarts::string())
                       ? defaultQuery : SmartsToMol(torsionBondSmarts);
  TEST_ASSERT(query);
  unsigned int nHits = SubstructMatch(mol, *query, matchVect);
  if (query != defaultQuery) delete query;

  for (unsigned int i = 0; i < nHits; ++i) {
    MatchVectType match = matchVect[i];
    TEST_ASSERT(match.size() == 2);
    int idx2 = match[0].second;
    int idx3 = match[1].second;
    const Bond *bond = mol.getBondBetweenAtoms(idx2, idx3);
    TEST_ASSERT(bond);
    const Atom *jAtom = mol.getAtomWithIdx(idx2);
    const Atom *kAtom = mol.getAtomWithIdx(idx3);
    if (((jAtom->getHybridization() == Atom::SP2) ||
         (jAtom->getHybridization() == Atom::SP3)) &&
        ((kAtom->getHybridization() == Atom::SP2) ||
         (kAtom->getHybridization() == Atom::SP3))) {
      ROMol::OEDGE_ITER beg1, end1;
      boost::tie(beg1, end1) = mol.getAtomBonds(jAtom);
      while (beg1 != end1) {
        const Bond *tBond1 = mol[*beg1].get();
        if (tBond1 != bond) {
          int idx1 = tBond1->getOtherAtomIdx(idx2);
          ROMol::OEDGE_ITER beg2, end2;
          boost::tie(beg2, end2) = mol.getAtomBonds(kAtom);
          while (beg2 != end2) {
            const Bond *tBond2 = mol[*beg2].get();
            if ((tBond2 != bond) && (tBond2 != tBond1)) {
              int idx4 = tBond2->getOtherAtomIdx(idx3);
              // make sure this isn't a three-membered ring:
              if (idx4 != idx1) {
                // we now have a torsion involving atoms (bonds):
                //  bIdx - (tBond1) - idx1 - (bond) - idx2 - (tBond2) - eIdx
                unsigned int torType;
                MMFFTor mmffTorParams;
                if (mmffMolProperties->getMMFFTorsionParams(
                        mol, idx1, idx2, idx3, idx4, torType, mmffTorParams)) {
                  TorsionAngleContrib *contrib = new TorsionAngleContrib(
                      field, idx1, idx2, idx3, idx4, &mmffTorParams);
                  field->contribs().push_back(ForceFields::ContribPtr(contrib));
                  if (mmffMolProperties->getMMFFVerbosity()) {
                    const Atom *iAtom = mol.getAtomWithIdx(idx1);
                    const Atom *lAtom = mol.getAtomWithIdx(idx4);
                    unsigned int iAtomType =
                        mmffMolProperties->getMMFFAtomType(idx1);
                    unsigned int jAtomType =
                        mmffMolProperties->getMMFFAtomType(idx2);
                    unsigned int kAtomType =
                        mmffMolProperties->getMMFFAtomType(idx3);
                    unsigned int lAtomType =
                        mmffMolProperties->getMMFFAtomType(idx4);
                    const RDGeom::Point3D p1((*(points[idx1]))[0],
                                             (*(points[idx1]))[1],
                                             (*(points[idx1]))[2]);
                    const RDGeom::Point3D p2((*(points[idx2]))[0],
                                             (*(points[idx2]))[1],
                                             (*(points[idx2]))[2]);
                    const RDGeom::Point3D p3((*(points[idx3]))[0],
                                             (*(points[idx3]))[1],
                                             (*(points[idx3]))[2]);
                    const RDGeom::Point3D p4((*(points[idx4]))[0],
                                             (*(points[idx4]))[1],
                                             (*(points[idx4]))[2]);
                    const double cosPhi =
                        MMFF::Utils::calcTorsionCosPhi(p1, p2, p3, p4);
                    const double torsionEnergy = MMFF::Utils::calcTorsionEnergy(
                        mmffTorParams.V1, mmffTorParams.V2, mmffTorParams.V3,
                        cosPhi);
                    if (mmffMolProperties->getMMFFVerbosity() ==
                        MMFF_VERBOSITY_HIGH) {
                      oStream
                          << std::left << std::setw(2) << iAtom->getSymbol()
                          << " #" << std::setw(5) << idx1 + 1 << std::setw(2)
                          << jAtom->getSymbol() << " #" << std::setw(5)
                          << idx2 + 1 << std::setw(2) << kAtom->getSymbol()
                          << " #" << std::setw(5) << idx3 + 1 << std::setw(2)
                          << lAtom->getSymbol() << " #" << std::setw(5)
                          << idx4 + 1 << std::right << std::setw(5) << iAtomType
                          << std::setw(5) << jAtomType << std::setw(5)
                          << kAtomType << std::setw(5) << lAtomType
                          << std::setw(6) << torType << "  " << std::fixed
                          << std::setprecision(3) << std::setw(10)
                          << RAD2DEG * acos(cosPhi) << std::setw(10)
                          << torsionEnergy << std::setw(10) << mmffTorParams.V1
                          << std::setw(10) << mmffTorParams.V2 << std::setw(10)
                          << mmffTorParams.V3 << std::endl;
                    }
                    totalTorsionEnergy += torsionEnergy;
                  }
                }
              }
            }
            beg2++;
          }
        }
        beg1++;
      }
    }
  }
  if (mmffMolProperties->getMMFFVerbosity()) {
    if (mmffMolProperties->getMMFFVerbosity() == MMFF_VERBOSITY_HIGH) {
      oStream << std::endl;
    }
    oStream << "TOTAL TORSIONAL ENERGY         =" << std::right << std::setw(16)
            << std::fixed << std::setprecision(4) << totalTorsionEnergy
            << std::endl;
  }
}