// // Copyright (C) 2013 Greg Landrum // // @@ All Rights Reserved @@ // This file is part of the RDKit. // The contents are covered by the terms of the BSD license // which is included in the file license.txt, found at the root // of the RDKit source tree. // #include #include #include #include #include #include namespace RDKit { namespace MolOps { ROMol *renumberAtoms(const ROMol &mol,const std::vector &newOrder){ unsigned int nAts=mol.getNumAtoms(); PRECONDITION(newOrder.size()==nAts,"bad newOrder size"); std::vector revOrder(nAts); for(unsigned int nIdx=0;nIdxnAts){ throw ValueErrorException("idx value exceeds numAtoms"); } revOrder[oIdx]=nIdx; } // ------ // newOrder[i] : which atom should be in position i of the new mol // revOrder[i] : where atom i of the original mol landed in the new mol RWMol *res=new RWMol(); // copy over the atoms: for(unsigned int nIdx=0;nIdxcopy(); res->addAtom(nAtom,false,true); // take care of atom-numbering-dependent properties: INT_VECT nAtoms; if(nAtom->getPropIfPresent(common_properties::_ringStereoAtoms, nAtoms)){ // FIX: ought to be able to avoid this copy. BOOST_FOREACH(int &val,nAtoms){ if(val<0){ val=-1*(revOrder[(-val-1)]+1); } else { val=revOrder[val-1]+1; } } nAtom->setProp(common_properties::_ringStereoAtoms,nAtoms,true); } } // now the bonds: for(ROMol::ConstBondIterator bi=mol.beginBonds(); bi!=mol.endBonds();++bi){ const Bond *oBond=(*bi); Bond *nBond=oBond->copy(); nBond->setBeginAtomIdx(revOrder[oBond->getBeginAtomIdx()]); nBond->setEndAtomIdx(revOrder[oBond->getEndAtomIdx()]); res->addBond(nBond,true); // take care of atom-numbering-dependent properties: BOOST_FOREACH(int &idx,nBond->getStereoAtoms()){ idx=revOrder[idx]; } } // Conformers: for(ROMol::ConstConformerIterator oConf=mol.beginConformers(); oConf!=mol.endConformers(); ++oConf){ Conformer *nConf=new Conformer(nAts); for(unsigned int i=0;isetAtomPos(i,(*oConf)->getAtomPos(newOrder[i])); } nConf->setId((*oConf)->getId()); res->addConformer(nConf); } // update the ring info: const RingInfo *oRings=mol.getRingInfo(); if(oRings){ RingInfo *nRings=res->getRingInfo(); nRings->reset(); nRings->initialize(); for(unsigned int i=0;inumRings();++i){ const INT_VECT &oRing=oRings->atomRings()[i]; INT_VECT nRing(oRing.size()); for(unsigned int j=0;jaddRing(nRing,oRings->bondRings()[i]); } } return dynamic_cast(res); } }; // end of namespace MolOps }; // end of namespace RDKit