FixHydrogenAngles(done[],atm,lastatm) { // 'done' is a table that flags atoms which have already been analyzed. // The analysis starts at 'atm' and should not recurse to 'lastatm'. // First make sure that each atom is analyzed only once: if (done[atm]) return done[atm]=1 // Maybe we will recurse to 'nextatm', but not yet nextatm=NONE // Store the bound hydrogens in 'hydtab' and their number in 'hydrogens' GetBoundHydrogens(hydtab,&hydrogens,atm) if (hydrogens==4) { // Handle four hydrogens like methane with two constraints FixAngle(hydtab[0],atm,hydtab[1]) FixAngle(hydtab[2],atm,hydtab[3]) } if (hydrogens==3) { // Handle three hydrogens like CH3,NH3 groups with three constraints FixAngle(hydtab[0],atm,hydtab[1]) FixAngle(hydtab[1],atm,hydtab[2]) FixAngle(hydtab[2],atm,hydtab[0]) // Don't recurse if the heavy atom bound to atm is sp3 with <=1 hydrogens nextatm=BoundHeavyAtom(atm) if (nextatm!=NONE and BoundHydrogens(nextatm)<=1 and Bonds(nextatm)>3) nextatm=NONE } if (hydrogens==2) { if (Bonds(atm)>3) { // Two hydrogens bound to sp3 atom. These need constraints to the next heavy atom: nextatm = A heavy atom bound to atm, which is not lastatm, which has <3 hydrogens, which does not already have an angle constraint atm-nextatm-x, and which has the highest score. The score is 3 if nextatm has two bound hydrogens (it's best if we continue along a -CH2- chain), 2 if it has 0 hydrogens (but also OK to end at an atom without hydrogens), 1 if it has 1 hydrogen and 3 bonds, otherwise 0. } if (nextatm!=NONE) { // Found a bound heavy atom that can take the constraints FixAngle(hydtab[0],atm,nextatm) FixAngle(hydtab[1],atm,nextatm) // Again, don't recurse if nextatm is sp3 with <=1 hydrogens, these are handled later if (BoundHydrogens(nextatm)<=1 and Bonds(nextatm)>3) nextatm=NONE } else { // Two hydrogens bound to sp2 atom (or no nextatm found), these can safely be coupled FixAngle(hydtab[0],atm,hydtab[1]) } } if (hydrogens==1) { // A single hydrogen gets a single constraint. Find best partner atom. nextatm = A heavy atom bound to atm, which has <3 hydrogens and the best score. The score is -(number of bound hydrogens + number of angle constraints nextatm-x-y)*4. If nextatm==lastatm or there already is an angle constraint atm-nextatm-x, then score=score-20. If nextatm is not in the same residue as atm, then score=score-10. if (nextatm!=NONE) FixAngle(hydtab[0],atm,nextatm) } // Recurse if it makes sense if (nextatm!=NONE) FixHydAngles(done,nextatm,atm) }