示例#1
0
void testIssue3399798(std::string rdbase){

  BOOST_LOG(rdInfoLog) << "---------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "-- testing issue 3399798             --" << std::endl;
  BOOST_LOG(rdInfoLog) << "---------------------------------------" << std::endl;

  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3399798.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(0)->getChiralTag()==Atom::CHI_UNSPECIFIED);
    TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag()==Atom::CHI_UNSPECIFIED);

    delete m;
  }

  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3399798.2.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(0)->getChiralTag()==Atom::CHI_UNSPECIFIED);
    TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag()!=Atom::CHI_UNSPECIFIED);

    delete m;
  }

  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "-- DONE                           --" << std::endl;
  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
}
示例#2
0
void testGithub186(){
  BOOST_LOG(rdInfoLog) << "testing github issue 186: chiral S not written to ctab" << std::endl;
  std::string rdbase = getenv("RDBASE");
  rdbase += "/Code/GraphMol/FileParsers/test_data/";
  
  {
    std::string fName = rdbase + "github186.mol";
    RWMol *m = MolFileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==11);
    TEST_ASSERT(m->getNumBonds()==10);
    TEST_ASSERT(m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_UNSPECIFIED &&
                m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_OTHER
                );

    std::string mb=MolToMolBlock(*m);
    delete m;
    m = MolBlockToMol(mb);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==11);
    TEST_ASSERT(m->getNumBonds()==10);
    TEST_ASSERT(m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_UNSPECIFIED &&
                m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_OTHER
                );

    delete m;
  }
  
}
示例#3
0
void testGithub438(std::string rdbase) {
  BOOST_LOG(rdInfoLog) << "-----------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog)
      << "-- testing GitHub issue #438: problems with metals in mol2 files  --"
      << std::endl;
  BOOST_LOG(rdInfoLog) << "-----------------------------------" << std::endl;

  {
    std::string fName =
        rdbase + "/Code/GraphMol/FileParsers/test_data/github438_1.mol2";
    RWMol *mol = Mol2FileToMol(fName);
    TEST_ASSERT(mol);
    TEST_ASSERT(mol->getAtomWithIdx(0)->getFormalCharge() == 1);
    delete mol;
  }
  {
    std::string fName =
        rdbase + "/Code/GraphMol/FileParsers/test_data/github438_2.mol2";
    RWMol *mol = Mol2FileToMol(fName);
    TEST_ASSERT(mol);
    TEST_ASSERT(mol->getAtomWithIdx(0)->getFormalCharge() == 2);
    delete mol;
  }
  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "-- DONE                           --" << std::endl;
  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
}
示例#4
0
void testGithub187(){
  BOOST_LOG(rdInfoLog) << "testing github issue 187: A not written to mol block" << std::endl;
  std::string rdbase = getenv("RDBASE");
  rdbase += "/Code/GraphMol/FileParsers/test_data/";
  
  {
    std::string fName = rdbase + "github187.mol";
    RWMol *m = MolFileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==1);
    TEST_ASSERT(m->getNumBonds()==0);
    TEST_ASSERT(m->getAtomWithIdx(0)->hasQuery());
    std::string mb=MolToMolBlock(*m);
    TEST_ASSERT(mb.find(" A   0")!=std::string::npos);

    // try the v3000 version:
    mb=MolToMolBlock(*m,true,-1,true,true);
    TEST_ASSERT(mb.find("V30 1 A 0")!=std::string::npos);
    
    delete m;
  }
  
  {
    std::string fName = rdbase + "github187.v3k.mol";
    RWMol *m = MolFileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==1);
    TEST_ASSERT(m->getNumBonds()==0);
    TEST_ASSERT(m->getAtomWithIdx(0)->hasQuery());
    std::string mb=MolToMolBlock(*m);
    TEST_ASSERT(mb.find(" A   0")!=std::string::npos);

    // try the v3000 version:
    mb=MolToMolBlock(*m,true,-1,true,true);
    TEST_ASSERT(mb.find("V30 1 A 0")!=std::string::npos);
    
    delete m;
  }

  {
    std::string fName = rdbase + "github187.2.mol";
    RWMol *m = MolFileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==1);
    TEST_ASSERT(m->getNumBonds()==0);
    TEST_ASSERT(m->getAtomWithIdx(0)->hasQuery());
    std::string mb=MolToMolBlock(*m);
    TEST_ASSERT(mb.find(" Q   0")!=std::string::npos);

    // try the v3000 version:
    mb=MolToMolBlock(*m,true,-1,true,true);
    TEST_ASSERT(mb.find("V30 1 \"NOT [C,H]\" 0")!=std::string::npos);
    
    delete m;
  }
  
  BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
