diff --git a/modules/mol/alg/pymod/wrap_mol_alg.cc b/modules/mol/alg/pymod/wrap_mol_alg.cc index fd2b9eb2d8fc97c886f0be1f8e133c3f03c2a2f3..0f5ac5190a7c23fb73d2cc234450322dacb86995 100644 --- a/modules/mol/alg/pymod/wrap_mol_alg.cc +++ b/modules/mol/alg/pymod/wrap_mol_alg.cc @@ -234,6 +234,28 @@ ost::mol::alg::GlobalRDMap prepare_lddt_global_rdmap_wrapper(const list& ref_lis return mol::alg::PreparelDDTGlobalRDMap(ref_list_vector, settings); } +list get_lddt_per_residue_stats_wrapper(mol::EntityHandle& model, + ost::mol::alg::GlobalRDMap& glob_dist_list, + ost::mol::alg::lDDTSettings& settings) { + std::vector<mol::alg::lDDTLocalScore> scores = GetlDDTPerResidueStats(model, glob_dist_list, settings); + list local_scores_list; + for (std::vector<mol::alg::lDDTLocalScore>::const_iterator sit = scores.begin(); sit != scores.end(); ++sit) { + local_scores_list.append(*sit); + } + return local_scores_list; +} + +void print_lddt_per_residue_stats_wrapper(list& scores, mol::alg::lDDTSettings settings){ + int scores_length = boost::python::extract<int>(scores.attr("__len__")()); + std::vector<mol::alg::lDDTLocalScore> scores_vector(scores_length); + + for (int i=0; i<scores_length; i++) { + scores_vector[i] = boost::python::extract<mol::alg::lDDTLocalScore>(scores[i]); + } + + return mol::alg::PrintlDDTPerResidueStats(scores_vector, settings); +} + } @@ -315,6 +337,18 @@ BOOST_PYTHON_MODULE(_ost_mol_alg) .def_readwrite("consistency_checks", &mol::alg::lDDTSettings::consistency_checks) .def_readwrite("cutoffs", &mol::alg::lDDTSettings::cutoffs) .def_readwrite("label", &mol::alg::lDDTSettings::label); + + class_<mol::alg::lDDTLocalScore>("lDDTLocalScore", init<String, String, int, String, String, Real, int, int>()) + .def("ToString", &mol::alg::lDDTLocalScore::ToString) + .def("GetHeader", &mol::alg::lDDTLocalScore::GetHeader) + .def_readwrite("cname", &mol::alg::lDDTLocalScore::cname) + .def_readwrite("rname", &mol::alg::lDDTLocalScore::rname) + .def_readwrite("rnum", &mol::alg::lDDTLocalScore::rnum) + .def_readwrite("is_assessed", &mol::alg::lDDTLocalScore::is_assessed) + .def_readwrite("quality_problems", &mol::alg::lDDTLocalScore::quality_problems) + .def_readwrite("local_lddt", &mol::alg::lDDTLocalScore::local_lddt) + .def_readwrite("conserved_dist", &mol::alg::lDDTLocalScore::conserved_dist) + .def_readwrite("total_dist", &mol::alg::lDDTLocalScore::total_dist); def("FillClashingDistances",&fill_clashing_distances_wrapper); def("FillStereoChemicalParams",&fill_stereochemical_params_wrapper); @@ -329,9 +363,12 @@ BOOST_PYTHON_MODULE(_ost_mol_alg) &mol::alg::CheckStructure, (arg("ent"), arg("bond_table"), arg("angle_table"), arg("nonbonded_table"), arg("bond_tolerance"), arg("angle_tolerance"))); - def("PrintlDDTPerResidueStats", - &mol::alg::PrintlDDTPerResidueStats, + def("GetlDDTPerResidueStats", + &get_lddt_per_residue_stats_wrapper, (arg("model"), arg("glob_dist_list"), arg("settings"))); + def("PrintlDDTPerResidueStats", + &print_lddt_per_residue_stats_wrapper, + (arg("scores"), arg("settings"))); class_<mol::alg::PDBize>("PDBize", diff --git a/modules/mol/alg/src/lddt.cc b/modules/mol/alg/src/lddt.cc index 357e766906e7ad97151830c9ec7eb926b50199af..7c8079d567b23a587426950c5bc27991e78e18a6 100644 --- a/modules/mol/alg/src/lddt.cc +++ b/modules/mol/alg/src/lddt.cc @@ -340,7 +340,9 @@ int main (int argc, char **argv) Real lddt = LocalDistDiffTest(model_view, ref_list, glob_dist_list, settings); // prints the residue-by-residue statistics - PrintlDDTPerResidueStats(model, glob_dist_list, settings); + std::vector<lDDTLocalScore> local_scores; + local_scores = GetlDDTPerResidueStats(model, glob_dist_list, settings); + PrintlDDTPerResidueStats(local_scores, settings); } return 0; } diff --git a/modules/mol/alg/src/local_dist_diff_test.cc b/modules/mol/alg/src/local_dist_diff_test.cc index a019251b96492d54585a3c0fa81055d8fe15ac3b..9c988d1005c1ca2614a48fbf74e7258a07caf135 100644 --- a/modules/mol/alg/src/local_dist_diff_test.cc +++ b/modules/mol/alg/src/local_dist_diff_test.cc @@ -477,6 +477,55 @@ void lDDTSettings::PrintParameters() { std::cout << ToString(); } +// Default constructor is neccessary for boost exposure +lDDTLocalScore::lDDTLocalScore(): cname(""), + rname(""), + rnum(-1), + is_assessed(""), + quality_problems(""), + local_lddt(-1.0), + conserved_dist(-1), + total_dist(-1) {} + +lDDTLocalScore::lDDTLocalScore(String init_cname, + String init_rname, + int init_rnum, + String init_is_assessed, + String init_quality_problems, + Real init_local_lddt, + int init_conserved_dist, + int init_total_dist): + cname(init_cname), + rname(init_rname), + rnum(init_rnum), + is_assessed(init_is_assessed), + quality_problems(init_quality_problems), + local_lddt(init_local_lddt), + conserved_dist(init_conserved_dist), + total_dist(init_total_dist) {} + +String lDDTLocalScore::ToString(bool structural_checks) const { + std::stringstream stkeylddt; + std::stringstream outstr; + stkeylddt << "(" << conserved_dist << "/" << total_dist << ")"; + String dist_string = stkeylddt.str(); + if (structural_checks) { + outstr << cname << "\t" << rname << "\t" << rnum << '\t' << is_assessed << '\t' << quality_problems << '\t' << local_lddt << "\t" << dist_string; + } else { + outstr << cname << "\t" << rname << "\t" << rnum << '\t' << is_assessed << '\t' << local_lddt << "\t" << dist_string; + } + return outstr.str(); +} + +String lDDTLocalScore::GetHeader(bool structural_checks, int cutoffs_length) { + std::stringstream outstr; + if (structural_checks) { + outstr << "Chain\tResName\tResNum\tAsses.\tQ.Prob.\tScore\t(Conserved/Total, over " << cutoffs_length << " thresholds)"; + } else { + outstr << "Chain\tResName\tResNum\tAsses.\tScore\t(Conserved/Total, over " << cutoffs_length << " thresholds)"; + } + return outstr.str(); +} GlobalRDMap CreateDistanceList(const EntityView& ref,Real max_dist) { @@ -782,36 +831,28 @@ void CheckStructure(EntityView& ent, std::cout << "Distances shorter than tolerance are on average shorter by: " << std::fixed << std::setprecision(5) << clash_info.GetAverageOffset() << std::endl; } -void PrintlDDTPerResidueStats(EntityHandle& model, GlobalRDMap& glob_dist_list, lDDTSettings& settings){ +std::vector<lDDTLocalScore> GetlDDTPerResidueStats(EntityHandle& model, GlobalRDMap& glob_dist_list, lDDTSettings& settings){ + std::vector<lDDTLocalScore> scores; EntityView outv = model.GetChainList()[0].Select("peptide=true"); - if (settings.structural_checks) { - std::cout << "Local LDDT Scores:" << std::endl; - std::cout << "(A 'Yes' in the 'Quality Problems' column stands for problems" << std::endl; - std::cout << "in the side-chain of a residue, while a 'Yes+' for problems" << std::endl; - std::cout << "in the backbone)" << std::endl; - } else { - std::cout << "Local LDDT Scores:" << std::endl; - } - if (settings.structural_checks) { - std::cout << "Chain\tResName\tResNum\tAsses.\tQ.Prob.\tScore\t(Conserved/Total, over " << settings.cutoffs.size() << " thresholds)" << std::endl; - } else { - std::cout << "Chain\tResName\tResNum\tAsses.\tScore\t(Conserved/Total, over " << settings.cutoffs.size() << " thresholds)" << std::endl; - } for (ChainViewList::const_iterator ci = outv.GetChainList().begin(), ce = outv.GetChainList().end(); ci != ce; ++ci) { for (ResidueViewList::const_iterator rit = ci->GetResidueList().begin(), re = ci->GetResidueList().end(); rit != re; ++rit) { - + ResidueView ritv=*rit; ResNum rnum = ritv.GetNumber(); bool assessed = false; String assessed_string="No"; - String quality_problems_string="No"; + String quality_problems_string; + if (settings.structural_checks) { + quality_problems_string="No"; + } else { + quality_problems_string="NA"; + } Real lddt_local = -1; String lddt_local_string="-"; int conserved_dist = -1; int total_dist = -1; - String dist_string = "-"; if (IsResnumInGlobalRDMap(rnum,glob_dist_list)) { assessed = true; assessed_string="Yes"; @@ -833,25 +874,43 @@ void PrintlDDTPerResidueStats(EntityHandle& model, GlobalRDMap& glob_dist_list, lddt_local_string=stkeylddt.str(); conserved_dist=ritv.GetIntProp(settings.label+"_conserved"); total_dist=ritv.GetIntProp(settings.label+"_total"); - std::stringstream stkeydist; - stkeydist << "("<< conserved_dist << "/" << total_dist << ")"; - dist_string=stkeydist.str(); } else { std::cout << settings.label << std::endl; lddt_local = 0; lddt_local_string="0.0000"; conserved_dist = 0; total_dist = 0; - dist_string="(0/0)"; } } - if (settings.structural_checks) { - std::cout << ritv.GetChain() << "\t" << ritv.GetName() << "\t" << ritv.GetNumber() << '\t' << assessed_string << '\t' << quality_problems_string << '\t' << lddt_local_string << "\t" << dist_string << std::endl; - } else { - std::cout << ritv.GetChain() << "\t" << ritv.GetName() << "\t" << ritv.GetNumber() << '\t' << assessed_string << '\t' << lddt_local_string << "\t" << dist_string << std::endl; - } + // std::tuple<String, String, int, String, String, Real, int, int> + lDDTLocalScore row(ritv.GetChain().GetName(), + ritv.GetName(), + ritv.GetNumber().GetNum(), + assessed_string, + quality_problems_string, + lddt_local, + conserved_dist, + total_dist); + scores.push_back(row); } } + + return scores; +} + +void PrintlDDTPerResidueStats(std::vector<lDDTLocalScore>& scores, lDDTSettings& settings){ + if (settings.structural_checks) { + std::cout << "Local LDDT Scores:" << std::endl; + std::cout << "(A 'Yes' in the 'Quality Problems' column stands for problems" << std::endl; + std::cout << "in the side-chain of a residue, while a 'Yes+' for problems" << std::endl; + std::cout << "in the backbone)" << std::endl; + } else { + std::cout << "Local LDDT Scores:" << std::endl; + } + std::cout << lDDTLocalScore::GetHeader(settings.structural_checks, settings.cutoffs.size()) << std::endl; + for (std::vector<lDDTLocalScore>::const_iterator sit = scores.begin(); sit != scores.end(); ++sit) { + std::cout << sit->ToString(settings.structural_checks) << std::endl; + } std::cout << std::endl; } diff --git a/modules/mol/alg/src/local_dist_diff_test.hh b/modules/mol/alg/src/local_dist_diff_test.hh index f44d972a22fbc1398232926ed9ec6329b14c08b3..21aee5a1d7a035ae21450b05c84212bc103a1b9d 100644 --- a/modules/mol/alg/src/local_dist_diff_test.hh +++ b/modules/mol/alg/src/local_dist_diff_test.hh @@ -54,6 +54,32 @@ struct lDDTSettings { std::string ToString(); }; +struct lDDTLocalScore { + String cname; + String rname; + int rnum; + String is_assessed; + String quality_problems; + Real local_lddt; + int conserved_dist; + int total_dist; + + lDDTLocalScore(); + + lDDTLocalScore(String init_cname, + String init_rname, + int init_rnum, + String init_is_assessed, + String init_quality_problems, + Real init_local_lddt, + int init_conserved_dist, + int init_total_dist); + + String ToString(bool structural_checks) const; + + static String GetHeader(bool structural_checks, int cutoffs_length); +}; + std::pair<int,int> DLLEXPORT_OST_MOL_ALG ComputeCoverage(const EntityView& v,const GlobalRDMap& glob_dist_list); bool DLLEXPORT_OST_MOL_ALG IsResnumInGlobalRDMap(const ResNum& resnum, const GlobalRDMap& glob_dist_list); @@ -188,9 +214,12 @@ void DLLEXPORT_OST_MOL_ALG CheckStructure(EntityView& ent, Real bond_tolerance, Real angle_tolerance); -void PrintlDDTPerResidueStats(EntityHandle& model, - GlobalRDMap& glob_dist_list, - lDDTSettings& settings); +std::vector<lDDTLocalScore> DLLEXPORT_OST_MOL_ALG GetlDDTPerResidueStats(EntityHandle& model, + GlobalRDMap& glob_dist_list, + lDDTSettings& settings); + +void DLLEXPORT_OST_MOL_ALG PrintlDDTPerResidueStats(std::vector<lDDTLocalScore>& scores, + lDDTSettings& settings); }}}