void OBStereoFacade::InitMaps() { if (m_perceive && !m_mol->HasChiralityPerceived()) PerceiveStereo(m_mol); std::vector<OBGenericData *> stereoData = m_mol->GetAllData(OBGenericDataType::StereoData); std::vector<OBGenericData*>::iterator data; for (data = stereoData.begin(); data != stereoData.end(); ++data) { OBStereo::Type type = ((OBStereoBase*)*data)->GetType(); if (type == OBStereo::Tetrahedral) { OBTetrahedralStereo *ts = dynamic_cast<OBTetrahedralStereo*>(*data); OBTetrahedralStereo::Config config = ts->GetConfig(); if (config.center == OBStereo::NoRef) continue; m_tetrahedralMap[config.center] = ts; } else if (type == OBStereo::SquarePlanar) { OBSquarePlanarStereo *sp = dynamic_cast<OBSquarePlanarStereo*>(*data); OBSquarePlanarStereo::Config config = sp->GetConfig(); if (config.center == OBStereo::NoRef) continue; m_squarePlanarMap[config.center] = sp; } else if (type == OBStereo::CisTrans) { OBCisTransStereo *ct = dynamic_cast<OBCisTransStereo*>(*data); OBCisTransStereo::Config config = ct->GetConfig(); // find the bond id from begin & end atom ids unsigned long id = OBStereo::NoRef; OBAtom *a = m_mol->GetAtomById(config.begin); if (!a) continue; FOR_BONDS_OF_ATOM (bond, a) { unsigned long beginId = bond->GetBeginAtom()->GetId(); unsigned long endId = bond->GetEndAtom()->GetId(); if ((beginId == config.begin && endId == config.end) || (beginId == config.end && endId == config.begin)) { id = bond->GetId(); break; } } if (id == OBStereo::NoRef) continue; m_cistransMap[id] = ct; }
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; }
OBGenericData* OBCisTransStereo::Clone(OBBase *mol) const { OBCisTransStereo *data = new OBCisTransStereo(static_cast<OBMol*>(mol)); data->SetConfig(m_cfg); return data; }