/*********************************************************************** Copyright (C) 2002, 2003 OpenEye Scientific Software, Inc. ***********************************************************************/ #include "openeye.h" #include #include #include "oeplatform.h" #include "oesystem.h" #include "oechem.h" using namespace OESystem; using namespace OEChem; using namespace std; oemolistream ifs; oemolostream ofs; unsigned int maxCenters = 12; // This an implementation which is moderately slow, but is a good example of // predicate iterators and use of the bi-directional properties of iterators // // For a production version of Flipper, please see flipper1 // bool flip(oemolostream &ofs, OEMolBase *mol, OEIter &atom,OEIter &bond) { if(atom) { OEAtomBase *a = atom; const vector &va = a->GetData >("Neighbors"); ++atom; a->SetStereo(va,OEAtomStereo::Tetra,OEAtomStereo::Right); if(!flip(ofs,mol,atom,bond)) ofs << *mol; a->SetStereo(va,OEAtomStereo::Tetra,OEAtomStereo::Left); if(!flip(ofs,mol,atom,bond)) ofs << *mol; a->SetStereo(va,OEAtomStereo::Tetra,OEAtomStereo::Undefined); --atom; return true; } if(bond) { OEBondBase *b = bond; const vector &vb = b->GetData >("Neighbors"); ++bond; b->SetStereo(vb,OEBondStereo::CisTrans,OEBondStereo::Cis); if(!flip(ofs,mol,atom,bond)) ofs << *mol; b->SetStereo(vb,OEBondStereo::CisTrans,OEBondStereo::Trans); if(!flip(ofs,mol,atom,bond)) ofs << *mol; b->SetStereo(vb,OEBondStereo::CisTrans,OEBondStereo::Undefined); --bond; return true; } return false; } void ProcessArgs(int argc,char *argv[]) { if (argc > 4 || argc < 3) OEThrow.Usage("flipper [maxCenters=12]"); if(!ifs.open(argv[1])) OEThrow.Error("Unable to open %s for reading.\n",argv[1]); if(!ofs.open(argv[2])) OEThrow.Error("Unable to open %s for writing.\n",argv[2]); if(argc == 4) maxCenters = (unsigned int)atoi(argv[3]); cerr << maxCenters << endl; } bool PrepareStereoCenters(OEIter &atom,OEIter &bond) { OEIter nbr; std::vector nbrs; for(;atom;++atom) { nbrs.clear(); for(nbr = atom->GetAtoms();nbr;++nbr) nbrs.push_back(nbr); atom->SetData("Neighbors",nbrs); } for(;bond;++bond) { nbrs.clear(); OEAtomBase *bgn = bond->GetBgn(); OEAtomBase *end = bond->GetEnd(); for(nbr = bgn->GetAtoms();nbr;++nbr) if(nbr != end) { nbrs.push_back(nbr); break; } for(nbr = end->GetAtoms();nbr;++nbr) if(nbr != bgn) { nbrs.push_back(nbr); break; } bond->SetData("Neighbors",nbrs); } atom.ToFirst(); bond.ToFirst(); return true; } int main(int argc,char *argv[]) { ProcessArgs(argc,argv); //build atom predicate IsChiralAtom isChiralAtom; HasAtomStereoSpecified atomStereoSpecified; //negate predicate OENot notAtomStereoSpecified(atomStereoSpecified); //logical and 2 predicates OEAnd unspecifiedChiralAtom(isChiralAtom,notAtomStereoSpecified); //build bond predicate IsChiralBond isChiralBond; HasBondStereoSpecified bondStereoSpecified; //negate predicate OENot notBondStereoSpecified(bondStereoSpecified); //logical and 2 predicates OEAnd unspecifiedChiralBond(isChiralBond,notBondStereoSpecified); OEIter mol; OEIter atom; OEIter bond; unsigned int centerCt; for(mol = ifs.GetMolBases();mol;++mol) { OEPerceiveChiral(mol); atom = mol->GetAtoms(unspecifiedChiralAtom); bond = mol->GetBonds(unspecifiedChiralBond); centerCt = 0; for(;atom;++atom) ++centerCt; for(;bond;++bond) ++centerCt; if(centerCt > maxCenters) { ofs << mol; continue; } atom.ToFirst(); bond.ToFirst(); PrepareStereoCenters(atom,bond); if(!flip(ofs,mol,atom,bond)) ofs << mol; } return 0; }