bool OBCisTransStereo::operator==(const OBCisTransStereo &other) const { if (!IsValid() || !other.IsValid()) return false; Config u = OBTetraPlanarStereo::ToConfig(other.GetConfig(), m_cfg.refs.at(0), OBStereo::ShapeU); unsigned long a1 = u.refs.at(0); unsigned long b1 = u.refs.at(2); if ((a1 == OBStereo::ImplicitRef) && (b1 == OBStereo::ImplicitRef)) { a1 = u.refs.at(1); b1 = u.refs.at(3); } if (b1 != OBStereo::ImplicitRef) if (a1 == GetTransRef(b1)) return true; if (a1 != OBStereo::ImplicitRef) if (b1 == GetTransRef(a1)) return true; return false; }
void genericSmilesCanonicalTest(const std::string &smiles) { cout << "Testing generic smiles <-> canonical smiles" << endl; // read a smiles string OBMol mol; OBConversion conv; OB_REQUIRE( conv.SetInFormat("smi") ); OB_REQUIRE( conv.SetOutFormat("can") ); cout << "smiles: " << smiles << endl; // read a smiles string OB_REQUIRE( conv.ReadString(&mol, smiles) ); // store the stereo data for the smiles string using unique symmetry ids std::vector<OBTetrahedralStereo::Config> tetrahedral1; std::vector<OBCisTransStereo::Config> cistrans1; std::vector<OBSquarePlanarStereo::Config> squareplanar1; // get the stereo data OB_ASSERT( mol.HasData(OBGenericDataType::StereoData) ); std::vector<OBGenericData *> stereoData = mol.GetAllData(OBGenericDataType::StereoData); std::vector<unsigned int> canlbls; std::vector<unsigned int> symclasses; OBGraphSym gs1(&mol); gs1.GetSymmetry(symclasses); CanonicalLabels(&mol, symclasses, canlbls); cout << "mol.NumAtoms = " << mol.NumAtoms() << endl; for (std::vector<OBGenericData*>::iterator data = stereoData.begin(); data != stereoData.end(); ++data) { if (((OBStereoBase*)*data)->GetType() == OBStereo::Tetrahedral) { // convert to tetrahedral data OBTetrahedralStereo *ts = dynamic_cast<OBTetrahedralStereo*>(*data); OB_REQUIRE( ts ); OB_ASSERT( ts->IsValid() ); if (!ts->IsValid()) continue; OBTetrahedralStereo::Config config = ts->GetConfig(); // convert atom ids to symmetry ids if (mol.GetAtomById(config.center)) config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 ); if (mol.GetAtomById(config.from)) config.from = canlbls.at( mol.GetAtomById(config.from)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; tetrahedral1.push_back(config); } else if (((OBStereoBase*)*data)->GetType() == OBStereo::CisTrans) { // convert to tetrahedral data OBCisTransStereo *ct = dynamic_cast<OBCisTransStereo*>(*data); OB_REQUIRE( ct ); OB_ASSERT( ct->IsValid() ); OBCisTransStereo::Config config = ct->GetConfig(); // convert atom ids to symmetry ids config.begin = canlbls.at( mol.GetAtomById(config.begin)->GetIdx() - 1 ); config.end = canlbls.at( mol.GetAtomById(config.end)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[3])) config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; cistrans1.push_back(config); } else if (((OBStereoBase*)*data)->GetType() == OBStereo::SquarePlanar) { // convert to tetrahedral data OBSquarePlanarStereo *sp = dynamic_cast<OBSquarePlanarStereo*>(*data); OB_REQUIRE( sp ); OB_ASSERT( sp->IsValid() ); if (!sp->IsValid()) continue; OBSquarePlanarStereo::Config config = sp->GetConfig(); // convert atom ids to symmetry ids if (mol.GetAtomById(config.center)) config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[3])) config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; squareplanar1.push_back(config); } } // write to can smiles std::string canSmiles = conv.WriteString(&mol); cout << "canSmiles: " << canSmiles; // read can smiles in again OB_REQUIRE( conv.ReadString(&mol, canSmiles) ); // store the stereo data for the smiles string using unique symmetry ids std::vector<OBTetrahedralStereo::Config> tetrahedral2; std::vector<OBCisTransStereo::Config> cistrans2; std::vector<OBSquarePlanarStereo::Config> squareplanar2; // get the stereo data OB_ASSERT( mol.HasData(OBGenericDataType::StereoData) ); stereoData = mol.GetAllData(OBGenericDataType::StereoData); OBGraphSym gs2(&mol); gs2.GetSymmetry(symclasses); CanonicalLabels(&mol, symclasses, canlbls); cout << "mol.NumAtoms = " << mol.NumAtoms() << endl; for (std::vector<OBGenericData*>::iterator data = stereoData.begin(); data != stereoData.end(); ++data) { if (((OBStereoBase*)*data)->GetType() == OBStereo::Tetrahedral) { // convert to tetrahedral data OBTetrahedralStereo *ts = dynamic_cast<OBTetrahedralStereo*>(*data); OB_REQUIRE( ts ); OB_ASSERT( ts->IsValid() ); OBTetrahedralStereo::Config config = ts->GetConfig(); // convert atom ids to symmetry ids if (mol.GetAtomById(config.center)) config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 ); if (mol.GetAtomById(config.from)) config.from = canlbls.at( mol.GetAtomById(config.from)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; tetrahedral2.push_back(config); } if (((OBStereoBase*)*data)->GetType() == OBStereo::CisTrans) { // convert to tetrahedral data OBCisTransStereo *ct = dynamic_cast<OBCisTransStereo*>(*data); OB_REQUIRE( ct ); OB_ASSERT( ct->IsValid() ); OBCisTransStereo::Config config = ct->GetConfig(); // convert atom ids to symmetry ids config.begin = canlbls.at( mol.GetAtomById(config.begin)->GetIdx() - 1 ); config.end = canlbls.at( mol.GetAtomById(config.end)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[3])) config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; cistrans2.push_back(config); } else if (((OBStereoBase*)*data)->GetType() == OBStereo::SquarePlanar) { // convert to tetrahedral data OBSquarePlanarStereo *sp = dynamic_cast<OBSquarePlanarStereo*>(*data); OB_REQUIRE( sp ); OB_ASSERT( sp->IsValid() ); OBSquarePlanarStereo::Config config = sp->GetConfig(); // convert atom ids to symmetry ids if (mol.GetAtomById(config.center)) config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[3])) config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; squareplanar2.push_back(config); } } // compare the tetrahedral structs OB_ASSERT( tetrahedral1.size() == tetrahedral2.size() ); for (unsigned int i = 0; i < tetrahedral1.size(); ++i) { for (unsigned int j = 0; j < tetrahedral2.size(); ++j) { if (tetrahedral1[i].center == tetrahedral2[j].center) OB_ASSERT( tetrahedral1[i] == tetrahedral2[j] ); if ( tetrahedral1[i] != tetrahedral2[j] ) { cout << "1 = " << tetrahedral1[i] << endl; cout << "2 = " << tetrahedral2[j] << endl; } } } // compare the cistrans structs OB_ASSERT( cistrans1.size() == cistrans2.size() ); for (unsigned int i = 0; i < cistrans1.size(); ++i) { for (unsigned int j = 0; j < cistrans2.size(); ++j) { if ((cistrans1[i].begin == cistrans2[j].begin) && (cistrans1[i].end == cistrans2[j].end)) OB_ASSERT( cistrans1[i] == cistrans2[j] ); if ((cistrans1[i].begin == cistrans2[j].end) && (cistrans1[i].end == cistrans2[j].begin)) OB_ASSERT( cistrans1[i] == cistrans2[j] ); } } // compare the square-planar structs OB_ASSERT( squareplanar1.size() == squareplanar2.size() ); for (unsigned int i = 0; i < squareplanar1.size(); ++i) { for (unsigned int j = 0; j < squareplanar2.size(); ++j) { if (squareplanar1[i].center == squareplanar2[j].center) OB_ASSERT( squareplanar1[i] == squareplanar2[j] ); if ( squareplanar1[i] != squareplanar2[j] ) { cout << "1 = " << squareplanar1[i] << endl; cout << "2 = " << squareplanar2[j] << endl; } } } cout << "." << endl << endl; }