OK my attempt, input pdb created in pymol with fab AVGLWPT , AVGLWPT , hydro=0
and saved as avgwpt.pdb
:
ATOM 1 N ALA 1 67.846 51.727 15.161 1.00 0.00 N
ATOM 2 CA ALA 1 68.522 53.021 15.161 1.00 0.00 C
ATOM 3 C ALA 1 70.022 52.847 15.161 1.00 0.00 C
ATOM 4 O ALA 1 70.553 51.730 15.150 1.00 0.00 O
ATOM 5 CB ALA 1 68.014 53.813 16.378 1.00 0.00 C
ATOM 6 N VAL 2 70.773 53.896 15.173 1.00 0.00 N
ATOM 7 CA VAL 2 72.223 53.728 15.173 1.00 0.00 C
ATOM 8 C VAL 2 72.922 55.066 15.188 1.00 0.00 C
ATOM 9 O VAL 2 72.296 56.134 15.198 1.00 0.00 O
ATOM 10 CB VAL 2 72.665 52.877 13.916 1.00 0.00 C
ATOM 11 CG1 VAL 2 74.193 52.762 13.664 1.00 0.00 C
ATOM 12 CG2 VAL 2 72.143 51.420 13.932 1.00 0.00 C
ATOM 13 N GLY 3 74.212 55.098 15.190 1.00 0.00 N
ATOM 14 CA GLY 3 74.888 56.392 15.204 1.00 0.00 C
ATOM 15 C GLY 3 76.388 56.218 15.203 1.00 0.00 C
ATOM 16 O GLY 3 76.917 55.104 15.192 1.00 0.00 O
ATOM 17 N LEU 4 77.138 57.267 15.215 1.00 0.00 N
ATOM 18 CA LEU 4 78.589 57.099 15.215 1.00 0.00 C
ATOM 19 C LEU 4 79.288 58.437 15.230 1.00 0.00 C
ATOM 20 O LEU 4 78.660 59.507 15.241 1.00 0.00 O
ATOM 21 CB LEU 4 79.040 56.251 13.992 1.00 0.00 C
ATOM 22 CG LEU 4 78.445 54.825 13.832 1.00 0.00 C
ATOM 23 CD1 LEU 4 79.094 54.113 12.637 1.00 0.00 C
ATOM 24 CD2 LEU 4 78.610 53.968 15.098 1.00 0.00 C
ATOM 25 N TRP 5 80.577 58.469 15.232 1.00 0.00 N
ATOM 26 CA TRP 5 81.254 59.763 15.246 1.00 0.00 C
ATOM 27 C TRP 5 82.754 59.589 15.245 1.00 0.00 C
ATOM 28 O TRP 5 83.281 58.478 15.233 1.00 0.00 O
ATOM 29 CB TRP 5 80.817 60.551 16.512 1.00 0.00 C
ATOM 30 CG TRP 5 79.341 60.958 16.536 1.00 0.00 C
ATOM 31 CD1 TRP 5 78.304 60.258 17.187 1.00 0.00 C
ATOM 32 CD2 TRP 5 78.731 62.003 15.872 1.00 0.00 C
ATOM 33 CE2 TRP 5 77.340 61.929 16.130 1.00 0.00 C
ATOM 34 CE3 TRP 5 79.257 63.017 15.031 1.00 0.00 C
ATOM 35 NE1 TRP 5 77.049 60.848 16.950 1.00 0.00 N
ATOM 36 CZ2 TRP 5 76.464 62.876 15.556 1.00 0.00 C
ATOM 37 CZ3 TRP 5 78.372 63.946 14.482 1.00 0.00 C
ATOM 38 CH2 TRP 5 76.996 63.879 14.742 1.00 0.00 C
ATOM 39 N PRO 6 83.505 60.638 15.257 1.00 0.00 N
ATOM 40 CA PRO 6 84.959 60.560 15.257 1.00 0.00 C
ATOM 41 C PRO 6 85.498 60.036 16.599 1.00 0.00 C
ATOM 42 O PRO 6 84.724 59.735 17.507 1.00 0.00 O
ATOM 43 CB PRO 6 85.354 62.018 14.978 1.00 0.00 C
ATOM 44 CG PRO 6 84.201 62.829 15.588 1.00 0.00 C
ATOM 45 CD PRO 6 82.967 61.980 15.271 1.00 0.00 C
ATOM 46 N THR 7 86.770 59.913 16.774 1.00 0.00 N
ATOM 47 CA THR 7 87.263 59.414 18.054 1.00 0.00 C
ATOM 48 C THR 7 88.771 59.342 18.062 1.00 0.00 C
ATOM 49 O THR 7 89.436 59.668 17.100 1.00 0.00 O
ATOM 50 CB THR 7 86.639 58.014 18.376 1.00 0.00 C
ATOM 51 CG2 THR 7 87.080 57.358 19.702 1.00 0.00 C
ATOM 52 OG1 THR 7 85.224 58.110 18.479 1.00 0.00 O
TER
END
pic :

