So the desired output is 1,2,3,4,5 instead of 3,3,3,4,5? If so, isn't SetImplicitValence what you are looking for?
>>> mol = pybel.readstring("smi", "[AlH3]").OBMol >>> mol.DeleteHydrogens() True >>> print pybel.Molecule(mol).write("smi") [AlH3] >>> print mol.GetAtom(1).GetImplicitValence() # 3 3 >>> mol.GetAtom(1).SetImplicitValence(2) >>> print pybel.Molecule(mol).write("smi") [AlH2] In your example, you were using Begin/EndModify. Unfortunately, EndModify() unsets ImplicitValencePerceived so that the atom typer is called again next time a "valence" is requested: >>> mol.BeginModify() >>> mol.EndModify() >>> print pybel.Molecule(mol).write("smi") [AlH3] ...but never fear, we can override this by adding a mol.SetImplicitValencePerceived() immediately after the EndModify(). The [AlH2] is then retained. - Noel On 20 March 2013 18:20, Craig James <cja...@emolecules.com> wrote: > Hi Noel, > > > > On Tue, Mar 19, 2013 at 3:16 PM, Noel O'Boyle <baoille...@gmail.com> wrote: >> >> I believe that the key value is the _impval property on an OBAtom, >> which is assigned by the atomtyper. Can you ask your program to print >> out the values after the EndModify() using atom->GetImplicitValence()? > > > It looks like your analysis is spot on. Here is output of the program (not > the original one, this is much simpler, see below): > > molecule starts with 4 atoms. > delete H, idx = 4 > delete H, idx = 3 > delete H, idx = 2 > molecule now has 1 atoms. > [AlH3] > add H, idx = 2, molecule now has 2 atoms, _impval = 3 > [AlH3] > add H, idx = 3, molecule now has 3 atoms, _impval = 3 > [AlH3] > add H, idx = 4, molecule now has 4 atoms, _impval = 3 > [AlH3] > add H, idx = 5, molecule now has 5 atoms, _impval = 4 > [AlH4] > add H, idx = 6, molecule now has 6 atoms, _impval = 5 > [AlH5] > > What's the solution? I can't find any method on the atom or bond object > that will force it to reset its _impval. > > Thanks, > Craig > > #include <sstream> > > #include <openbabel/babelconfig.h> > #include <openbabel/mol.h> > #include <openbabel/obconversion.h> > > using namespace std; > using namespace OpenBabel; > > static string test_mol > ( > "\n" > " OpenBabel03191316172D\n" > "\n" > " 4 3 0 0 0 0 0 0 0 0999 V2000\n" > " 0.0000 0.0000 0.0000 Al 0 0 0 0 0 0 0 0 0 0 0 0\n" > " 0.0000 0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0\n" > " 0.0000 0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0\n" > " 0.0000 0.0000 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0\n" > " 1 2 1 0 0 0 0\n" > " 1 3 1 0 0 0 0\n" > " 1 4 1 0 0 0 0\n" > "M END\n" > "$$$$\n" > ); > > int main(int argc,char **argv) > { > OBAtom *atom; > vector<OBAtom*> delete_h; > vector<OBAtom*>::iterator ai; > > OBMol *pmol = new OBMol; > OBConversion conv(&cin, &cout); > conv.SetInAndOutFormats("sdf", "smi"); > > pmol->Clear(); > conv.ReadString(pmol, test_mol); > pmol->BeginModify(); > > cout << "molecule starts with " << pmol->NumAtoms() << " atoms.\n"; > for (atom = pmol->BeginAtom(ai); atom; atom = pmol->NextAtom(ai)) { > if (atom->GetAtomicNum() == 1) > delete_h.push_back(atom); > } > for (ai = delete_h.end() - 1; ai >= delete_h.begin(); ai--) { > atom = *ai; > cout << "delete H, idx = " << atom->GetIdx() << "\n"; > pmol->DeleteAtom(atom); > } > cout << "molecule now has " << pmol->NumAtoms() << " atoms.\n"; > pmol->EndModify(); > conv.Write(pmol); > > for (int i = 2; i <= 6; i++) { > pmol->BeginModify(); > atom = pmol->NewAtom(i); > atom->SetAtomicNum(1); > pmol->AddBond(1, i, 1); > pmol->EndModify(); > cout << "add H, idx = " << i <<", molecule now has " > << pmol->NumAtoms() << " atoms, _impval = " > << pmol->GetAtom(1)->GetImplicitValence() << "\n"; > conv.Write(pmol); > } > } > ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_mar _______________________________________________ OpenBabel-Devel mailing list OpenBabel-Devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openbabel-devel