diff --git a/doc/tests/scripts/loop_monte_carlo.py b/doc/tests/scripts/loop_monte_carlo.py index ea54fce24dbd7c3ec503f58b42d7c22fafa3768f..dba23d61455d956443a5fb1b475535dcc2523a89 100644 --- a/doc/tests/scripts/loop_monte_carlo.py +++ b/doc/tests/scripts/loop_monte_carlo.py @@ -1,5 +1,5 @@ from ost import io -from promod3 import loop, modelling +from promod3 import loop, scoring, modelling import numpy as np # setup protein @@ -20,11 +20,16 @@ mc_sampler = modelling.SoftSampler(terminal_sequence, torsion_sampler, # setup mc_closer mc_closer = modelling.NTerminalCloser(prot.residues[n_terminal_length-1]) -# set up mc_scorer -scorer = loop.LoadBackboneLoopScorer() -scorer.Initialize(seqres) -scorer.SetEnvironment(prot) +# setup backbone scorer with clash and cbeta scoring +score_env = scoring.BackboneScoreEnv(seqres) +score_env.SetInitialEnvironment(prot) +scorer = scoring.BackboneOverallScorer() +scorer["cbeta"] = scoring.LoadCBetaScorer() +scorer["cbeta"].AttachEnvironment(score_env) +scorer["clash"] = scoring.ClashScorer() +scorer["clash"].AttachEnvironment(score_env) +# set up mc_scorer weights = dict() weights["cbeta"] = 10.0 weights["clash"] = 0.1 diff --git a/doc/tests/scripts/modelling_close_small_deletions.py b/doc/tests/scripts/modelling_close_small_deletions.py index c11ff7998c13d6c45dcf20da446d50212ea1e2be..54809c2fdb1591cce6257fcca98ceb1e47baaf5c 100644 --- a/doc/tests/scripts/modelling_close_small_deletions.py +++ b/doc/tests/scripts/modelling_close_small_deletions.py @@ -9,6 +9,6 @@ aln.AttachView(1, tpl.CreateFullView()) mhandle = modelling.BuildRawModel(aln) # close small deletion print 'Number of gaps before: %d' % len(mhandle.gaps) -scorer = modelling.SetupBackboneScorer(mhandle) -modelling.CloseSmallDeletions(mhandle, scorer) +modelling.SetupDefaultBackboneScorer(mhandle) +modelling.CloseSmallDeletions(mhandle) print 'Number of gaps after: %d' % len(mhandle.gaps) diff --git a/doc/tests/scripts/modelling_fill_loops_by_database.py b/doc/tests/scripts/modelling_fill_loops_by_database.py index ed3035b30125a56fb0975c2fd66b4983f050e2e4..16f0944bbf7b86130d3e66412d089da6348cada5 100644 --- a/doc/tests/scripts/modelling_fill_loops_by_database.py +++ b/doc/tests/scripts/modelling_fill_loops_by_database.py @@ -11,8 +11,8 @@ aln.AttachView(1, tpl.CreateFullView()) mhandle = modelling.BuildRawModel(aln) # merge gaps print 'Number of gaps before: %d' % len(mhandle.gaps) -scorer = modelling.SetupBackboneScorer(mhandle) -modelling.FillLoopsByDatabase(mhandle, scorer, loop.LoadFragDB(), +modelling.SetupDefaultBackboneScorer(mhandle) +modelling.FillLoopsByDatabase(mhandle, loop.LoadFragDB(), loop.LoadStructureDB(), loop.LoadTorsionSamplerCoil()) print 'Number of gaps after: %d' % len(mhandle.gaps) diff --git a/doc/tests/scripts/modelling_fill_loops_by_monte_carlo.py b/doc/tests/scripts/modelling_fill_loops_by_monte_carlo.py index 184f6bfc22b0369b2e20613a1cb8721621dfa9d1..e8e02a052f0c533026c85afe3de68e109c24fc84 100644 --- a/doc/tests/scripts/modelling_fill_loops_by_monte_carlo.py +++ b/doc/tests/scripts/modelling_fill_loops_by_monte_carlo.py @@ -11,7 +11,7 @@ aln.AttachView(1, tpl.CreateFullView()) mhandle = modelling.BuildRawModel(aln) # merge gaps print 'Number of gaps before: %d' % len(mhandle.gaps) -scorer = modelling.SetupBackboneScorer(mhandle) -modelling.FillLoopsByMonteCarlo(mhandle, scorer, +modelling.SetupDefaultBackboneScorer(mhandle) +modelling.FillLoopsByMonteCarlo(mhandle, loop.LoadTorsionSamplerCoil()) print 'Number of gaps after: %d' % len(mhandle.gaps) diff --git a/doc/tests/scripts/modelling_model_termini.py b/doc/tests/scripts/modelling_model_termini.py index 5a557064bc0a866dadaa16fc30f44e5ef938eeac..464857d455f6cdba5a92b8e1ab6b1482322b74cd 100644 --- a/doc/tests/scripts/modelling_model_termini.py +++ b/doc/tests/scripts/modelling_model_termini.py @@ -11,7 +11,7 @@ aln.AttachView(1, tpl.CreateFullView()) mhandle = modelling.BuildRawModel(aln) # merge gaps print 'Number of gaps before: %d' % len(mhandle.gaps) -scorer = modelling.SetupBackboneScorer(mhandle) -modelling.ModelTermini(mhandle, scorer, +modelling.SetupDefaultBackboneScorer(mhandle) +modelling.ModelTermini(mhandle, loop.LoadTorsionSamplerCoil()) print 'Number of gaps after: %d' % len(mhandle.gaps) diff --git a/doc/tests/scripts/modelling_steps.py b/doc/tests/scripts/modelling_steps.py index ac57bc1a1a1721ebd0dc3abcfaa1f7a4797a240c..93b4a65dc0aacc8c05b07550e6fd1d0c442a80de 100644 --- a/doc/tests/scripts/modelling_steps.py +++ b/doc/tests/scripts/modelling_steps.py @@ -14,27 +14,27 @@ aln.AttachView(1, tpl.CreateFullView()) mhandle = modelling.BuildRawModel(aln) # perform loop modelling to close all gaps -scorer = modelling.SetupBackboneScorer(mhandle) +modelling.SetupDefaultBackboneScorer(mhandle) modelling.RemoveTerminalGaps(mhandle) -modelling.CloseSmallDeletions(mhandle, scorer) +modelling.CloseSmallDeletions(mhandle) for distance in range(merge_distance): modelling.MergeGapsByDistance(mhandle, distance) - modelling.FillLoopsByDatabase(mhandle, scorer, fragment_db, + modelling.FillLoopsByDatabase(mhandle, fragment_db, structure_db, torsion_sampler, min_loops_required=-1, max_res_extension=6) # if above fails, try DB-fill with less restrictions -modelling.FillLoopsByDatabase(mhandle, scorer, fragment_db, +modelling.FillLoopsByDatabase(mhandle, fragment_db, structure_db, torsion_sampler, min_loops_required=-1) -modelling.FillLoopsByDatabase(mhandle, scorer, fragment_db, +modelling.FillLoopsByDatabase(mhandle, fragment_db, structure_db, torsion_sampler) # if above fails on some gaps, use Monte Carlo -modelling.FillLoopsByMonteCarlo(mhandle, scorer, torsion_sampler) +modelling.FillLoopsByMonteCarlo(mhandle, torsion_sampler) # as a last resort, try to close large deletions -modelling.CloseLargeDeletions(mhandle, scorer, structure_db) +modelling.CloseLargeDeletions(mhandle, structure_db) # build sidechains -modelling.BuildSidechains(mhandle, merge_distance, scorer, +modelling.BuildSidechains(mhandle, merge_distance, fragment_db, structure_db, torsion_sampler) # minimize energy of final model using molecular mechanics diff --git a/modelling/pymod/_closegaps.py b/modelling/pymod/_closegaps.py index bf9256ffecec255741e482109ae6cd5489fc7849..44e07d20085d5389ea8675456c6b8d8727d293fc 100644 --- a/modelling/pymod/_closegaps.py +++ b/modelling/pymod/_closegaps.py @@ -53,11 +53,10 @@ def _GetWeights(): weights["reduced"] = 2.13535565 weights["cbeta"] = 3.59177335 weights["cb_packing"] = 1.17280667 - weights["constraint"] = -0.7 + weights["pairwise"] = -0.7 return weights -def _CloseLoopFrame(mhandle, scorer, gap_orig, actual_candidates, - actual_extended_gaps): +def _CloseLoopFrame(mhandle, gap_orig, actual_candidates, actual_extended_gaps): '''Rank candidates with "frame-approach". All found candidates are extended prior to scoring so they match in size. ''' @@ -99,35 +98,28 @@ def _CloseLoopFrame(mhandle, scorer, gap_orig, actual_candidates, loop_candidate.bb_list, start_index, False) final_loop_candidates.Add(actual_frame_backbone_list) back_mapper.append((i, j)) + + if len(final_loop_candidates) > 0: + # score them + scores = final_loop_candidates.CalculateLinearScores(\ + mhandle.backbone_scorer, _GetWeights(), min_before_resnum, + actual_chain_idx) + min_score = min(scores) + min_idx = scores.index(min_score) - # score them - final_loop_candidates.AttachScorer(scorer) - final_loop_candidates.CalculateCombinedScores(_GetWeights(), - min_before_resnum, - actual_chain_idx) - - # compare scores - min_score = float("inf") - optimal_candidate = -1 - for i in range(len(final_loop_candidates)): - score = final_loop_candidates[i].combined_score - if score < min_score: - optimal_candidate = i - min_score = score - - ost.LogVerbose("Gap %s - %d candidates, best (min) score %g" % - (str(gap_orig), len(final_loop_candidates), min_score)) + ost.LogVerbose("Gap %s - %d candidates, best (min) score %g" % + (str(gap_orig), len(final_loop_candidates), min_score)) - # finally resolve loop - if optimal_candidate != -1: - idx_a = back_mapper[optimal_candidate][0] - idx_b = back_mapper[optimal_candidate][1] + # resolve loop + idx_a = back_mapper[min_idx][0] + idx_b = back_mapper[min_idx][1] # update model start_resnum = actual_extended_gaps[idx_a].before.GetNumber() bb_list = actual_candidates[idx_a][idx_b].bb_list bb_list.InsertInto(mhandle.model.chains[actual_chain_idx], start_resnum) - # update scorer - scorer.SetEnvironment(bb_list, start_resnum, actual_chain_idx) + # update score env. + mhandle.backbone_scorer_env.SetEnvironment(bb_list, start_resnum, + actual_chain_idx) ost.LogInfo("Resolved %s by filling %s (%d candidates)" % \ (str(gap_orig), str(actual_extended_gaps[idx_a]), @@ -139,8 +131,8 @@ def _CloseLoopFrame(mhandle, scorer, gap_orig, actual_candidates, return -2 -def _CloseLoopBare(mhandle, scorer, gap_orig, actual_candidates, - actual_extended_gaps, penalize_length=True): +def _CloseLoopBare(mhandle, gap_orig, actual_candidates, actual_extended_gaps, + penalize_length=True): '''Rank candidates directly. All candidates are scored directly and optionally penalized for gap length. ''' @@ -149,31 +141,30 @@ def _CloseLoopBare(mhandle, scorer, gap_orig, actual_candidates, actual_chain = mhandle.model.chains[actual_chain_idx] # score loops as they are + scorer = mhandle.backbone_scorer weights = _GetWeights() min_score = float("inf") optimal_gap = None optimal_candidate = None n_candidates = 0 for i, loop_candidates in enumerate(actual_candidates): + if len(loop_candidates) == 0: continue n_candidates += len(loop_candidates) # score them before_resnum = actual_extended_gaps[i].before.GetNumber().GetNum() - loop_candidates.AttachScorer(scorer) - loop_candidates.CalculateCombinedScores(weights, - before_resnum, - actual_chain_idx) - # any good ones? - gap_length = actual_extended_gaps[i].length - for loop_candidate in loop_candidates: - # penalized by gap length? - if penalize_length: - score = loop_candidate.combined_score * gap_length - else: - score = loop_candidate.combined_score - if score < min_score: - optimal_gap = actual_extended_gaps[i] - optimal_candidate = loop_candidate - min_score = score + scores = loop_candidates.CalculateLinearScores(\ + scorer, weights, before_resnum, actual_chain_idx) + # check best one + score = min(scores) + best_idx = scores.index(score) + if penalize_length: + # penalized by gap length + score = score * actual_extended_gaps[i].length + if score < min_score: + # keep best one + min_score = score + optimal_gap = actual_extended_gaps[i] + optimal_candidate = loop_candidates[best_idx] ost.LogVerbose("Gap %s - %d candidates, best (min) score %g" % (str(gap_orig), n_candidates, min_score)) @@ -184,8 +175,9 @@ def _CloseLoopBare(mhandle, scorer, gap_orig, actual_candidates, start_resnum = optimal_gap.before.GetNumber() bb_list = optimal_candidate.bb_list bb_list.InsertInto(mhandle.model.chains[actual_chain_idx], start_resnum) - # update scorer - scorer.SetEnvironment(bb_list, start_resnum, actual_chain_idx) + # update score env. + mhandle.backbone_scorer_env.SetEnvironment(bb_list, start_resnum, + actual_chain_idx) ost.LogInfo("Resolved %s by filling %s (%d candidates)" % \ (str(gap_orig), str(optimal_gap), n_candidates)) # will return -1 if last gap removed @@ -194,10 +186,9 @@ def _CloseLoopBare(mhandle, scorer, gap_orig, actual_candidates, ost.LogInfo("Failed at loop insertion (%s)" % str(gap_orig)) return -2 -def _CloseLoop(mhandle, scorer, gap_orig, actual_candidates, +def _CloseLoop(mhandle, gap_orig, actual_candidates, actual_extended_gaps, variant=0): '''Choose best scoring loop candidate and close loop in mhandle. - :param scorer: scorer dedicated to this model :param gap_orig: Gap we actually wanted to close :param actual_candidates: List of LoopCandidates :param actual_extended_gaps: List of gaps (same size as actual_candidates) @@ -218,10 +209,10 @@ def _CloseLoop(mhandle, scorer, gap_orig, actual_candidates, return -2 # choose variant if variant == 0: - return _CloseLoopFrame(mhandle, scorer, gap_orig, actual_candidates, + return _CloseLoopFrame(mhandle, gap_orig, actual_candidates, actual_extended_gaps) elif variant in [1,2]: - return _CloseLoopBare(mhandle, scorer, gap_orig, actual_candidates, + return _CloseLoopBare(mhandle, gap_orig, actual_candidates, actual_extended_gaps, variant == 2) else: raise RuntimeError("Unknown variant %d" % variant); @@ -253,7 +244,7 @@ def _InRange(gap, chain_idx, resnum_range): ############################################################################### -def CloseSmallDeletions(mhandle, scorer, max_extension=9, clash_thresh=1.0, +def CloseSmallDeletions(mhandle, max_extension=9, clash_thresh=1.0, e_thresh=200, use_scoring_extender=True, use_full_extender=True, chain_idx=None, resnum_range=None): @@ -272,10 +263,6 @@ def CloseSmallDeletions(mhandle, scorer, max_extension=9, clash_thresh=1.0, :param mhandle: Modelling handle on which to apply change. :type mhandle: :class:`ModellingHandle` - :param scorer: A scorer dedicated to this model. - If gaps are closed, the *scorer* is updated. - :type scorer: :class:`~promod3.loop.BackboneLoopScorer` - :param max_extension: Maximal number of gap extension steps to perform (see :class:`GapExtender`) :type max_extension: :class:`int` @@ -323,6 +310,7 @@ def CloseSmallDeletions(mhandle, scorer, max_extension=9, clash_thresh=1.0, else: return + clash_scorer = mhandle.backbone_scorer.Get("clash") current_gap_index = 0 # iterating mhandle.gaps. The number of gaps may change during the process, @@ -378,10 +366,10 @@ def CloseSmallDeletions(mhandle, scorer, max_extension=9, clash_thresh=1.0, bb_relaxer = BackboneRelaxer(bb_list) potential_e = bb_relaxer.Run(bb_list, 300, 0.1) # check for clashes - score = scorer.CalculateClashScore(\ - bb_list, - n_stem_resnum.GetNum(), - current_chain_index) + score = clash_scorer.CalculateScore(bb_list, + n_stem_resnum.GetNum(), + current_chain_index) + # if there is no clash and potential energy is low enough we # just solved a gap, delete it and update the scorer for the # changed model @@ -392,8 +380,8 @@ def CloseSmallDeletions(mhandle, scorer, max_extension=9, clash_thresh=1.0, (mhandle.gaps[current_gap_index], current_gap)) chain = current_gap.before.GetChain() bb_list.InsertInto(chain, n_stem_resnum) - scorer.SetEnvironment(bb_list, n_stem_resnum, - current_chain_index) + mhandle.backbone_scorer_env.SetEnvironment(\ + bb_list, n_stem_resnum, current_chain_index) ClearGaps(mhandle, current_gap) success = True break @@ -468,7 +456,7 @@ def MergeGapsByDistance(mhandle, distance): try_again = True break -def FillLoopsByDatabase(mhandle, scorer, fragment_db, structure_db, +def FillLoopsByDatabase(mhandle, fragment_db, structure_db, torsion_sampler, max_loops_to_search=40, min_loops_required=4, max_res_extension=-1, extended_search=True, use_scoring_extender=True, @@ -487,10 +475,6 @@ def FillLoopsByDatabase(mhandle, scorer, fragment_db, structure_db, :param mhandle: Modelling handle on which to apply change. :type mhandle: :class:`ModellingHandle` - :param scorer: A scorer dedicated to this model. - If gaps are closed, the *scorer* is updated. - :type scorer: :class:`~promod3.loop.BackboneLoopScorer` - :param fragment_db: A fragment database coupled to the *structure_db*. :type fragment_db: :class:`~promod3.loop.FragDB` @@ -679,7 +663,7 @@ def FillLoopsByDatabase(mhandle, scorer, fragment_db, structure_db, ################################## # close loop ################################## - new_idx = _CloseLoop(mhandle, scorer, gap_orig, actual_candidates, + new_idx = _CloseLoop(mhandle, gap_orig, actual_candidates, actual_extended_gaps, score_variant) if new_idx == -2: # try next one if we failed @@ -691,7 +675,7 @@ def FillLoopsByDatabase(mhandle, scorer, fragment_db, structure_db, gap_idx = new_idx -def FillLoopsByMonteCarlo(mhandle, scorer, torsion_sampler, max_loops_to_search=6, +def FillLoopsByMonteCarlo(mhandle, torsion_sampler, max_loops_to_search=6, max_extension=30, mc_num_loops=2, mc_steps=5000, use_scoring_extender=True, use_full_extender=True, score_variant=0, ring_punch_detection=1, @@ -715,10 +699,6 @@ def FillLoopsByMonteCarlo(mhandle, scorer, torsion_sampler, max_loops_to_search= :param mhandle: Modelling handle on which to apply change. :type mhandle: :class:`ModellingHandle` - :param scorer: A scorer dedicated to this model. - If gaps are closed, the *scorer* is updated. - :type scorer: :class:`~promod3.loop.BackboneLoopScorer` - :param torsion_sampler: A sampler for torsion angles. :type torsion_sampler: :class:`~promod3.loop.TorsionSampler` @@ -856,7 +836,7 @@ def FillLoopsByMonteCarlo(mhandle, scorer, torsion_sampler, max_loops_to_search= weights["cb_packing"] = 2.0 weights["hbond"] = 1.0 weights["clash"] = 0.05 - mc_scorer = LinearScorer(scorer, + mc_scorer = LinearScorer(mhandle.backbone_scorer, actual_gap.before.GetNumber().GetNum(), actual_chain_idx, weights) @@ -902,7 +882,7 @@ def FillLoopsByMonteCarlo(mhandle, scorer, torsion_sampler, max_loops_to_search= ################################## # close loop ################################## - new_idx = _CloseLoop(mhandle, scorer, gap_orig, actual_candidates, + new_idx = _CloseLoop(mhandle, gap_orig, actual_candidates, actual_extended_gaps, score_variant) if new_idx == -2: # try next one if we failed @@ -914,7 +894,7 @@ def FillLoopsByMonteCarlo(mhandle, scorer, torsion_sampler, max_loops_to_search= gap_idx = new_idx -def ModelTermini(mhandle, scorer, torsion_sampler, fragger_handles=None, +def ModelTermini(mhandle, torsion_sampler, fragger_handles=None, mc_num_loops=20, mc_steps=5000): '''Try to model termini with Monte Carlo sampling. @@ -932,10 +912,6 @@ def ModelTermini(mhandle, scorer, torsion_sampler, fragger_handles=None, :param mhandle: Modelling handle on which to apply change. :type mhandle: :class:`ModellingHandle` - :param scorer: A scorer dedicated to this model. - If gaps are closed, the *scorer* is updated. - :type scorer: :class:`~promod3.loop.BackboneLoopScorer` - :param torsion_sampler: A sampler for torsion angles. :type torsion_sampler: :class:`~promod3.loop.TorsionSampler` @@ -996,8 +972,8 @@ def ModelTermini(mhandle, scorer, torsion_sampler, fragger_handles=None, scorer_weights["cb_packing"] = 2.0 scorer_weights["hbond"] = 1.0 scorer_weights["clash"] = 0.05 - mc_scorer = LinearScorer(scorer, start_resnum, actual_chain_idx, - scorer_weights) + mc_scorer = LinearScorer(mhandle.backbone_scorer, start_resnum, + actual_chain_idx, scorer_weights) # setup cooler start_temperature = 100 @@ -1014,29 +990,19 @@ def ModelTermini(mhandle, scorer, torsion_sampler, fragger_handles=None, actual_gap.full_seq, mc_num_loops, mc_steps, mc_sampler, mc_closer, mc_scorer, mc_cooler) - # score candidates - candidates.AttachScorer(scorer) - candidates.CalculateCombinedScores(_GetWeights(), start_resnum, - actual_chain_idx) - # get best one - min_score = float("inf") - optimal_candidate = None - for candidate in candidates: - score = candidate.combined_score - if score < min_score: - optimal_candidate = candidate - min_score = score - - ost.LogVerbose("Gap %s - %d candidates, best (min) score %g" % - (str(actual_gap), len(candidates), min_score)) - - # finally resolve loop - if optimal_candidate is not None: + if len(candidates) > 0: + # score candidates + scores = candidates.CalculateLinearScores(\ + mhandle.backbone_scorer, _GetWeights(), start_resnum, + actual_chain_idx) + min_score = min(scores) + min_idx = scores.index(min_score) # update model - bb_list = optimal_candidate.bb_list + bb_list = candidates[min_idx].bb_list bb_list.InsertInto(actual_chain, start_resnum) - # update scorer - scorer.SetEnvironment(bb_list, start_resnum, actual_chain_idx) + # update score env. + mhandle.backbone_scorer_env.SetEnvironment(bb_list, start_resnum, + actual_chain_idx) ost.LogInfo("Resolved terminal gap %s (%d candidates)" % \ (str(actual_gap), len(candidates))) ClearGaps(mhandle, actual_gap) @@ -1044,7 +1010,7 @@ def ModelTermini(mhandle, scorer, torsion_sampler, fragger_handles=None, ost.LogInfo("Failed to model terminal gap (%s)" % str(actual_gap)) -def CloseLargeDeletions(mhandle, scorer, structure_db, linker_length=8, +def CloseLargeDeletions(mhandle, structure_db, linker_length=8, num_fragments=500, use_scoring_extender=True, use_full_extender=True): @@ -1058,10 +1024,6 @@ def CloseLargeDeletions(mhandle, scorer, structure_db, linker_length=8, :param mhandle: Modelling handle on which to apply change. :type mhandle: :class:`ModellingHandle` - :param scorer: A scorer dedicated to this model. - If gaps are closed, the *scorer* is updated. - :type scorer: :class:`~promod3.loop.BackboneLoopScorer` - :param structure_db: The database from which to extract fragments for the linker region. :type structure_db: :class:`~promod3.loop.StructureDB` @@ -1191,6 +1153,7 @@ def CloseLargeDeletions(mhandle, scorer, structure_db, linker_length=8, # the n-terminus best_score = float("inf") best_idx = 0 + scorer_weights = {"clash": 1, "reduced": 1} for i in range(len(fragger)): fragment = fragger[i] @@ -1207,10 +1170,8 @@ def CloseLargeDeletions(mhandle, scorer, structure_db, linker_length=8, bb_list.ApplyTransform(t) # a simple score gets calculated and best chosen - score = scorer.CalculateReducedScore(bb_list, first_num, - actual_chain_idx) - score += scorer.CalculateClashScore(bb_list, first_num, - actual_chain_idx) + score = mhandle.backbone_scorer.CalculateLinearCombination(\ + scorer_weights, bb_list, first_num, actual_chain_idx) if score < best_score: best_score = score best_idx = i @@ -1240,8 +1201,9 @@ def CloseLargeDeletions(mhandle, scorer, structure_db, linker_length=8, fragment = bb_list.Extract(frag_start_idx, len(bb_list)) fragment.InsertInto(actual_chain, n_res_num) - # update scorer - scorer.SetEnvironment(bb_list, first_num, actual_chain_idx) + # update score env. + mhandle.backbone_scorer_env.SetEnvironment(bb_list, first_num, + actual_chain_idx) # will return -1 if last gap removed gap_idx = ClearGaps(mhandle, actual_gap) @@ -1252,11 +1214,3 @@ def CloseLargeDeletions(mhandle, scorer, structure_db, linker_length=8, # these methods will be exported into module __all__ = ('CloseSmallDeletions', 'MergeGapsByDistance', 'FillLoopsByDatabase', 'FillLoopsByMonteCarlo', 'ModelTermini', 'CloseLargeDeletions') - -# LocalWords: modeling stereochemically param idx init -# LocalWords: py ost pylint modelling promod CloseSmallDeletions -# LocalWords: fillloopsbydb tpl aln trg TLNGFTVPAGNTLV LNPDKGATVTMA mhandle -# LocalWords: NGGTLLIPNGTYHFLGIQMKSNVHIRVE AttachView CreateFullView len -# LocalWords: BuildRawModel SetupBackboneScorer FillLoopsByDatabase -# LocalWords: LoadFragDB LoadStructureDB LoadTorsionSamplerCoil dbs fasta -# LocalWords: rtype diff --git a/modelling/pymod/_pipeline.py b/modelling/pymod/_pipeline.py index ea3a03393de733a10f604b55dc237b61775c9501..3dc87809edd398563101c250db684f54fb4b1847 100644 --- a/modelling/pymod/_pipeline.py +++ b/modelling/pymod/_pipeline.py @@ -162,7 +162,7 @@ def _GetSimEntity(sim): return ent ############################################################################### -def BuildSidechains(mhandle, merge_distance=4, scorer=None, fragment_db=None, +def BuildSidechains(mhandle, merge_distance=4, fragment_db=None, structure_db=None, torsion_sampler=None): '''Build sidechains for model. @@ -177,10 +177,6 @@ def BuildSidechains(mhandle, merge_distance=4, scorer=None, fragment_db=None, :param merge_distance: Used as parameter for :func:`MergeGapsByDistance` if ring punches are found. :type merge_distance: :class:`int` - :param scorer: Used as parameter for :func:`FillLoopsByDatabase` - if ring punches are found. A default one is created - if None. - :type scorer: :class:`~promod3.loop.BackboneLoopScorer` :param fragment_db: Used as parameter for :func:`FillLoopsByDatabase` if ring punches are found. A default one is loaded if None. @@ -213,8 +209,8 @@ def BuildSidechains(mhandle, merge_distance=4, scorer=None, fragment_db=None, mygap = StructuralGap(res.prev, res.next, res.one_letter_code) mhandle.gaps.append(mygap) # load stuff if needed - if scorer is None: - scorer = SetupBackboneScorer(mhandle) + if not IsBackboneScorerSet(mhandle) or not IsBackboneScorerSet(mhandle): + SetupDefaultBackboneScorer(mhandle) if fragment_db is None: fragment_db = loop.LoadFragDB() if structure_db is None: @@ -223,7 +219,7 @@ def BuildSidechains(mhandle, merge_distance=4, scorer=None, fragment_db=None, torsion_sampler = loop.LoadTorsionSamplerCoil() # fix it MergeGapsByDistance(mhandle, merge_distance) - FillLoopsByDatabase(mhandle, scorer, fragment_db, structure_db, + FillLoopsByDatabase(mhandle, fragment_db, structure_db, torsion_sampler, ring_punch_detection=2) # re-build sidechains sidechain.Reconstruct(mhandle.model, keep_sidechains=True) @@ -403,7 +399,7 @@ def CheckFinalModel(mhandle): ost.LogInfo("Stereo-chemical problem in sidechain " + \ "of residue " + str(res)) -def BuildFromRawModel(mhandle, scorer = None, use_amber_ff=False, extra_force_fields=list()): +def BuildFromRawModel(mhandle, use_amber_ff=False, extra_force_fields=list()): '''Build a model starting with a raw model (see :func:`BuildRawModel`). This function implements a recommended pipeline to generate complete models @@ -411,7 +407,13 @@ def BuildFromRawModel(mhandle, scorer = None, use_amber_ff=False, extra_force_fi :ref:`above <modelling_steps_example>`. If you wish to use your own pipeline, you can use that code as a starting point for your own custom modelling pipeline. For reproducibility, we recommend that you keep copies - of custom pipelines. + of custom pipelines. + + If you wish to use a custom scorer, you can attach your own scorers to the + `mhandle`. In that case you need to make sure that `mhandle.backbone_scorer` + and `mhandle.backbone_scorer_env` are both set and are consistent. You can + also call :meth:`SetupDefaultBackboneScorer` and adapt the default scorer + for your purposes. If the function fails to close all gaps, it will produce a warning and return an incomplete model. @@ -453,30 +455,32 @@ def BuildFromRawModel(mhandle, scorer = None, use_amber_ff=False, extra_force_fi torsion_sampler = loop.LoadTorsionSamplerCoil() merge_distance = 4 - if scorer == None: - scorer = SetupBackboneScorer(mhandle) + if IsBackboneScorerSet(mhandle) and IsBackboneScorerSet(mhandle): + ost.LogInfo("Using scorer which is already set in modelling handle.") + else: + SetupDefaultBackboneScorer(mhandle) # remove terminal gaps and close small deletions RemoveTerminalGaps(mhandle) - CloseSmallDeletions(mhandle, scorer) + CloseSmallDeletions(mhandle) # iteratively merge gaps of distance i and fill loops by database for distance in range(merge_distance): MergeGapsByDistance(mhandle, distance) - FillLoopsByDatabase(mhandle, scorer, fragment_db, structure_db, + FillLoopsByDatabase(mhandle, fragment_db, structure_db, torsion_sampler, min_loops_required=-1, max_res_extension=6) - FillLoopsByDatabase(mhandle, scorer, fragment_db, structure_db, + FillLoopsByDatabase(mhandle, fragment_db, structure_db, torsion_sampler, min_loops_required=-1) - FillLoopsByDatabase(mhandle, scorer, fragment_db, structure_db, + FillLoopsByDatabase(mhandle, fragment_db, structure_db, torsion_sampler) # close remaining gaps by Monte Carlo - FillLoopsByMonteCarlo(mhandle, scorer, torsion_sampler) - CloseLargeDeletions(mhandle, scorer, structure_db) + FillLoopsByMonteCarlo(mhandle, torsion_sampler) + CloseLargeDeletions(mhandle, structure_db) # build sidechains - BuildSidechains(mhandle, merge_distance, scorer, fragment_db, + BuildSidechains(mhandle, merge_distance, fragment_db, structure_db, torsion_sampler) # minimize energy of final model using molecular mechanics diff --git a/modelling/pymod/export_model.cc b/modelling/pymod/export_model.cc index 1de295e835290e1b40506cd6cd89934a579bb608..6fb5a66c77274630eeaff52ffd47d2498b6567cc 100644 --- a/modelling/pymod/export_model.cc +++ b/modelling/pymod/export_model.cc @@ -23,35 +23,41 @@ int WrapCountEnclosedIns(ModellingHandle& mhandle, const StructuralGap& gap) { } promod3::scoring::BackboneOverallScorerPtr -WrapGetBackboneScorer(ModellingHandle& mhandle){ - if(!mhandle.backbone_scorer){ - String err = "backbone_scorer must first be properly initialized "; - err += "before it can be used!"; - throw promod3::Error(err); +WrapGetBackboneScorer(ModellingHandle& mhandle) { + if (!mhandle.backbone_scorer) { + throw promod3::Error("The backbone_scorer must be properly initialized " + "before it can be used!"); } return mhandle.backbone_scorer; } void WrapSetBackboneScorer(ModellingHandle& mhandle, - promod3::scoring::BackboneOverallScorerPtr scorer){ + promod3::scoring::BackboneOverallScorerPtr scorer) { mhandle.backbone_scorer = scorer; } promod3::scoring::BackboneScoreEnvPtr -WrapGetBackboneScorerEnv(ModellingHandle& mhandle){ - if(!mhandle.backbone_scorer_env){ - String err = "backbone_scorer_env must first be properly initialized "; - err += "before it can be used!"; - throw promod3::Error(err); +WrapGetBackboneScorerEnv(ModellingHandle& mhandle) { + if (!mhandle.backbone_scorer_env) { + throw promod3::Error("The backbone_scorer_env must be properly initialized " + "before it can be used!"); } return mhandle.backbone_scorer_env; } void WrapSetBackboneScorerEnv(ModellingHandle& mhandle, - promod3::scoring::BackboneScoreEnvPtr env){ + promod3::scoring::BackboneScoreEnvPtr env) { mhandle.backbone_scorer_env = env; } +// not really needed in C++ as we can do the check below directly +bool WrapIsBackboneScorerSet(ModellingHandle& mhandle) { + return bool(mhandle.backbone_scorer); +} +bool WrapIsBackboneScorerEnvSet(ModellingHandle& mhandle) { + return bool(mhandle.backbone_scorer_env); +} + } // anon ns void export_model() @@ -71,7 +77,9 @@ void export_model() def("CountEnclosedInsertions", WrapCountEnclosedIns, (arg("mhandle"),arg("gap"))); def("MergeGaps", MergeGaps, (arg("mhandle"),arg("index"))); def("RemoveTerminalGaps", RemoveTerminalGaps, (arg("mhandle"))); - def("SetupDefaultBackboneScorer", &SetupDefaultBackboneScorer,(arg("mhandle"))); + def("SetupDefaultBackboneScorer", &SetupDefaultBackboneScorer, (arg("mhandle"))); + def("IsBackboneScorerSet", &WrapIsBackboneScorerSet, (arg("mhandle"))); + def("IsBackboneScorerEnvSet", &WrapIsBackboneScorerEnvSet, (arg("mhandle"))); def("BuildRawModel", BuildRawModelHandle, (arg("aln"), arg("include_ligands")=false, diff --git a/modelling/src/model.cc b/modelling/src/model.cc index 8d7b32f73eac5505089768162c2fe7c3e8b85189..1421da48ae2cb040d3ec09cc541e0df2e1f46e2e 100644 --- a/modelling/src/model.cc +++ b/modelling/src/model.cc @@ -218,7 +218,7 @@ void AttachScorer(BackboneOverallScorerPtr overall_scorer, void SetupDefaultBackboneScorer(ModellingHandle& mhandle){ - //setup environment + // setup environment BackboneScoreEnvPtr env(new BackboneScoreEnv(mhandle.seqres)); env->SetInitialEnvironment(mhandle.model); @@ -236,6 +236,7 @@ void SetupDefaultBackboneScorer(ModellingHandle& mhandle){ mhandle.backbone_scorer_env = env; mhandle.backbone_scorer = scorer; + LOG_INFO("Initialized default backbone scorer for modelling."); } bool CopyConserved(ResidueView src_res, ResidueHandle dst_res, XCSEditor& edi, diff --git a/modelling/src/monte_carlo_scorer.hh b/modelling/src/monte_carlo_scorer.hh index 0651af7b5c7bffa34e2ed60b3619af39cabed230..799f0e60a56e5df5b2d4eb96bf8d34d94274de9c 100644 --- a/modelling/src/monte_carlo_scorer.hh +++ b/modelling/src/monte_carlo_scorer.hh @@ -7,7 +7,7 @@ #include <ost/mol/mol.hh> // TODO: follow define, kill backbone_loop_score -// #define NEW_STYLE_SCORING +#define NEW_STYLE_SCORING #include <promod3/loop/backbone_loop_score.hh> #include <promod3/scoring/backbone_overall_scorer.hh> diff --git a/modelling/tests/test_close_gaps.py b/modelling/tests/test_close_gaps.py index 7119e5a6a9f65774c920590edad8ea42b9bfdaac..49bb60b26bcdb791a373e85c1bf9751ab31f2c8a 100644 --- a/modelling/tests/test_close_gaps.py +++ b/modelling/tests/test_close_gaps.py @@ -161,10 +161,10 @@ class CloseGapsTests(unittest.TestCase): aln.AttachView(1, tpl.CreateFullView()) mhandle = modelling.BuildRawModel(aln) self.assertEqual(len(mhandle.gaps), 1) - # obtain the scorer - scorer = modelling.SetupBackboneScorer(mhandle) + # close it + modelling.SetupDefaultBackboneScorer(mhandle) nlogs = len(self.log.messages['INFO']) - modelling.CloseSmallDeletions(mhandle, scorer) + modelling.CloseSmallDeletions(mhandle) self.assertEqual(len(mhandle.gaps), 0) # check backbone self.backboneCheck(mhandle.model, 'GGGGGG') @@ -190,8 +190,8 @@ class CloseGapsTests(unittest.TestCase): mhandle = modelling.BuildRawModel(alns) self.assertEqual(len(mhandle.gaps), 2) # do it - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.CloseSmallDeletions(mhandle, scorer) + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.CloseSmallDeletions(mhandle) # check self.assertEqual(len(mhandle.gaps), 0) self.backboneCheckHandle(mhandle) @@ -287,8 +287,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabase(self): '''Get rid of 2 gaps by db.''' mhandle = self.getGapTest() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler) self.assertEqual(len(mhandle.gaps), 0) @@ -299,8 +299,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabaseDeletion(self): '''Get rid of deletion by db.''' mhandle = self.getGapTestDeletion() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler) self.assertEqual(len(mhandle.gaps), 0) @@ -311,8 +311,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabaseInsertion(self): '''Get rid of insertion by db.''' mhandle = self.getGapTestInsertion() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler) self.assertEqual(len(mhandle.gaps), 0) @@ -323,8 +323,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabaseInsertionTerminal(self): '''Get rid of insertion by db close to terminal (needs FullExtender).''' mhandle = self.getGapTestInsertionTerminal() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler, use_full_extender=True) @@ -336,8 +336,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabaseTerminal(self): '''Terminal loops are not altered.''' mhandle = self.getGapTestTerminal() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler) self.assertEqual(len(mhandle.gaps), 2) @@ -345,8 +345,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabaseNoSE(self): '''Get rid of 2 gaps by db (without scoring extender).''' mhandle = self.getGapTest() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler, use_scoring_extender=False) @@ -358,8 +358,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabaseDeletionNoSE(self): '''Get rid of deletion by db (without scoring extender).''' mhandle = self.getGapTestDeletion() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler, use_scoring_extender=False) @@ -371,8 +371,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabaseInsertionNoSE(self): '''Get rid of insertion by db (without scoring extender).''' mhandle = self.getGapTestInsertion() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler, use_scoring_extender=False) @@ -384,8 +384,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabaseTerminalNoSE(self): '''Terminal loops are not altered (without scoring extender).''' mhandle = self.getGapTestTerminal() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler, use_scoring_extender=False) @@ -394,8 +394,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabaseHomoOligomer(self): '''Get rid of 2 gaps by db for homo oligomers.''' mhandle = self.getRawModelOligo("data/2aoh-1_cut") - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler) self.assertEqual(len(mhandle.gaps), 0) @@ -404,8 +404,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByDatabaseHeteroOligomer(self): '''Get rid of 2 gaps by db for hetero oligomers.''' mhandle = self.getRawModelOligo("data/5d52-1_cut") - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler) self.assertEqual(len(mhandle.gaps), 0) @@ -416,8 +416,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByMonteCarlo(self): '''Get rid of 2 gaps by MC.''' mhandle = self.getGapTest() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByMonteCarlo(mhandle, scorer, self.torsion_sampler, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler, mc_steps=100) self.assertEqual(len(mhandle.gaps), 0) # check backbone @@ -427,8 +427,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByMonteCarloDeletion(self): '''Get rid of deletion by MC.''' mhandle = self.getGapTestDeletion() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByMonteCarlo(mhandle, scorer, self.torsion_sampler, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler, mc_steps=100) self.assertEqual(len(mhandle.gaps), 0) # check backbone @@ -438,8 +438,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByMonteCarloInsertion(self): '''Get rid of insertion by MC.''' mhandle = self.getGapTestInsertion() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByMonteCarlo(mhandle, scorer, self.torsion_sampler, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler, mc_steps=100) self.assertEqual(len(mhandle.gaps), 0) # check backbone @@ -449,16 +449,16 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByMonteCarloTerminal(self): '''Terminal loops are not altered.''' mhandle = self.getGapTestTerminal() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByMonteCarlo(mhandle, scorer, self.torsion_sampler, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler, mc_steps=100) self.assertEqual(len(mhandle.gaps), 2) def testFillGapsByMonteCarloHomoOligomer(self): '''Get rid of 2 gaps by db for homo oligomers.''' mhandle = self.getRawModelOligo("data/2aoh-1_cut") - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByMonteCarlo(mhandle, scorer, self.torsion_sampler, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler, mc_steps=100) self.assertEqual(len(mhandle.gaps), 0) self.backboneCheckHandle(mhandle) @@ -466,8 +466,8 @@ class CloseGapsTests(unittest.TestCase): def testFillGapsByMonteCarloHeteroOligomer(self): '''Get rid of 2 gaps by db for hetero oligomers.''' mhandle = self.getRawModelOligo("data/5d52-1_cut") - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByMonteCarlo(mhandle, scorer, self.torsion_sampler, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler, mc_steps=100) self.assertEqual(len(mhandle.gaps), 0) self.backboneCheckHandle(mhandle) @@ -482,14 +482,14 @@ class CloseGapsTests(unittest.TestCase): mhandle = modelling.BuildRawModel(aln) self.assertEqual(len(mhandle.gaps), 3) # model termini - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.ModelTermini(mhandle, scorer, self.torsion_sampler, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.ModelTermini(mhandle, self.torsion_sampler, mc_steps=100) self.assertEqual(len(mhandle.gaps), 1) myseq = ''.join([r.one_letter_code for r in mhandle.model.residues]) self.assertEqual(myseq, 'AAAAGGGGGGGGGGGGGGGGGGGGAAAAAA') # model rest - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler) self.assertEqual(len(mhandle.gaps), 0) @@ -512,8 +512,8 @@ class CloseGapsTests(unittest.TestCase): mhandle = modelling.BuildRawModel(alns) self.assertEqual(len(mhandle.gaps), 4) # model termini - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.ModelTermini(mhandle, scorer, self.torsion_sampler, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.ModelTermini(mhandle, self.torsion_sampler, mc_steps=100) self.assertEqual(len(mhandle.gaps), 0) self.assertEqual(mhandle.model.residue_count, 63) @@ -529,9 +529,9 @@ class CloseGapsTests(unittest.TestCase): seq.CreateSequence('tpl', 'NGGTLLIPNGTYHFLGIQMKSNVHIRVE')) aln.AttachView(1, tpl.CreateFullView()) mhandle = modelling.BuildRawModel(aln) - scorer = modelling.SetupBackboneScorer(mhandle) + modelling.SetupDefaultBackboneScorer(mhandle) self.assertEqual(len(mhandle.gaps), 1) - modelling.CloseLargeDeletions(mhandle, scorer, self.structure_db, + modelling.CloseLargeDeletions(mhandle, self.structure_db, num_fragments=100) self.assertEqual(len(mhandle.gaps), 0) # check backbone @@ -545,10 +545,10 @@ class CloseGapsTests(unittest.TestCase): seq.CreateSequence('tpl', 'NGGTLLIPNGTYHFLGIQMKSNVHIRVE')) aln.AttachView(1, tpl.CreateFullView()) mhandle = modelling.BuildRawModel(aln) - scorer = modelling.SetupBackboneScorer(mhandle) + modelling.SetupDefaultBackboneScorer(mhandle) modelling.MergeGapsByDistance(mhandle, 1) self.assertEqual(len(mhandle.gaps), 1) - modelling.CloseLargeDeletions(mhandle, scorer, self.structure_db, + modelling.CloseLargeDeletions(mhandle, self.structure_db, num_fragments=100) self.assertEqual(len(mhandle.gaps), 0) # check backbone @@ -562,9 +562,9 @@ class CloseGapsTests(unittest.TestCase): seq.CreateSequence('tpl', 'NGGTLLIPNGTYHFLGIQMKSNVHIRVE')) aln.AttachView(1, tpl.CreateFullView()) mhandle = modelling.BuildRawModel(aln) - scorer = modelling.SetupBackboneScorer(mhandle) + modelling.SetupDefaultBackboneScorer(mhandle) self.assertEqual(len(mhandle.gaps), 1) - modelling.CloseLargeDeletions(mhandle, scorer, self.structure_db, + modelling.CloseLargeDeletions(mhandle, self.structure_db, num_fragments=100) self.assertEqual(len(mhandle.gaps), 0) # check backbone @@ -579,9 +579,9 @@ class CloseGapsTests(unittest.TestCase): aln.AttachView(1, tpl.CreateFullView()) mhandle = modelling.BuildRawModel(aln) modelling.RemoveTerminalGaps(mhandle) - scorer = modelling.SetupBackboneScorer(mhandle) + modelling.SetupDefaultBackboneScorer(mhandle) self.assertEqual(len(mhandle.gaps), 1) - modelling.CloseLargeDeletions(mhandle, scorer, self.structure_db, + modelling.CloseLargeDeletions(mhandle, self.structure_db, num_fragments=100) self.assertEqual(len(mhandle.gaps), 0) # check backbone @@ -602,9 +602,9 @@ class CloseGapsTests(unittest.TestCase): alns.append(aln_A) alns.append(aln_B) mhandle = modelling.BuildRawModel(alns) - scorer = modelling.SetupBackboneScorer(mhandle) + modelling.SetupDefaultBackboneScorer(mhandle) self.assertEqual(len(mhandle.gaps), 2) - modelling.CloseLargeDeletions(mhandle, scorer, self.structure_db, + modelling.CloseLargeDeletions(mhandle, self.structure_db, num_fragments=100) self.assertEqual(len(mhandle.gaps), 0) # check backbone diff --git a/modelling/tests/test_pipeline.py b/modelling/tests/test_pipeline.py index 1afff3ac00b237a201f872fa9bfc8f41a0f855bf..acaa032be02e4ae2ac086480aa5b89fcf505e37c 100644 --- a/modelling/tests/test_pipeline.py +++ b/modelling/tests/test_pipeline.py @@ -44,11 +44,11 @@ from promod3 import loop, modelling, core # io.SavePDB(final_model, 'data/1crn_build.pdb') # # step-by-step - loop # mhandle = modelling.BuildRawModel(aln) -# scorer = modelling.SetupBackboneScorer(mhandle) +# modelling.SetupDefaultBackboneScorer(mhandle) # frag_db = loop.LoadFragDB() # structure_db = loop.LoadStructureDB() # torsion_sampler = loop.LoadTorsionSamplerCoil() -# modelling.FillLoopsByDatabase(mhandle, scorer, frag_db, +# modelling.FillLoopsByDatabase(mhandle, frag_db, # structure_db, # torsion_sampler) # io.SavePDB(mhandle.model, 'data/1crn_rec.pdb') @@ -218,8 +218,8 @@ class PipelineTests(unittest.TestCase): def testLoopReconstruction(self): '''Check loop reconstruction.''' mhandle = self.getRawModel() - scorer = modelling.SetupBackboneScorer(mhandle) - modelling.FillLoopsByDatabase(mhandle, scorer, self.frag_db, + modelling.SetupDefaultBackboneScorer(mhandle) + modelling.FillLoopsByDatabase(mhandle, self.frag_db, self.structure_db, self.torsion_sampler) self.assertEqual(len(mhandle.gaps), 0) diff --git a/scoring/pymod/export_backbone_score.cc b/scoring/pymod/export_backbone_score.cc index 0715d3bf958a7bdb94c35f123e230a8c559e4a95..ad460ebf25cd2ee75a999a05e073756928903aff 100644 --- a/scoring/pymod/export_backbone_score.cc +++ b/scoring/pymod/export_backbone_score.cc @@ -18,18 +18,45 @@ using namespace boost::python; namespace { - BackboneScoreEnvPtr WrapInitOne(const ost::seq::SequenceHandle& seqres){ + BackboneScoreEnvPtr WrapInitSeq(const ost::seq::SequenceHandle& seqres) { ost::seq::SequenceList seq_list = ost::seq::CreateSequenceList(); seq_list.AddSequence(seqres); BackboneScoreEnvPtr env(new BackboneScoreEnv(seq_list)); return env; } - BackboneScoreEnvPtr WrapInitTwo(const ost::seq::SequenceList& seqres){ + BackboneScoreEnvPtr WrapInitSeqList(const ost::seq::SequenceList& seqres) { BackboneScoreEnvPtr env(new BackboneScoreEnv(seqres)); return env; } + BackboneScoreEnvPtr WrapInitStr(const String& seqres) { + ost::seq::SequenceList seq_list = ost::seq::CreateSequenceList(); + ost::seq::SequenceHandle s = ost::seq::CreateSequence("A", seqres); + seq_list.AddSequence(s); + BackboneScoreEnvPtr env(new BackboneScoreEnv(seq_list)); + return env; + } + + BackboneScoreEnvPtr WrapInitStrList(const boost::python::list& seqres) { + ost::seq::SequenceList seq_list = ost::seq::CreateSequenceList(); + for (uint i = 0; i < boost::python::len(seqres); ++i) { + String s = boost::python::extract<String>(seqres[i]); + ost::seq::SequenceHandle sh = ost::seq::CreateSequence("A", s); + seq_list.AddSequence(sh); + } + BackboneScoreEnvPtr env(new BackboneScoreEnv(seq_list)); + return env; + } + + void WrapSetEnvironmentResNum(BackboneScoreEnvPtr env, + const promod3::loop::BackboneList& bb_list, + const ost::mol::ResNum& start_resnum, + uint chain_index) { + uint num = start_resnum.GetNum(); + env->SetEnvironment(bb_list, num, chain_index); + } + void WrapSetPsipredPrediction(BackboneScoreEnvPtr env, loop::PsipredPredictionPtr pp){ env->SetPsipredPrediction(pp); @@ -108,16 +135,27 @@ void export_BackboneScore() { // score environment class_<BackboneScoreEnv, BackboneScoreEnvPtr>("BackboneScoreEnv", no_init) - .def("__init__", make_constructor(&WrapInitOne)) - .def("__init__", make_constructor(&WrapInitTwo)) - .def("SetInitialEnvironment", &BackboneScoreEnv::SetInitialEnvironment,(arg("env_structure"))) - .def("SetEnvironment", &BackboneScoreEnv::SetEnvironment,(arg("env_bb_list"), arg("start_resnum"), arg("chain_idx") = 0)) - .def("ClearEnvironment", &BackboneScoreEnv::ClearEnvironment,(arg("start_resnum"), arg("num_residues"), arg("chain_idx") = 0)) - .def("SetPsipredPrediction", &WrapSetPsipredPrediction,("pred")) - .def("SetPsipredPrediction", &WrapSetPsipredPredictionList,("pred")) - .def("SetMap", &BackboneScoreEnv::SetMap,(arg("map"),arg("resolution"),arg("all_atom")=false)) - .def("AddPairwiseFunction", &BackboneScoreEnv::AddPairwiseFunction,(arg("function"),arg("function_type"))) - .def("ApplyPairwiseFunction", &BackboneScoreEnv::ApplyPairwiseFunction,(arg("chain_idx_one"),arg("resnum_one"),arg("chain_idx_two"),arg("resnum_two"),arg("f_idx"))) + .def("__init__", make_constructor(&WrapInitSeq)) + .def("__init__", make_constructor(&WrapInitSeqList)) + .def("__init__", make_constructor(&WrapInitStr)) + .def("__init__", make_constructor(&WrapInitStrList)) + .def("SetInitialEnvironment", &BackboneScoreEnv::SetInitialEnvironment, + (arg("env_structure"))) + .def("SetEnvironment", &BackboneScoreEnv::SetEnvironment, + (arg("bb_list"), arg("start_resnum"), arg("chain_idx") = 0)) + .def("SetEnvironment", &WrapSetEnvironmentResNum, + (arg("bb_list"), arg("start_resnum"), arg("chain_idx") = 0)) + .def("ClearEnvironment", &BackboneScoreEnv::ClearEnvironment, + (arg("start_resnum"), arg("num_residues"), arg("chain_idx") = 0)) + .def("SetPsipredPrediction", &WrapSetPsipredPrediction, (arg("pred"))) + .def("SetPsipredPrediction", &WrapSetPsipredPredictionList, (arg("pred"))) + .def("SetMap", &BackboneScoreEnv::SetMap, + (arg("map"), arg("resolution"), arg("all_atom")=false)) + .def("AddPairwiseFunction", &BackboneScoreEnv::AddPairwiseFunction, + (arg("function"), arg("function_type"))) + .def("ApplyPairwiseFunction", &BackboneScoreEnv::ApplyPairwiseFunction, + (arg("chain_idx_one"), arg("resnum_one"), arg("chain_idx_two"), + arg("resnum_two"), arg("f_idx"))) .def("GetSeqres", &BackboneScoreEnv::GetSeqres) ; @@ -129,6 +167,7 @@ void export_BackboneScore() { class_<BackboneOverallScorer, BackboneOverallScorerPtr> ("BackboneOverallScorer", init<>()) .def("Contains", &BackboneOverallScorer::Contains, (arg("key"))) + .def("Get", &BackboneOverallScorer::Get, (arg("key"))) .def("__getitem__", &bos_getitem, (arg("key"))) .def("__setitem__", &bos_setitem, (arg("key"), arg("scorer"))) .def("Calculate", &WrapCalculate, diff --git a/scoring/src/backbone_score_base.cc b/scoring/src/backbone_score_base.cc index f5304698a83de4f9e94bae6ace7136ebd61709e0..deff570cc255807cd69b4b8c408b674af38223bc 100644 --- a/scoring/src/backbone_score_base.cc +++ b/scoring/src/backbone_score_base.cc @@ -53,7 +53,7 @@ void IdxHandler::SetupScoreCalculation(const loop::BackboneList& bb_list, end_idx = start_idx + bb_list_size - 1; // let's finally check the range of the end_idx - if (end_idx >= chain_sizes_[chain_idx]) { + if (end_idx >= chain_start_idx_[chain_idx] + chain_sizes_[chain_idx]) { throw promod3::Error("Invalid End ResNum!"); } }