示例#5
0
文件: testMIF.cpp 项目: dfhahn/rdkit
void test4Coulomb () {
  std::string path = getenv("RDBASE");
  path += "/Code/GraphMol/MIF/test_data/";

  RWMol mol = *MolFileToMol(path + "HCl.mol", true, false);

  computeGasteigerCharges(mol);

  std::vector<double> charges;
  std::vector<Point3D> pos;
  Conformer conf = mol.getConformer(0);
  for (int i = 0; i < mol.getNumAtoms(); ++i) {
    charges.push_back(mol.getAtomWithIdx (i)->getProp<double> ("_GasteigerCharge"));
    pos.push_back(conf.getAtomPos(i));
  }

  UniformRealValueGrid3D grd = *constructGrid(mol);
  UniformRealValueGrid3D grd2 = *constructGrid(mol);

  Coulomb coul(mol);

  calculateDescriptors<Coulomb>(grd, coul);
  calculateDescriptors<Coulomb>(grd2, Coulomb (charges, pos));

  CHECK_INVARIANT(grd.compareGrids(grd2),
                  "Coulomb: Different constructors do not yield the same descriptor.");
  CHECK_INVARIANT(feq (coul(0.0,0.0,0.0, 1000), 0.0),
                  "Coulomb: Potential between atoms wrong.(should be 0)");
  CHECK_INVARIANT(coul(2.0,0.0,0.0, 1000) < 0,
                  "Coulomb: Potential between positive charges not positive.");
  CHECK_INVARIANT(coul(-2.0,0.0,0.0, 1000) > 0,
                  "Coulomb: Potential between positive and negative charges not negative.");
  CHECK_INVARIANT(feq(coul(0.0,0.0,0.0, 0.1), 0.0),
                  "Coulomb: Small threshold dist does not give 0.");
                  
  calculateDescriptors<Coulomb>(grd, Coulomb(mol, 0, 1.0, true));
  for (unsigned int i = 0; i < grd.getSize(); i++) {
    CHECK_INVARIANT(grd.getVal (i) <= 0.0, "Coulomb: Absolute value field not negative");
  }

Coulomb coul1(mol, 0, -1.0, false, "_GasteigerCharge", 0.0, 0.01);
  CHECK_INVARIANT(coul1(-2.0, 0.0, 0.0, 1000) < 0, "Coulomb: Potential between negative charges not positive.");
  CHECK_INVARIANT(coul1(2.0, 0.0, 0.0, 1000) > 0, "Coulomb: Potential between positive and negative charges not negative.");

  Coulomb coul2 = Coulomb(mol, 0, -.5, false, "_GasteigerCharge", 0.0, 0.01);
  CHECK_INVARIANT(coul1(-2.0, 0.0, 0.0, 1000) < coul2 (-2.0, 0.0, 0.0, 1000),
                  "Coulomb: Higher probecharge does not result in stronger forces.");

  Coulomb coul3(mol, 0, 1.0, false, "_GasteigerCharge", 0.01, 1.0);
  CHECK_INVARIANT(coul3(0.0, 0.0, 0.0, 1000) > coul3(0.1, 0.0, 0.0, 1000),
                  "Coulomb: Softcore interaction wrong.");
  CHECK_INVARIANT(coul3(0.66, 0.0, 0.0, 1000) > coul3(0.68, 0.0, 0.0, 1000),
                  "Coulomb: Softcore interaction wrong.");
  CHECK_INVARIANT(coul3(0.70, 0.0, 0.0, 1000) > coul3(0.68, 0.0, 0.0, 1000),
                  "Coulomb: Softcore interaction wrong.");
  CHECK_INVARIANT(feq(coul3(0.0,0.0,0.0, 0.1), 0.0),
                  "Coulomb: Small threshold dist does not give 0.");

}
示例#6
0
void test504() {
  BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "Testing FMCS test504" << std::endl;
  std::cout << "\ntest504()\n";
  std::vector<ROMOL_SPTR> mols;
  const char* smi[] = {
      // TEST 504
      "C(CCNC(C1CC1[c:1]1[c:2]c(Cl)c(Cl)c[c:3]1)=O)CCN1CCC(NC(Nc2ccc(Cl)cc2)=O)"
      "C1 CHEMBL545864",  // - QUERY

      "FC(F)(F)c1cc(NC(N2CCCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)ccc1Cl "
      "CHEMBL528228",
      "FC(F)(F)c1cc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)C2)=O)ccc1Cl "
      "CHEMBL525875",
      "Fc1ccc(NC(N2CCCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)cc1C(F)(F)F "
      "CHEMBL527277",
      "FC(F)(F)c1cc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)ccc1Cl "
      "CHEMBL537333",
      "Fc1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)C2)=O)cc1C(F)(F)F "
      "CHEMBL588077",
      "FC(F)(F)c1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3cc(Cl)c(Cl)cc3)=O)C2)=O)cc1 "
      "CHEMBL525307",
      "Fc1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)cc1C(F)(F)F "
      "CHEMBL581847",
      "FC(F)(F)c1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3cc(Cl)c(Cl)cc3)=O)CC2)=O)cc1 "
      "CHEMBL579547",
      "N#Cc1cccc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)c1 "
      "CHEMBL529994",
  };
  RWMol* qm = SmilesToMol(getSmilesOnly(smi[0]));
  unsigned nq = qm->getNumAtoms();
  for (size_t ai = 0; ai < nq; ai++) {
    Atom* atom = qm->getAtomWithIdx(ai);
    atom->setProp("molAtomMapNumber", (int)ai);
  }
  std::cout << "Query +MAP " << MolToSmiles(*qm) << "\n";
  mols.push_back(ROMOL_SPTR(qm));  // with RING INFO
  for (size_t i = 1; i < sizeof(smi) / sizeof(smi[0]); i++)
    mols.push_back(
        ROMOL_SPTR(SmilesToMol(getSmilesOnly(smi[i]))));  // with RING INFO
  t0 = nanoClock();
  MCSResult res = findMCS(mols);
  std::cout << "MCS: " << res.SmartsString << " " << res.NumAtoms << " atoms, "
            << res.NumBonds << " bonds\n";
  printTime();
  TEST_ASSERT(res.NumAtoms == 34 && res.NumBonds == 36);
  BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
}
示例#7
0
文件: testMIF.cpp 项目: dfhahn/rdkit
void test3CubeFiles () {
  std::string path = getenv ("RDBASE");
  path += "/Code/GraphMol/MIF/test_data/";

  RWMol mol = *MolFileToMol(path + "HCl.mol", true, false);
  RealValueVect *data = new RealValueVect (0.0, 125);
  UniformRealValueGrid3D grd (5.0, 5.0, 5.0, 1.0, new Point3D (0.0, 0.0, 0.0),
                              data);
  for (unsigned int i = 0; i < grd.getSize (); i++) {
    grd.setVal (i, double (i / 10.0));
  }
  writeToCubeFile (grd, mol, path + "test3.cube");
  UniformRealValueGrid3D grd2;
  RWMol mol2 = *readFromCubeFile (grd2, path + "test3.cube");

  CHECK_INVARIANT(grd.getSize() == grd2.getSize(),
                  "I/O: grid sizes are not the same.");
  for (unsigned int i = 0; i < grd2.getSize (); i++) {
    CHECK_INVARIANT(feq(grd2.getVal(i), double(i / 10.0)),
                    "I/O: values in grid are not correct.");
  }
  CHECK_INVARIANT(grd.getNumX() == grd2.getNumX(), "I/O: grids are not the same.");
  CHECK_INVARIANT(grd.getNumY() == grd2.getNumY(), "I/O: grids are not the same.");
  CHECK_INVARIANT(grd.getNumZ() == grd2.getNumZ(), "I/O: grids are not the same.");
  CHECK_INVARIANT(feq(grd.getOffset().x, grd2.getOffset().x), "I/O: grids are not the same.");
  CHECK_INVARIANT(feq(grd.getSpacing(), grd2.getSpacing()), "I/O: grids are not the same.");
  CHECK_INVARIANT(grd.compareVectors(grd2), "I/O: grids are not the same.");
  CHECK_INVARIANT(grd.compareParams(grd2), "I/O: grids are not the same.");
  CHECK_INVARIANT(grd.compareGrids(grd2), "I/O: grids are not the same.");

  CHECK_INVARIANT(mol.getNumAtoms() == mol2.getNumAtoms(),
                  "I/O: number of atoms are not the same.");
  for (unsigned int i = 0; i < mol.getNumAtoms (); i++) {
    CHECK_INVARIANT(mol.getAtomWithIdx (i)->getAtomicNum ()
                    == mol2.getAtomWithIdx (i)->getAtomicNum (),
                    "I/O: atoms are not the same");
    CHECK_INVARIANT(feq (mol.getConformer ().getAtomPos (i).x,
                         mol2.getConformer ().getAtomPos (i).x),
                    "I/O: atom positions are not the same");
    CHECK_INVARIANT(feq (mol.getConformer ().getAtomPos (i).y,
                         mol2.getConformer ().getAtomPos (i).y),
                    "I/O: atom positions are not the same");
    CHECK_INVARIANT(feq (mol.getConformer ().getAtomPos (i).z,
                         mol2.getConformer ().getAtomPos (i).z),
                    "I/O: atom positions are not the same");
  }
}
示例#8
0
void testQualifiedQueries() {
  BOOST_LOG(rdErrorLog)
      << "---------------------- Test queries using qualifiers instead of =="
      << std::endl;
  RWMol *m = SmilesToMol("CNO");

  {
    QueryAtom qA;
    qA.setQuery(makeAtomNumQuery<ATOM_GREATER_QUERY>(7, "test"));
    TEST_ASSERT(qA.Match(m->getAtomWithIdx(0)));
    TEST_ASSERT(!qA.Match(m->getAtomWithIdx(1)));
    TEST_ASSERT(!qA.Match(m->getAtomWithIdx(2)));
  }
  {
    QueryAtom qA;
    qA.setQuery(makeAtomNumQuery<ATOM_GREATEREQUAL_QUERY>(7, "test"));
    TEST_ASSERT(qA.Match(m->getAtomWithIdx(0)));
    TEST_ASSERT(qA.Match(m->getAtomWithIdx(1)));
    TEST_ASSERT(!qA.Match(m->getAtomWithIdx(2)));
  }
  {
    QueryAtom qA;
    qA.setQuery(makeAtomNumQuery<ATOM_LESS_QUERY>(7, "test"));
    TEST_ASSERT(!qA.Match(m->getAtomWithIdx(0)));
    TEST_ASSERT(!qA.Match(m->getAtomWithIdx(1)));
    TEST_ASSERT(qA.Match(m->getAtomWithIdx(2)));
  }
  {
    QueryAtom qA;
    qA.setQuery(makeAtomNumQuery<ATOM_LESSEQUAL_QUERY>(7, "test"));
    TEST_ASSERT(!qA.Match(m->getAtomWithIdx(0)));
    TEST_ASSERT(qA.Match(m->getAtomWithIdx(1)));
    TEST_ASSERT(qA.Match(m->getAtomWithIdx(2)));
  }

  delete m;
  BOOST_LOG(rdErrorLog) << "Done!" << std::endl;
}
示例#9
0
void test18() {
  BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "Testing FMCS test18" << std::endl;
  std::cout << "\ntest18()\n";
  std::vector<ROMOL_SPTR> mols;
  const char* smi[] = {
      // TEST 18
      "Cc1nc(CN(C(C)c2ncccc2)CCCCN)ccc1 CHEMBL1682991",  //-- QUERY
      "Cc1ccc(CN(C(C)c2ccccn2)CCCCN)nc1 CHEMBL1682990",
      "Cc1cccnc1CN(C(C)c1ccccn1)CCCCN CHEMBL1682998",
      "CC(N(CCCCN)Cc1c(N)cccn1)c1ccccn1 CHEMBL1682987",
      "Cc1cc(C)c(CN(C(C)c2ccccn2)CCCCN)nc1 CHEMBL1682992",
      "Cc1cc(C(C)N(CCCCN)Cc2c(C)cccn2)ncc1 CHEMBL1682993",
      "Cc1nc(C(C)N(CCCCN)Cc2nc3c([nH]2)cccc3)ccc1 CHEMBL1682878",
      "CC(c1ncccc1)N(CCCCN)Cc1nc2c([nH]1)cccc2 CHEMBL1682867",
      "CC(N(CCCCN)Cc1c(C(C)(C)C)cccn1)c1ccccn1 CHEMBL1682989",
      "CC(N(CCCCN)Cc1c(C(F)(F)F)cccn1)c1ccccn1 CHEMBL1682988",
      //# 18 .  20 20 0.04 sec. Python MCS: CC(c1ccccn1)N(CCCCN)Ccnccc
  };
  RWMol* qm = SmilesToMol(getSmilesOnly(smi[0]));
  unsigned nq = qm->getNumAtoms();
  for (size_t ai = 0; ai < nq; ai++) {
    Atom* atom = qm->getAtomWithIdx(ai);
    atom->setProp("molAtomMapNumber", (int)ai);
  }
  std::cout << "Query +MAP " << MolToSmiles(*qm) << "\n";
  mols.push_back(ROMOL_SPTR(qm));  // with RING INFO
  for (size_t i = 1; i < sizeof(smi) / sizeof(smi[0]); i++)
    mols.push_back(
        ROMOL_SPTR(SmilesToMol(getSmilesOnly(smi[i]))));  // with RING INFO
  t0 = nanoClock();
  MCSResult res = findMCS(mols);
  std::cout << "MCS: " << res.SmartsString << " " << res.NumAtoms << " atoms, "
            << res.NumBonds << " bonds\n";
  printTime();
  TEST_ASSERT(res.NumAtoms == 21 && res.NumBonds == 21);
  BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
}
示例#10
0
void testGeneral(std::string rdbase){

  BOOST_LOG(rdInfoLog) << "---------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "-- testing general mol2 file parsing --" << std::endl;
  BOOST_LOG(rdInfoLog) << "---------------------------------------" << std::endl;

  {
    bool ok=false;
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/nonExistFile.mol2";
    try{
      RWMol *m = Mol2FileToMol(fName);
      delete m;
    } catch(const BadFileException &e){
      ok=true;
    }
    TEST_ASSERT(ok);
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/pyrazole_pyridine.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==5);

    // this was sf.net issue 2727976:
    TEST_ASSERT(m->getNumConformers()==1);
    TEST_ASSERT(m->getConformer().is3D());
    TEST_ASSERT(feq(m->getConformer().getAtomPos(0).x,1.5019));
    TEST_ASSERT(feq(m->getConformer().getAtomPos(0).y,1.0435));
    TEST_ASSERT(feq(m->getConformer().getAtomPos(0).z,0.0000));

    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/benzene.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==6);
    delete m;
  }
  {
    bool ok=false;
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/mol_noatoms.mol2";
    try {
      RWMol *m = Mol2FileToMol(fName);
      delete m;
    } catch(const FileParseException &e){
      ok=true;
    }
    TEST_ASSERT(ok);
  }
  {
    bool ok=false;
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/mol_nomol.mol2";
    try {
      RWMol *m = Mol2FileToMol(fName);
      delete m;
    } catch(const FileParseException &e){
      ok=true;
    }
    TEST_ASSERT(ok);
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/lonePairMol.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==5 && m->getNumBonds()==4);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/symmetricGuanidine.mol2";
    RWMol *m = Mol2FileToMol(fName,false);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(1)->getFormalCharge()==1);
    TEST_ASSERT(m->getAtomWithIdx(8)->getFormalCharge()==1);
    delete m;
  }

  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/highlySymmetricGuanidine.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(4)->getFormalCharge()==1);
    TEST_ASSERT(m->getAtomWithIdx(12)->getFormalCharge()==1);
    TEST_ASSERT(m->getAtomWithIdx(20)->getFormalCharge()==1);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Noxide.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(8)->getFormalCharge()==1);
    TEST_ASSERT(m->getAtomWithIdx(9)->getFormalCharge()==-1);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Noxide.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(8)->getFormalCharge()==1);
    TEST_ASSERT(m->getAtomWithIdx(9)->getFormalCharge()==-1);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/fusedRing.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);


    TEST_ASSERT(m->getAtomWithIdx(0)->getFormalCharge()==0);
    TEST_ASSERT(m->getAtomWithIdx(5)->getFormalCharge()==0);
    TEST_ASSERT(m->getAtomWithIdx(8)->getFormalCharge()==0);
    TEST_ASSERT(m->getAtomWithIdx(13)->getFormalCharge()==0);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/pyridiniumPhenyl.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(5)->getFormalCharge()==1);
    TEST_ASSERT(m->getAtomWithIdx(6)->getFormalCharge()==0);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/sulfonAmide.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(1)->getFormalCharge()==0);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/chargedAmidineRWH.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(6)->getFormalCharge()==1);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/chargedAmidineEC.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(3)->getFormalCharge()==1);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/chargedAmidine.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(9)->getFormalCharge()==1);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/dbtranslateCharged.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(8)->getFormalCharge()==1);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/dbtranslateUncharged.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(8)->getFormalCharge()==0);
    delete m;
  }
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/dbtranslateUnchargedRing.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(2)->getFormalCharge()==0);
    delete m;
  }


