From 2214bbb03dddb83633b8008522a3b30834d858d5 Mon Sep 17 00:00:00 2001 From: Prabindh Sundareson Date: Wed, 3 Jan 2024 11:01:18 +0000 Subject: [PATCH] Fix leak in Vina::m_scoring_function reported by valgrind --- src/lib/scoring_function.h | 25 +++++++++++++++++++++++-- src/lib/vina.cpp | 32 +++++++++++++++----------------- src/lib/vina.h | 3 ++- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/lib/scoring_function.h b/src/lib/scoring_function.h index b969ac8f..6aed8ba1 100644 --- a/src/lib/scoring_function.h +++ b/src/lib/scoring_function.h @@ -38,7 +38,10 @@ enum scoring_function_choice {SF_VINA, SF_AD42, SF_VINARDO}; class ScoringFunction { public: - ScoringFunction() { } + ScoringFunction() { + m_num_potentials = 0; + m_num_conf_independents = 0; + } ScoringFunction(const scoring_function_choice sf_choice, const flv& weights){ switch (sf_choice) { @@ -94,7 +97,25 @@ class ScoringFunction { m_num_conf_independents = m_conf_independents.size(); m_weights = weights; }; - ~ScoringFunction() { } + void Destroy() + { + for (auto p : m_potentials) + { + delete p; + } + m_potentials.clear(); + m_num_potentials = 0; + for (auto p : m_conf_independents) + { + delete p; + } + m_conf_independents.clear(); + m_num_conf_independents = 0; + } + ~ScoringFunction() { + Destroy(); + } + fl eval(atom& a, atom& b, fl r) const{ // intentionally not checking for cutoff fl acc = 0; VINA_FOR (i, m_num_potentials) diff --git a/src/lib/vina.cpp b/src/lib/vina.cpp index aaf5f14c..150f47fb 100644 --- a/src/lib/vina.cpp +++ b/src/lib/vina.cpp @@ -81,7 +81,7 @@ void Vina::set_receptor(const std::string& rigid_name, const std::string& flex_n } // CONDITIONS 4, 5, 6, 7 (rigid_name and flex_name are empty strings per default) - m_receptor = parse_receptor_pdbqt(rigid_name, flex_name, m_scoring_function.get_atom_typing()); + m_receptor = parse_receptor_pdbqt(rigid_name, flex_name, m_scoring_function->get_atom_typing()); m_model = m_receptor; m_receptor_initialized = true; @@ -97,7 +97,7 @@ void Vina::set_ligand_from_string(const std::string& ligand_string) { exit(EXIT_FAILURE); } - atom_type::t atom_typing = m_scoring_function.get_atom_typing(); + atom_type::t atom_typing = m_scoring_function->get_atom_typing(); if (!m_receptor_initialized) { // This situation will happen if we don't need a receptor and we are using affinity maps @@ -113,7 +113,7 @@ void Vina::set_ligand_from_string(const std::string& ligand_string) { m_model.append(parse_ligand_pdbqt_from_string(ligand_string, atom_typing)); // Because we precalculate ligand atoms interactions - precalculate_byatom precalculated_byatom(m_scoring_function, m_model); + precalculate_byatom precalculated_byatom(*m_scoring_function, m_model); // Check that all atom types are in the grid (if initialized) if (m_map_initialized) { @@ -142,7 +142,7 @@ void Vina::set_ligand_from_string(const std::vector& ligand_string) exit(EXIT_FAILURE); } - atom_type::t atom_typing = m_scoring_function.get_atom_typing(); + atom_type::t atom_typing = m_scoring_function->get_atom_typing(); if (!m_receptor_initialized) { // This situation will happen if we don't need a receptor and we are using affinity maps @@ -158,7 +158,7 @@ void Vina::set_ligand_from_string(const std::vector& ligand_string) m_model.append(parse_ligand_pdbqt_from_string(ligand_string[i], atom_typing)); // Because we precalculate ligand atoms interactions - precalculate_byatom precalculated_byatom(m_scoring_function, m_model); + precalculate_byatom precalculated_byatom(*m_scoring_function, m_model); // Check that all atom types are in the grid (if initialized) if (m_map_initialized) { @@ -280,9 +280,8 @@ void Vina::set_ad4_weights(double weight_ad4_vdw , double weight_ad4_hb, } void Vina::set_forcefield() { - ScoringFunction scoring_function(m_sf_choice, m_weights); - // Store in Vina object - m_scoring_function = scoring_function; + // Store in Vina object + m_scoring_function = std::make_shared(m_sf_choice, m_weights); } std::vector Vina::grid_dimensions_from_ligand(double buffer_size) { @@ -335,7 +334,7 @@ void Vina::compute_vina_maps(double center_x, double center_y, double center_z, vec center(center_x, center_y, center_z); const fl slope = 1e6; // FIXME: too large? used to be 100 szv atom_types; - atom_type::t atom_typing = m_scoring_function.get_atom_typing(); + atom_type::t atom_typing = m_scoring_function->get_atom_typing(); /* Atom types initialization If a ligand was defined before, we only use those present in the ligand @@ -344,7 +343,7 @@ void Vina::compute_vina_maps(double center_x, double center_y, double center_z, if (m_ligand_initialized) atom_types = m_model.get_movable_atom_types(atom_typing); else - atom_types = m_scoring_function.get_atom_types(); + atom_types = m_scoring_function->get_atom_types(); // Grid dimensions VINA_FOR_IN(i, gd) { @@ -361,7 +360,7 @@ void Vina::compute_vina_maps(double center_x, double center_y, double center_z, } // Initialize the scoring function - precalculate precalculated_sf(m_scoring_function); + precalculate precalculated_sf(*m_scoring_function); // Store it now in Vina object because of non_cache m_precalculated_sf = precalculated_sf; @@ -407,7 +406,7 @@ void Vina::load_maps(std::string maps) { // Check that all the affinity map are present for ligands/flex residues (if initialized already) if (m_ligand_initialized) { - atom_type::t atom_typing = m_scoring_function.get_atom_typing(); + atom_type::t atom_typing = m_scoring_function->get_atom_typing(); szv atom_types = m_model.get_movable_atom_types(atom_typing); if (m_sf_choice == SF_VINA || m_sf_choice == SF_VINARDO) { @@ -430,12 +429,12 @@ void Vina::write_maps(const std::string& map_prefix, const std::string& gpf_file } szv atom_types; - atom_type::t atom_typing = m_scoring_function.get_atom_typing(); + atom_type::t atom_typing = m_scoring_function->get_atom_typing(); if (m_ligand_initialized) atom_types = m_model.get_movable_atom_types(atom_typing); else - atom_types = m_scoring_function.get_atom_types(); + atom_types = m_scoring_function->get_atom_types(); if (m_sf_choice == SF_VINA || m_sf_choice == SF_VINARDO) { doing("Writing Vina maps", m_verbosity, 0); @@ -721,7 +720,7 @@ std::vector Vina::score(double intramolecular_energy) { lig_intra = m_model.evali(m_precalculated_byatom, authentic_v); // [2] ligand_i -- ligand_i intra = flex_grids + intra_pairs + lig_intra; // Total - total = m_scoring_function.conf_independent(m_model, inter + intra - intramolecular_energy); // we pass intermolecular energy from the best pose + total = m_scoring_function->conf_independent(m_model, inter + intra - intramolecular_energy); // we pass intermolecular energy from the best pose // Torsion, we want to know how much torsion penalty was added to the total energy conf_independent = total - (inter + intra - intramolecular_energy); } else { @@ -735,7 +734,7 @@ std::vector Vina::score(double intramolecular_energy) { lig_intra = m_model.evali(m_precalculated_byatom, authentic_v); // [2] ligand_i -- ligand_i intra = flex_grids + intra_pairs + lig_intra; // Torsion - conf_independent = m_scoring_function.conf_independent(m_model, 0); // [3] we can pass e=0 because we do not modify the energy like in vina + conf_independent = m_scoring_function->conf_independent(m_model, 0); // [3] we can pass e=0 because we do not modify the energy like in vina // Total total = inter + conf_independent; // (+ intra - intra) } @@ -1033,7 +1032,6 @@ Vina::~Vina() { // scoring function scoring_function_choice m_sf_choice; flv m_weights; - ScoringFunction m_scoring_function; precalculate_byatom m_precalculated_byatom; precalculate m_precalculated_sf; // maps diff --git a/src/lib/vina.h b/src/lib/vina.h index a44cf9b3..622b6bff 100644 --- a/src/lib/vina.h +++ b/src/lib/vina.h @@ -53,6 +53,7 @@ #include "utils.h" #include "scoring_function.h" #include "precalculate.h" +#include class vina_runtime_error : public std::exception { @@ -162,7 +163,7 @@ class Vina { // scoring function scoring_function_choice m_sf_choice; flv m_weights; - ScoringFunction m_scoring_function; + std::shared_ptr m_scoring_function; precalculate_byatom m_precalculated_byatom; precalculate m_precalculated_sf; // maps