When developing a benchmarking set, a user may wish to select entries with a certain set of interactions. We provide the scoring function used by the AutoDOCK vina software package to help users select desirable interactions.

Note: You will need to include the additional file: <lemon/xscore.hpp> to have access to these features.

struct VinaScore

An object which represents the components of XScore/Vina’s scoring function

The XScore/Vina scoring function is divided into five components: two gaussian functions, hydrophobic interactions, repulsive forces, and hydrogen bonding.

template<typename Container>
VinaScore xscore::lemon::vina_score(const chemfiles::Frame &frame, size_t ligid, Container recid, double cutoff = DEFAULT_INTERACTION_DISTANCE)

XScore is a ‘docking’ scoring function used to evaluate compound-protein interactions

The docking program AutoDOCK Vina utilizes a modified version of the XScore scoring function to evaluate the fit of a compound-protein interaction. Since the original XScore program is not open source, we’ve included a copy of the Vina version of this scoring function.


The five components of Vina/XScore’s scoring function.

  • [in] frame: The frame for which the ligand-protein score will be calculated

  • [in] ligid: The residue ID for the ligand in the entry

  • [in] recid: The residue IDs for the protein in the entry

  • [in] cutoff: The interaction distance cutoff between ligand and protein



auto worker = [](const chemfiles::Frame& entry,
                 const std::string& pdbid) -> std::string {

    // Selection phase= 
    auto smallm = lemon::select::small_molecules(entry);
    if (smallm.empty()) {
        return std::string("");

    // Pruning phase
    lemon::prune::identical_residues(entry, smallm);
    lemon::prune::cofactors(entry, smallm, lemon::common_cofactors);
    lemon::prune::cofactors(entry, smallm, lemon::common_fatty_acids);

    // Output phase
    const auto& residues = entry.topology().residues();
    std::list<size_t> proteins;
    for (size_t i = 0; i < entry.topology().residues().size(); ++i) {

    std::string result;
    for (auto smallm_id : smallm) {
        auto prot_copy = proteins;

        lemon::prune::keep_interactions(entry, smallm, prot_copy, lemon::xscore::DEFAULT_INTERACTION_DISTANCE);
        prot_copy.erase(std::remove(prot_copy.begin(), prot_copy.end(), smallm_id), prot_copy.end());

        auto vscore =
            lemon::xscore::vina_score(entry, smallm_id, prot_copy);

        result += pdbid + "\t" +
            residues[smallm_id].name() + "\t" +
            std::to_string(vscore.g1) + "\t" +
            std::to_string(vscore.g2) + "\t" +
            std::to_string(vscore.hydrogen) + "\t" +
            std::to_string(vscore.hydrophobic) + "\t" +
            std::to_string(vscore.rep) + "\n";

    return result;


import lemon

class MyWorkflow(lemon.Workflow):
    def worker(self, entry, pdbid):
        import lemon

        # Selection phase
        smallm = lemon.select_small_molecules(entry, lemon.small_molecule_types, 10)
        if (len(smallm) == 0):
            return ""

        # Pruning phase
        lemon.prune_identical_residues(entry, smallm)
        lemon.prune_cofactors(entry, smallm, lemon.common_cofactors)
        lemon.prune_cofactors(entry, smallm, lemon.common_fatty_acids)

        # Output phase
        prot = []
        residues = entry.topology().residues()
        for resid in range(0, len(residues)):
        result = ""
        for smallm_id in smallm:
            lig_copy = [smallm_id]

            # Hack to remove self
            prot_copy = lemon.remove_interactions(entry, prot, lig_copy, 0.001)

            vscore = lemon.vina_score(entry, smallm_id, prot_copy, 8.0)

            result += pdbid + "\t" 
            result += residues[smallm_id].name() + "\t" 
            result += str(vscore.g1) + "\t" 
            result += str(vscore.g2) + "\t"
            result += str(vscore.hydrogen) + "\t" 
            result += str(vscore.hydrophobic) + "\t"
            result += str(vscore.rep) + "\n"

        return result
    def finalize(self):