• RE: normalise hydrogen position

    For anyone who has the same problem, here is another possible implementation into a substructure search:


    import numpy as np
    import ccdc.search

    # normalised bond lengths between hydrogen and C, N or O (same as in ConQuest)
    h_dict = {'C': 1.089, 'N': 1.015, 'O': 0.993}

    def norm(v):
        """ calculates the norm of a vector """
        return np.sqrt(np.dot(v, v))

    def angle(a, b, c):
        """ angle between 3 points with b in the center """
        ba = a - b
        bc = c - b
        x = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))
        return np.degrees(np.arccos(x))

    def h_correction(d, h, type):
        """ Correcting length of bond between hydrogen and C, O or N"""
        ha = h - a
        dis = norm(ha)
        ha_corrected = (ha / dis) * h_dict[type]
        h_corrected = a + ha_corrected
        return h_corrected

    # preparing search with aliphatic hydroxyl as donor and oxygen or nitrogen as acceptor
    search = ccdc.search.SubstructureSearch()
    don_sub = ccdc.search.SMARTSSubstructure('[CX4][OX2][H]')
    acc_sub = ccdc.search.SMARTSSubstructure('[O,N]')
    don_sub_id = search.add_substructure(don_sub)
    acc_sub_id = search.add_substructure(acc_sub)

    # constraining distance between donor and acceptor atom to 5 A
    search.add_distance_constraint('DIST1', don_sub_id, 1, acc_sub_id, 0, (0.0, 5.0), 'Intermolecular')

    # constraining angle involving donor, hydrogen and acceptor atom between 100 and 180
    search.add_angle_constraint('ANG1', don_sub_id, 1, don_sub_id, 2, acc_sub_id, 0, (100.0, 180.0))

    # using only high quality data
    search.settings.has_3d_coordinates = True
    search.settings.only_organic = True
    search.settings.no_errors = True
    search.settings.not_polymeric = True
    search.settings.no_disorder = 'Non-hydrogen'
    search.settings.max_r_factor = 5.0

    # starting search
    hits = search.search()

    # empty lists for data
    dists = []
    angles = []
    errors = []

    # analysing hits
    for hit in hits:
        # some entries miss the hydrogen position, so we need to try
            atoms = hit.match_atoms()
            # getting coordinates (atom index according to queries --> [CX4][OX2][H] - [O,N] --> [0][1][2] - [3])
            donor = np.array(atoms[1].coordinates[:])
            hydrogen = np.array(atoms[2].coordinates[:])
            acceptor = np.array(atoms[3].coordinates[:])
            # correcting hydrogen position for angle calculation
            hydrogen = h_correction(donor, hydrogen, atoms[1].atomic_symbol)
            ang = angle(acceptor, hydrogen, donor)
            # keeping hbonds with angle of at least 120
            if ang >= 120:
        # if something doesnt work in the try statement save the identifier


    I hope that helps,


  • RE: normalise hydrogen position

    Dear Richard,

    thanks for your reply. I will implement your suggestion into my workflow.

    Best wishes,


  • normalise hydrogen position


    I would like to use the python csd api for hydrogen bond geometry analysis. In ConQuest is an option for searching hydrogen normalised entries. I can not find this option in the python substructure search. I only found an option to normalise hydrogens of molecules but that makes everything rather complicated. Did I miss here something for performing this analysis on normalised entries?

    Thanks in advance for any suggestion,