#if 0  
  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Sulfonate.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    BOOST_LOG(rdInfoLog) <<MolToSmiles(*m)<<std::endl;
    delete m;
  }
#endif

  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "-- DONE general mol2 file parsing --" << std::endl;
  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;

}
示例#11
0
int setAromaticity(RWMol &mol) {
  // FIX: we will assume for now that if the input molecule came
  // with aromaticity information it is correct and we will not
  // touch it. Loop through the atoms and check if any atom has
  // arom stuff set.  We may want check this more carefully later
  // and start from scratch if necessary
  ROMol::AtomIterator ai;
  for (ai = mol.beginAtoms(); ai != mol.endAtoms(); ai++) {
    if ((*ai)->getIsAromatic()) {
      // found aromatic info
      return -1;
    }
  }

  // first find the all the simple rings in the molecule
  VECT_INT_VECT srings;
  if (mol.getRingInfo()->isInitialized()) {
    srings = mol.getRingInfo()->atomRings();
  } else {
    MolOps::symmetrizeSSSR(mol, srings);
  }

  int narom = 0;
  // loop over all the atoms in the rings that can be candidates
  // for aromaticity
  // Atoms are candidates if
  //   - it is part of ring
  //   - has one or more electron to donate or has empty p-orbitals
  int natoms = mol.getNumAtoms();
  boost::dynamic_bitset<> acands(natoms);
  boost::dynamic_bitset<> aseen(natoms);
  VECT_EDON_TYPE edon(natoms);

  VECT_INT_VECT cRings;  // holder for rings that are candidates for aromaticity
  for (VECT_INT_VECT_I vivi = srings.begin(); vivi != srings.end(); ++vivi) {
    bool allAromatic = true;
    for (INT_VECT_I ivi = (*vivi).begin(); ivi != (*vivi).end(); ++ivi) {
      if (aseen[*ivi]) {
        if (!acands[*ivi]) allAromatic = false;
        continue;
      }
      aseen[*ivi] = 1;
      Atom *at = mol.getAtomWithIdx(*ivi);

      // now that the atom is part of ring check if it can donate
      // electron or has empty orbitals. Record the donor type
      // information in 'edon' - we will need it when we get to
      // the Huckel rule later
      edon[*ivi] = getAtomDonorTypeArom(at);
      acands[*ivi] = isAtomCandForArom(at, edon[*ivi]);
      if (!acands[*ivi]) allAromatic = false;
    }
    if (allAromatic) {
      cRings.push_back((*vivi));
    }
  }

  // first convert all rings to bonds ids
  VECT_INT_VECT brings;
  RingUtils::convertToBonds(cRings, brings, mol);

  // make the neighbor map for the rings
  // i.e. a ring is a neighbor a another candidate ring if
  // shares at least one bond
  // useful to figure out fused systems
  INT_INT_VECT_MAP neighMap;
  RingUtils::makeRingNeighborMap(brings, neighMap, maxFusedAromaticRingSize);

  // now loop over all the candidate rings and check the
  // huckel rule - of course paying attention to fused systems.
  INT_VECT doneRs;
  int curr = 0;
  int cnrs = rdcast<int>(cRings.size());
  boost::dynamic_bitset<> fusDone(cnrs);
  INT_VECT fused;
  while (curr < cnrs) {
    fused.resize(0);
    RingUtils::pickFusedRings(curr, neighMap, fused, fusDone);
    applyHuckelToFused(mol, cRings, brings, fused, edon, neighMap, narom, 6);

    int rix;
    for (rix = 0; rix < cnrs; rix++) {
      if (!fusDone[rix]) {
        curr = rix;
        break;
      }
    }
    if (rix == cnrs) {
      break;
    }
  }

  mol.setProp(common_properties::numArom, narom, true);

  return narom;
}
示例#12
0
void deletebonds(const ROMol &mol, String ftype, int hac){
RWMol *newMol = static_cast<RWMol*>(new ROMol(mol,false));
int total_acyclic = 0;
int total_cyclic = 0;
//find the relevant bonds to break

// Single acyclic Cuts
if(ftype == acyc_smarts){
acyclic_matching_atoms = mol.getSubstructMatches(acyc);
total_acyclic = acyclic_matching_atoms.size();
MatchVectType acyclic_matching_atoms;
std::vector<int> bonds_selected;
Match_Vect bonds_selected;
SubstructMatch(mol, acyc, acyclic_matching_atoms);
// if we didn't find any matches, there's nothing to be done here
    // simply return a list with a copy of the starting molecule
    if (acyclic_matching_atoms.size() == 0) {
      newMol.push_back(ROMOL_SPTR(new ROMol(mol,false)));
      newMol[0]->clearComputedProps(false);
      return newMol;
for(MatchVectType::const_iterator mvit=acyclic_matching_atoms.begin();
        mvit!=acyclic_matching_atoms.end(); mvit++){
      bonds_selected.push_back(mvit->first);
      bonds_selected.push_back(mvit->second);
	bonds_selected[0] = mvit->first;
	bonds_selected[1] = mvit->second;

Atom *at1 = newMol->getAtomWithIdx(bonds_selected[0]);
Atom *at2 = newMol->getAtomWithIdx(bonds_selected[1]);
Atom *atom0 = newMol->getAtomWithIdx(0);
Atom *atom1 = newMol->getAtomWithIdx(0);
newMol->removeBond(bonds_selected[0], bonds_selected[1]);// Break the bond with idx=at1, at2.

// Introduce two dummy atoms in the molecule
newMol->addAtom(atom0);
newMol->addAtom(atom1);
// Bond the dummy atoms to the new terminal atoms
Bond *oBond=newMol->getBondBetweenAtoms(bonds_selected[0],atom0->getIdx());
          CHECK_INVARIANT(oBond,"required bond not found");
          newMol->addBond(at1,
                          *atom0,Bond::SINGLE);

Bond *oBond=newMol->getBondBetweenAtoms(bonds_selected[1],atom1->getIdx());
          CHECK_INVARIANT(oBond,"required bond not found");
          newMol->addBond(at2,
                          *atom1,Bond::SINGLE);

break;
}

//Now get the modified fragment in smiles(i.e. smi2);

String smi2 = MolToSmiles(*newMol);

//printf (smi2);
	}
}

//cyclic Cuts
if(ftype == cyc_smarts){
cyclic_matching_atoms = mol.getSubstructMatches(cyc);
int total_cyclic = cyclic_matching_atoms.size();
MatchVectType cyclic_matching_atoms;
std::vector<int> bonds_selected;
Match_Vect bonds_selected;
SubstructMatch(mol, cyc, cyclic_matching_atoms);
// if we didn't find any matches, there's nothing to be done here
    // simply return a list with a copy of the starting molecule
    if (cyclic_matching_atoms.size() == 0) {
      newMol.push_back(ROMOL_SPTR(new ROMol(mol,false)));
      newMol[0]->clearComputedProps(false);
      return newMol;
for(MatchVectType::const_iterator mvit=cyclic_matching_atoms.begin();
        mvit!=cyclic_matching_atoms.end(); mvit++){
      bonds_selected.push_back(mvit->first);
      bonds_selected.push_back(mvit->second);
	bonds_selected[0] = mvit->first;
	bonds_selected[1] = mvit->second;

Atom *at1 = newMol->getAtomWithIdx(bonds_selected[0]);
Atom *at2 = newMol->getAtomWithIdx(bonds_selected[1]);
Atom *atom0 = newMol->getAtomWithIdx(0);
Atom *atom1 = newMol->getAtomWithIdx(0);
newMol->removeBond(bonds_selected[0], bonds_selected[1]);// Break the bond with idx=at1, at2.

// Introduce two dummy atoms in the molecule
newMol->addAtom(atom0);
newMol->addAtom(atom1);
// Bond the dummy atoms to the new terminal atoms
Bond *oBond=newMol->getBondBetweenAtoms(bonds_selected[0],atom0->getIdx());
          CHECK_INVARIANT(oBond,"required bond not found");
          newMol->addBond(at1,
                          *atom0,Bond::SINGLE);

Bond *oBond=newMol->getBondBetweenAtoms(bonds_selected[1],atom1->getIdx());
          CHECK_INVARIANT(oBond,"required bond not found");
          newMol->addBond(at2,
                          *atom1,Bond::SINGLE);

continue;
}
//Now get the modified fragment in smiles(i.e. smi2);

String smi2 = MolToSmiles(*newMol);
//printf (smi2);

//now do an acyclic cut with the successful cyclic cut on the mol
for(MatchVectType::const_iterator mvit=acyclic_matching_atoms.begin();
        mvit!=acyclic_matching_atoms.end(); mvit++){
      bonds_selected.push_back(mvit->first);
      bonds_selected.push_back(mvit->second);
	bonds_selected[0] = mvit->first;
	bonds_selected[1] = mvit->second;

Atom *at1 = newMol->getAtomWithIdx(bonds_selected[0]);
Atom *at2 = newMol->getAtomWithIdx(bonds_selected[1]);
Atom *atom0 = newMol->getAtomWithIdx(0);
Atom *atom1 = newMol->getAtomWithIdx(0);
newMol->removeBond(bonds_selected[0], bonds_selected[1]);// Break the bond with idx=at1, at2.

// Introduce two dummy atoms in the molecule
newMol->addAtom(atom0);
newMol->addAtom(atom1);
// Bond the dummy atoms to the new terminal atoms
Bond *oBond=newMol->getBondBetweenAtoms(bonds_selected[0],atom0->getIdx());
          CHECK_INVARIANT(oBond,"required bond not found");
          newMol->addBond(at1,
                          *nbrIdx,oBond->getBondType());

Bond *oBond=newMol->getBondBetweenAtoms(bonds_selected[1],atom1->getIdx());
          CHECK_INVARIANT(oBond,"required bond not found");
          newMol->addBond(at2,
                          *atom1,Bond::SINGLE);

continue;
}

//Now get the modified fragment in smiles(i.e. smi2);

String smi2 = MolToSmiles(*newMol);
//printf (smi2);
	}
}

//determine whether ring cut is valid
String cSma1 = ("[#0][r].[r][#0]");
static ROMol *Sma1 = SmartsToMol("[#0][r].[r][#0]");
String cSma2 = ("[#0][r][#0]");
static ROMol *Sma2 = SmartsToMol("[#0][r][#0]");
void is_ring_cut_valid(ROMol *fMol, ROMol *Sma1, ROMol *Sma2){
//to check is a fragment is a valid ring cut, it needs to match the
//smarts: [$([#0][r].[r][#0]),$([#0][r][#0])]

	boolean valid = false;
	ROMol *m = new RWMol();
//if m is not None:
	if (m != NULL){
    //use global smarts
    if(m->hasSubstructMatch(Sma1) || m->hasSubstructMatch(Sma2)){
    	int atom_count = m->getNumAtoms();
    	valid = true;
    		}
	}
}
示例#13
0
void testV3000WriterDetails(){
  BOOST_LOG(rdInfoLog) << "testing details of v3000 writing" << std::endl;
  std::string rdbase = getenv("RDBASE");
  rdbase += "/Code/GraphMol/FileParsers/test_data/";
  {
    std::string fName = rdbase + "chebi_57262.v3k.mol";
    RWMol *m = MolFileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==22);
    TEST_ASSERT(m->getNumBonds()==21);
    TEST_ASSERT(m->getAtomWithIdx(18)->getAtomicNum()==0);
    TEST_ASSERT(!m->getAtomWithIdx(18)->hasQuery());
    TEST_ASSERT(m->getAtomWithIdx(18)->getIsotope()==1);
    TEST_ASSERT(m->getAtomWithIdx(21)->getAtomicNum()==0);
    TEST_ASSERT(!m->getAtomWithIdx(21)->hasQuery());
    TEST_ASSERT(m->getAtomWithIdx(21)->getIsotope()==2);

    std::string mb=MolToMolBlock(*m,true,-1,true,true);
    TEST_ASSERT(mb.find("MASS=1")!=std::string::npos);
    TEST_ASSERT(mb.find("MASS=2")!=std::string::npos);

    delete m;
    m = MolBlockToMol(mb);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==22);
    TEST_ASSERT(m->getNumBonds()==21);
    TEST_ASSERT(m->getAtomWithIdx(18)->getAtomicNum()==0);
    TEST_ASSERT(!m->getAtomWithIdx(18)->hasQuery());
    TEST_ASSERT(m->getAtomWithIdx(18)->getIsotope()==1);
    TEST_ASSERT(m->getAtomWithIdx(21)->getAtomicNum()==0);
    TEST_ASSERT(!m->getAtomWithIdx(21)->hasQuery());
    TEST_ASSERT(m->getAtomWithIdx(21)->getIsotope()==2);

    // repeat that one more time to make sure we're really solid:
    mb=MolToMolBlock(*m,true,-1,true,true);
    TEST_ASSERT(mb.find("MASS=1")!=std::string::npos);
    TEST_ASSERT(mb.find("MASS=2")!=std::string::npos);

    delete m;
    m = MolBlockToMol(mb);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==22);
    TEST_ASSERT(m->getNumBonds()==21);
    TEST_ASSERT(m->getAtomWithIdx(18)->getAtomicNum()==0);
    TEST_ASSERT(!m->getAtomWithIdx(18)->hasQuery());
    TEST_ASSERT(m->getAtomWithIdx(18)->getIsotope()==1);
    TEST_ASSERT(m->getAtomWithIdx(21)->getAtomicNum()==0);
    TEST_ASSERT(!m->getAtomWithIdx(21)->hasQuery());
    TEST_ASSERT(m->getAtomWithIdx(21)->getIsotope()==2);
    
    delete m;
  }
  
  BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
