why the default h-bond distance range is negative (-5.0, 0.0)?

i got two different result ,when i use two different distance range (-5.0, 0.0) and (0.0, 5.0):

 

cryst_mol = csd_reader.crystal('TEHREG')
crystall_hbond = cryst_mol.hbonds(distance_range=(0.0, 5.0))
crystall_hbond
Out:
(HBond(Atom(O2)-Atom(H21)-Atom(N2)),
HBond(Atom(N1)-Atom(H1)-Atom(O3)),
HBond(Atom(N1)-Atom(H1)-Atom(O4)),
HBond(Atom(N1)-Atom(H1)-Atom(O4)),
HBond(Atom(O1)-Atom(H21)-Atom(N2)),
HBond(Atom(O2)-Atom(H21)-Atom(N2)),
HBond(Atom(N2)-Atom(H21)-Atom(N3)),
HBond(Atom(N2)-Atom(H21)-Atom(F4?)),
HBond(Atom(N2)-Atom(H21)-Atom(F6?)))

crystall_hbond1 = cryst_mol.hbonds(distance_range=(-5.0, 0.0))
crystall_hbond1
Out:
(HBond(Atom(O1)-Atom(H21)-Atom(N2)), HBond(Atom(O2)-Atom(H22)-Atom(N4)), HBond(Atom(N1)-Atom(H1)-Atom(N3)))

One of the options to the detection of HBonds either in the crystal or in the molecule is whether or not the distance range is absolute or Van der Waals corrected, i.e. a distance minus the sum of the radii of the atoms concerned.  This is the default.  We can see this more clearly in the following script:

from ccdc import io

csd = io.EntryReader('csd')
cry = csd.crystal('TEHREG')

def vdw_correct(hb):
    return hb.length - hb.atoms[0].vdw_radius - hb.atoms[-1].vdw_radius

hbonds_vdw = cry.hbonds(distance_range=(-5, 0))
for hb in hbonds_vdw:
    print hb, hb.length, vdw_correct(hb)

hbonds_vdw = cry.hbonds(distance_range=(0, 5))
for hb in hbonds_vdw:
    print hb, hb.length, vdw_correct(hb)

If you prefer, you may calculate HBonds with the absolute distance:

hbonds_abs = cry.hbonds(distance_range=(0, 5), vdw_corrected=False)

I hope this is helpful

Best wishes

Richard

Thanks for your detailed answer. But there is one more question that the hb.length is different when I use the two distance range (-5.0, 0.0) and (0.0, 5.0). For example:

 

 

from ccdc import io
csd = io.EntryReader('csd')
cry = csd.crystal('TEHREG')

def vdw_correct(hb):
return hb.length - hb.atoms[0].vdw_radius - hb.atoms[-1].vdw_radius

hbonds_vdw = cry.hbonds(distance_range=(-5, 0))
for hb in hbonds_vdw:
print(hb, hb.length, hb.atoms[0].vdw_radius, hb.atoms[-1].vdw_radius, vdw_correct(hb))

Out:
HBond(Atom(O1)-Atom(H21)-Atom(N2)) 2.06647597521 1.52 1.55 -1.00352402479
HBond(Atom(O2)-Atom(H22)-Atom(N4)) 2.13782138621 1.52 1.55 -0.932178613791 HBond(Atom(N1)-Atom(H1)-Atom(N3)) 2.21193130874 1.55 1.55 -0.888068691263

hbonds_vdw = cry.hbonds(distance_range=(0, 5))
for hb in hbonds_vdw:
print(hb, hb.length, hb.atoms[0].vdw_radius, hb.atoms[-1].vdw_radius, vdw_correct(hb))

Out:
HBond(Atom(O2)-Atom(H21)-Atom(N2)) 4.83753829295 1.52 1.55 1.76753829295 HBond(Atom(N1)-Atom(H1)-Atom(O3)) 5.41035345957 1.55 1.52 2.34035345957 HBond(Atom(N1)-Atom(H1)-Atom(O4)) 5.20008796325 1.55 1.52 2.13008796325 HBond(Atom(N1)-Atom(H1)-Atom(O4)) 7.67608495183 1.55 1.52 4.60608495183 HBond(Atom(O1)-Atom(H21)-Atom(N2)) 6.12238515037 1.52 1.55 3.05238515037 HBond(Atom(O2)-Atom(H21)-Atom(N2)) 5.56704927369 1.52 1.55 2.49704927369 HBond(Atom(N2)-Atom(H21)-Atom(N3)) 7.50483415478 1.55 1.55 4.40483415478 HBond(Atom(N2)-Atom(H21)-Atom(F4?)) 5.66590719935 1.55 1.47 2.64590719935 HBond(Atom(N2)-Atom(H21)-Atom(F6?)) 4.717808386 1.55 1.47 1.697808386

 

the length of HBond(Atom(O1)-Atom(H21)-Atom(N2)) is different

Why is this?the calculation criterion of H-bond found in google is that the distance between Acceptor and Donor is less or equal to a cutoff (i.e. 3.5Å or 5.0Å relaxed) and the angle D-H-A  is more or equal to 120°.   Is the calculation of the length of the hydrogen bond based on atomic coordinates? or other algorithm ?

Best wishes

This is because the HBond may come from different symmetry transformed copies of the unit cell molecule.  The API seeks to provide only a single copy of each HBond, for example O1-H21-N2, though this behaviour can be changed.  To see all HBonds,

hbonds = cry.hbonds(distance_range=(0, 5),  unique=False)
for hb in hbonds:
    print hb, hb.length, vdw_correct(hb), hb.symmetry_operators[-1]

So the O1-H21-N2 has a symmetry operator of  1-x,1-y,1-z.

In the first example with a distance range of (-5, 0) O1-H21-N2 has a symmetry operator of x,y,z so they are the unit cell atoms.  It does not appear in the second list because the vdw-corrected distance is less than 0,

from ccdc.descriptors import MolecularDescriptors as MD
mol = cry.molecule

MD.atom_distance(mol.atom('O1'), mol.atom('N2)) - mol.atom('O1').vdw_radius - mol.atom('N2').vdw_radius

-0.11999

You can check other distances by instantiating the symmetry transformed molecule:

symm_mol = cry.symmetric_molecule('1-x,1-y,1-z')

 

Best wishes

Richard

 

Dear Richard,

thanks for your help! I can confirm that the patch solves the problem.

You must be signed in to post in this forum.