code :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
molecule create in pymol with fab AVGLWPT , AVGLWPT , hydro=0
"""
import Bio
print('########## Biopython VERSION ##########################################')
print('\n\n BIOPYTHON_VERSION : ', Bio.__version__)
print('###################################################################')
from Bio.PDB import (
PDBParser,
Atom,
PDBIO
)
structure_code = 'avgwpt'
structure_name = structure_code
parser_pdb= PDBParser(QUIET=False) ### shows warnings
structure_whole = parser_pdb.get_structure(structure_name, structure_name+".pdb")
last_serial = list(structure_whole.get_atoms())[-1].serial_number
print(" last_serial : ",last_serial)
for model in structure_whole:
for chain in model:
for resi in chain:
print('1 : ', resi)
print('2 : ',resi.id)
try :
print('3 : ',chain[resi.id[1]-1])
doable = True
except :
print('3 : ','residue -1 missing !!!!!!!!!!!!!!!!!!!!!!1')
doable = False
print('4 : ',[i for i in resi.get_atoms()])
if doable:
print('5 : ','ok')
else:
print('5 : ','NO')
if doable:
print(chain[resi.id[1]-1]['C'])
print(chain[resi.id[1]-1]['C'].get_vector(), type(chain[resi.id[1]-1]['C'].get_vector()))
print(chain[resi.id[1]]['N'].get_vector())
c = chain[resi.id[1]-1]['C'].get_vector()
n = chain[resi.id[1]]['N'].get_vector()
ca = chain[resi.id[1]]['CA'].get_vector()
nc = n-c
nca = n-ca
print('vector BN : ', nc)
nc.normalize()
print('vector BN normalize : ', nc)
print('vector B2B : ', nca)
nca.normalize()
print('vector B2B normalize : ', nca)
print('sum of nc + nca : ' , nsum := nc + nca)
nsum.normalize()
nsum**1.023
nsum += n
print(nsum)
print(nsum.get_array(), type(nsum.get_array()))
resi.add(Atom.Atom(name=' H ', coord = nsum.get_array(), bfactor=0., occupancy=1., altloc=' ', fullname=' H ', serial_number = last_serial ,element='H'))
last_serial += 1
io=PDBIO()
io.set_structure(structure_whole )
io.save(structure_name+"_H_added.pdb" , preserve_atom_numbering = True)
output , saved as avgwpt_H_added.pdb
:
ATOM 1 N ALA 1 67.846 51.727 15.161 1.00 0.00 N
ATOM 2 CA ALA 1 68.522 53.021 15.161 1.00 0.00 C
ATOM 3 C ALA 1 70.022 52.847 15.161 1.00 0.00 C
ATOM 4 O ALA 1 70.553 51.730 15.150 1.00 0.00 O
ATOM 5 CB ALA 1 68.014 53.813 16.378 1.00 0.00 C
ATOM 6 N VAL 2 70.773 53.896 15.173 1.00 0.00 N
ATOM 7 CA VAL 2 72.223 53.728 15.173 1.00 0.00 C
ATOM 8 C VAL 2 72.922 55.066 15.188 1.00 0.00 C
ATOM 9 O VAL 2 72.296 56.134 15.198 1.00 0.00 O
ATOM 10 CB VAL 2 72.665 52.877 13.916 1.00 0.00 C
ATOM 11 CG1 VAL 2 74.193 52.762 13.664 1.00 0.00 C
ATOM 12 CG2 VAL 2 72.143 51.420 13.932 1.00 0.00 C
ATOM 52 H VAL 2 70.368 54.810 15.182 1.00 0.00 H
ATOM 13 N GLY 3 74.212 55.098 15.190 1.00 0.00 N
ATOM 14 CA GLY 3 74.888 56.392 15.204 1.00 0.00 C
ATOM 15 C GLY 3 76.388 56.218 15.203 1.00 0.00 C
ATOM 16 O GLY 3 76.917 55.104 15.192 1.00 0.00 O
ATOM 53 H GLY 3 74.741 54.249 15.182 1.00 0.00 H
ATOM 17 N LEU 4 77.138 57.267 15.215 1.00 0.00 N
ATOM 18 CA LEU 4 78.589 57.099 15.215 1.00 0.00 C
ATOM 19 C LEU 4 79.288 58.437 15.230 1.00 0.00 C
ATOM 20 O LEU 4 78.660 59.507 15.241 1.00 0.00 O
ATOM 21 CB LEU 4 79.040 56.251 13.992 1.00 0.00 C
ATOM 22 CG LEU 4 78.445 54.825 13.832 1.00 0.00 C
ATOM 23 CD1 LEU 4 79.094 54.113 12.637 1.00 0.00 C
ATOM 24 CD2 LEU 4 78.610 53.968 15.098 1.00 0.00 C
ATOM 54 H LEU 4 76.733 58.181 15.224 1.00 0.00 H
ATOM 25 N TRP 5 80.577 58.469 15.232 1.00 0.00 N
ATOM 26 CA TRP 5 81.254 59.763 15.246 1.00 0.00 C
ATOM 27 C TRP 5 82.754 59.589 15.245 1.00 0.00 C
ATOM 28 O TRP 5 83.281 58.478 15.233 1.00 0.00 O
ATOM 29 CB TRP 5 80.817 60.551 16.512 1.00 0.00 C
ATOM 30 CG TRP 5 79.341 60.958 16.536 1.00 0.00 C
ATOM 31 CD1 TRP 5 78.304 60.258 17.187 1.00 0.00 C
ATOM 32 CD2 TRP 5 78.731 62.003 15.872 1.00 0.00 C
ATOM 33 CE2 TRP 5 77.340 61.929 16.130 1.00 0.00 C
ATOM 34 CE3 TRP 5 79.257 63.017 15.031 1.00 0.00 C
ATOM 35 NE1 TRP 5 77.049 60.848 16.950 1.00 0.00 N
ATOM 36 CZ2 TRP 5 76.464 62.876 15.556 1.00 0.00 C
ATOM 37 CZ3 TRP 5 78.372 63.946 14.482 1.00 0.00 C
ATOM 38 CH2 TRP 5 76.996 63.879 14.742 1.00 0.00 C
ATOM 55 H TRP 5 81.105 57.620 15.224 1.00 0.00 H
ATOM 39 N PRO 6 83.505 60.638 15.257 1.00 0.00 N
ATOM 40 CA PRO 6 84.959 60.560 15.257 1.00 0.00 C
ATOM 41 C PRO 6 85.498 60.036 16.599 1.00 0.00 C
ATOM 42 O PRO 6 84.724 59.735 17.507 1.00 0.00 O
ATOM 43 CB PRO 6 85.354 62.018 14.978 1.00 0.00 C
ATOM 44 CG PRO 6 84.201 62.829 15.588 1.00 0.00 C
ATOM 45 CD PRO 6 82.967 61.980 15.271 1.00 0.00 C
ATOM 56 H PRO 6 83.072 61.539 15.267 1.00 0.00 H
ATOM 46 N THR 7 86.770 59.913 16.774 1.00 0.00 N
ATOM 47 CA THR 7 87.263 59.414 18.054 1.00 0.00 C
ATOM 48 C THR 7 88.771 59.342 18.062 1.00 0.00 C
ATOM 49 O THR 7 89.436 59.668 17.100 1.00 0.00 O
ATOM 50 CB THR 7 86.639 58.014 18.376 1.00 0.00 C
ATOM 51 CG2 THR 7 87.080 57.358 19.702 1.00 0.00 C
ATOM 52 OG1 THR 7 85.224 58.110 18.479 1.00 0.00 O
ATOM 57 H THR 7 87.409 60.156 16.044 1.00 0.00 H
TER 58 THR 7
END
pic : 
Not sure I got the code above (in question) right, can't read it , had to use comments as trace.
Spent a while banging my head with : HAAD: A Quick Algorithm for Accurate Prediction of Hydrogen Atoms in Protein Structures
and trying to figure out their alghoritm, [code (https://seq2fun.dcmb.med.umich.edu//HAAD/haad.f90) is in FORTRAN90] from the paper , but no luck, if anybody wants to help eplaining this bit:
For constructing the sp2H2 and sp2H1 H-atoms, we first decide on the orientation of the conjugated plane or the aromatic ring with respect to the neighboring heavy atoms; the normal vector of the conjugated plane is determined by taking the cross product of two vectors between the heavy atoms. For the sp2H2 H-atoms (illustrated in Fig. 1b), the normal vector of the conjugated plane is the cross product of the unit vectors B→N and B2→B; then the two H-atoms are placed at positions A1 and H, which are within the conjugated plane respected to the B→N vector with the exact bond angle from CHARMM22 force field. For sp2H1 H-atoms, two conformations are possible. The first is to place the H-atom in the peptide plane as illustrated in Fig. 1b, where A1 and B1 represent the alpha carbon atoms. The position of H in this case is decided by using the same method as the one used to determine the position of the sp2H2 H-atoms while holding the trans-conformation.
it refers to Fig.1 of linked freely available article