示例#14
0
void testIssue3525000() {
  {
    std::string rdbase = getenv("RDBASE");
    std::string fname = rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3525000.sdf";
    RWMol *mol = MolFileToMol(fname);
    TEST_ASSERT(mol);
    std::string cip;
    TEST_ASSERT(mol->getAtomWithIdx(0)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(0)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(3)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(3)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(6)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(6)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(8)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(8)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(9)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(9)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(10)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(10)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="S");
    TEST_ASSERT(mol->getAtomWithIdx(14)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(14)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(15)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(15)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");

    std::string mb=MolToMolBlock(*mol);
    delete mol;
    mol = MolBlockToMol(mb);
    TEST_ASSERT(mol);
    TEST_ASSERT(mol->getAtomWithIdx(0)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(0)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(3)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(3)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(6)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(6)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(8)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(8)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(9)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(9)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(10)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(10)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="S");
    TEST_ASSERT(mol->getAtomWithIdx(14)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(14)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(15)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(15)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
  }  
  {
    std::string rdbase = getenv("RDBASE");
    std::string fname = rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3525000b.sdf";
    RWMol *mol = MolFileToMol(fname);
    TEST_ASSERT(mol);
    MolOps::assignChiralTypesFrom3D(*mol);
    MolOps::assignStereochemistry(*mol);
    std::string cip;
    TEST_ASSERT(mol->getAtomWithIdx(0)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(0)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="S");
    TEST_ASSERT(mol->getAtomWithIdx(1)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(1)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="S");
    TEST_ASSERT(mol->getAtomWithIdx(2)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(2)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(3)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(3)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(4)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(4)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="S");

    std::string mb=MolToMolBlock(*mol);
    delete mol;
    mol = MolBlockToMol(mb);
    TEST_ASSERT(mol);
    TEST_ASSERT(mol->getAtomWithIdx(0)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(0)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="S");
    TEST_ASSERT(mol->getAtomWithIdx(1)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(1)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="S");
    TEST_ASSERT(mol->getAtomWithIdx(2)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(2)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(3)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(3)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="R");
    TEST_ASSERT(mol->getAtomWithIdx(4)->hasProp("_CIPCode"));
    mol->getAtomWithIdx(4)->getProp("_CIPCode",cip);
    TEST_ASSERT(cip=="S");
  }  
}
示例#15
0
文件: Kekulize.cpp 项目: giallu/rdkit
bool kekulizeWorker(RWMol &mol, const INT_VECT &allAtms,
                    boost::dynamic_bitset<> dBndCands,
                    boost::dynamic_bitset<> dBndAdds, INT_VECT done,
                    unsigned int maxBackTracks) {
  INT_DEQUE astack;
  INT_INT_DEQ_MAP options;
  int lastOpt = -1;
  boost::dynamic_bitset<> localBondsAdded(mol.getNumBonds());

  // ok the algorithm goes something like this
  // - start with an atom that has been marked aromatic before
  // - check if it can have a double bond
  // - add its neighbors to the stack
  // - check if one of its neighbors can also have a double bond
  // - if yes add a double bond.
  // - if multiple neighbors can have double bonds - add them to a
  //   options stack we may have to retrace out path if we chose the
  //   wrong neighbor to add the double bond
  // - if double bond added update the candidates for double bond
  // - move to the next atom on the stack and repeat the process
  // - if an atom that can have multiple a double bond has no
  //   neighbors that can take double bond - we made a mistake
  //   earlier by picking a wrong candidate for double bond
  // - in this case back track to where we made the mistake

  int curr;
  INT_DEQUE btmoves;
  unsigned int numBT = 0;  // number of back tracks so far
  while ((done.size() < allAtms.size()) || (astack.size() > 0)) {
    // pick a curr atom to work with
    if (astack.size() > 0) {
      curr = astack.front();
      astack.pop_front();
    } else {
      for (int allAtm : allAtms) {
        if (std::find(done.begin(), done.end(), allAtm) == done.end()) {
          curr = allAtm;
          break;
        }
      }
    }
    done.push_back(curr);

    // loop over the neighbors if we can add double bonds or
    // simply push them onto the stack
    INT_DEQUE opts;
    bool cCand = false;
    if (dBndCands[curr]) {
      cCand = true;
    }
    int ncnd;
    // if we are here because of backtracking
    if (options.find(curr) != options.end()) {
      opts = options[curr];
      CHECK_INVARIANT(opts.size() > 0, "");
    } else {
      RWMol::ADJ_ITER nbrIdx, endNbrs;
      boost::tie(nbrIdx, endNbrs) =
          mol.getAtomNeighbors(mol.getAtomWithIdx(curr));
      while (nbrIdx != endNbrs) {
        // ignore if the neighbor has already been dealt with before
        if (std::find(done.begin(), done.end(), static_cast<int>(*nbrIdx)) !=
            done.end()) {
          ++nbrIdx;
          continue;
        }
        // ignore if the neighbor is not part of the fused system
        if (std::find(allAtms.begin(), allAtms.end(),
                      static_cast<int>(*nbrIdx)) == allAtms.end()) {
          ++nbrIdx;
          continue;
        }

        // if the neighbor is not on the stack add it
        if (std::find(astack.begin(), astack.end(),
                      static_cast<int>(*nbrIdx)) == astack.end()) {
          astack.push_back(rdcast<int>(*nbrIdx));
        }

        // check if the neighbor is also a candidate for a double bond
        // the refinement that we'll make to the candidate check we've already
        // done is to make sure that the bond is either flagged as aromatic
        // or involves a dummy atom. This was Issue 3525076.
        // This fix is not really 100% of the way there: a situation like
        // that for Issue 3525076 but involving a dummy atom in the cage
        // could lead to the same failure. The full fix would require
        // a fairly detailed analysis of all bonds in the molecule to determine
        // which of them is eligible to be converted.
        if (cCand && dBndCands[*nbrIdx] &&
            (mol.getBondBetweenAtoms(curr, *nbrIdx)->getIsAromatic() ||
             mol.getAtomWithIdx(curr)->getAtomicNum() == 0 ||
             mol.getAtomWithIdx(*nbrIdx)->getAtomicNum() == 0)) {
          opts.push_back(rdcast<int>(*nbrIdx));
        }  // end of curr atoms can have a double bond
        ++nbrIdx;
      }  // end of looping over neighbors
    }
    // now add a double bond from current to one of the neighbors if we can
    if (cCand) {
      if (opts.size() > 0) {
        ncnd = opts.front();
        opts.pop_front();
        Bond *bnd = mol.getBondBetweenAtoms(curr, ncnd);
        bnd->setBondType(Bond::DOUBLE);

        // remove current and the neighbor from the dBndCands list
        dBndCands[curr] = 0;
        dBndCands[ncnd] = 0;

        // add them to the list of bonds to which have been made double
        dBndAdds[bnd->getIdx()] = 1;
        localBondsAdded[bnd->getIdx()] = 1;

        // if this is an atom we previously visted and picked we
        // simply tried a different option now, overwrite the options
        // stored for this atoms
        if (options.find(curr) != options.end()) {
          if (opts.size() == 0) {
            options.erase(curr);
            btmoves.pop_back();
            if (btmoves.size() > 0) {
              lastOpt = btmoves.back();
            } else {
              lastOpt = -1;
            }
          } else {
            options[curr] = opts;
          }
        } else {
          // this is new atoms we are trying and have other
          // neighbors as options to add double bond store this to
          // the options stack, we may have made a mistake in
          // which one we chose and have to return here
          if (opts.size() > 0) {
            lastOpt = curr;
            btmoves.push_back(lastOpt);
            options[curr] = opts;
          }
        }

      }  // end of adding a double bond
      else {
        // we have an atom that should be getting a double bond
        // but none of the neighbors can take one. Most likely
        // because of a wrong choice earlier so back track
        if ((lastOpt >= 0) && (numBT < maxBackTracks)) {
          // std::cerr << "PRE BACKTRACK" << std::endl;
          // mol.debugMol(std::cerr);
          backTrack(mol, options, lastOpt, done, astack, dBndCands, dBndAdds);
          // std::cerr << "POST BACKTRACK" << std::endl;
          // mol.debugMol(std::cerr);
          numBT++;
        } else {
          // undo any remaining changes we made while here
          // this was github #962
          for (unsigned int bidx = 0; bidx < mol.getNumBonds(); ++bidx) {
            if (localBondsAdded[bidx]) {
              mol.getBondWithIdx(bidx)->setBondType(Bond::SINGLE);
            }
          }
          return false;
        }
      }  // end of else try to backtrack
    }    // end of curr atom atom being a cand for double bond
  }      // end of while we are not done with all atoms
  return true;
}