diff --git a/modelling/doc/pipeline.rst b/modelling/doc/pipeline.rst
index 3c2930ab87d67c47e9bba28cc998a4a38b542ea3..2db13068e8ab3637707d0d8b85ce74694cd8af04 100644
--- a/modelling/doc/pipeline.rst
+++ b/modelling/doc/pipeline.rst
@@ -80,26 +80,65 @@ Build Raw Modelling Handle
 
   .. attribute:: backbone_scorer_env
 
-    Backbone score environment attached to this handle. A default environment
-    can be set with :func:`SetupDefaultBackboneScorer`. Additional information
-    can be added to the environment before running the pipeline steps.
+    Backbone score environment attached to this handle. A default environment is
+    set with :func:`SetupDefaultBackboneScoring` when needed. Additional
+    information can be added to the environment before running the pipeline
+    steps.
 
     :type: :class:`~promod3.scoring.BackboneScoreEnv`
 
   .. attribute:: backbone_scorer
 
     Backbone scorer container attached to this handle. A default set of scorers
-    can be initialized with :func:`SetupDefaultBackboneScorer`.
+    is initialized with :func:`SetupDefaultBackboneScoring` when needed.
 
     :type: :class:`~promod3.scoring.BackboneOverallScorer`
 
+  .. attribute:: all_atom_scorer_env
+
+    All atom environment attached to this handle for scoring. A default
+    environment is set with :func:`SetupDefaultAllAtomScoring` when needed. This
+    environment is for temporary work only and is only updated to score loops.
+    It is not to be updated when loops are chosen and added to the final model.
+
+    :type: :class:`~promod3.loop.AllAtomEnv`
+
+  .. attribute:: all_atom_scorer
+
+    All atom scorer container attached to this handle. A default set of scorers
+    is initialized with :func:`SetupDefaultAllAtomScoring` when needed.
+
+    :type: :class:`~promod3.scoring.AllAtomOverallScorer`
+
+  .. attribute:: all_atom_sidechain_env
+
+    All atom environment attached to this handle for sidechain reconstruction. A
+    default environment is set with :func:`SetupDefaultAllAtomScoring` when
+    needed.
+
+    :type: :class:`~promod3.loop.AllAtomEnv`
+
+  .. attribute:: sidechain_reconstructor
+
+    A sidechain reconstructor to add sidechains to loops prior to all atom
+    scoring. A default one is set with :func:`SetupDefaultAllAtomScoring` when
+    needed.
+
+    :type: :class:`~promod3.sidechain.SidechainReconstructor`
+
   .. method:: Copy()
 
     Generates a deep copy. Everything will be copied over to the returned
-    :class:`ModellingHandle`, except the potentially set **backbone_scorer_env**
-    and **backbone_scorer**.
+    :class:`ModellingHandle`, except the potentially set scoring members
+    :attr:`~ModellingHandle.backbone_scorer`,
+    :attr:`~ModellingHandle.backbone_scorer_env`,
+    :attr:`~ModellingHandle.all_atom_scorer_env`,
+    :attr:`~ModellingHandle.all_atom_scorer`,
+    :attr:`~ModellingHandle.all_atom_sidechain_env` and
+    :attr:`~ModellingHandle.sidechain_reconstructor`.
 
-    :returns:           A deep copy of the current handle
+    :return: A deep copy of the current handle
+    :rtype:  :class:`ModellingHandle`
 
 
 .. function:: BuildRawModel(aln, include_ligands=False, chain_names=\
@@ -177,9 +216,9 @@ Modelling Steps
 
 .. autofunction:: BuildFromRawModel
 
-.. function:: SetupDefaultBackboneScorer(mhandle)
+.. function:: SetupDefaultBackboneScoring(mhandle)
 
-    Setup scorers and environment for medling with backbones.
+    Setup scorers and environment for meddling with backbones.
     This one is already tailored towards a certain modelling job.
     The scorers added (with their respective keys) are:
 
@@ -193,8 +232,7 @@ Modelling Steps
     - "pairwise": :class:`~promod3.scoring.PairwiseScorer`
     - "density": :class:`~promod3.scoring.DensityScorer`
 
-    :param mhandle: The modelling handle this scorer should be dedicated to.
-                    This will set the properties
+    :param mhandle: The modelling handle. This will set the properties
                     :attr:`~ModellingHandle.backbone_scorer` and
                     :attr:`~ModellingHandle.backbone_scorer_env` of `mhandle`.
     :type mhandle:  :class:`~promod3.modelling.ModellingHandle`
@@ -207,6 +245,34 @@ Modelling Steps
   :param mhandle: Modelling handle to check.
   :type mhandle:  :class:`ModellingHandle`
 
+.. function:: SetupDefaultAllAtomScoring(mhandle)
+
+    Setup scorers and environment to perform all atom scoring.
+    This one is already tailored towards a certain modelling job, where we
+    reconstruct sidechains for loop candidates and score them.
+    The scorers added (with their respective keys) are:
+
+    - "aa_interaction": :class:`~promod3.scoring.AllAtomInteractionScorer`
+    - "aa_packing": :class:`~promod3.scoring.AllAtomPackingScorer`
+    - "aa_clash": :class:`~promod3.scoring.AllAtomClashScorer`
+
+    :param mhandle: The modelling handle. This will set the properties
+                    :attr:`~ModellingHandle.all_atom_scorer_env`,
+                    :attr:`~ModellingHandle.all_atom_scorer`,
+                    :attr:`~ModellingHandle.all_atom_sidechain_env` and
+                    :attr:`~ModellingHandle.sidechain_reconstructor`.
+    :type mhandle:  :class:`~promod3.modelling.ModellingHandle`
+
+.. function:: IsAllAtomScoringSetUp(mhandle)
+
+  :return: True, if :attr:`~ModellingHandle.all_atom_scorer_env`,
+           :attr:`~ModellingHandle.all_atom_scorer`,
+           :attr:`~ModellingHandle.all_atom_sidechain_env` and
+           :attr:`~ModellingHandle.sidechain_reconstructor` of `mhandle` are set.
+  :rtype:  :class:`bool`
+  :param mhandle: Modelling handle to check.
+  :type mhandle:  :class:`ModellingHandle`
+
 .. function:: RemoveTerminalGaps(mhandle)
 
   Removes terminal gaps without modelling them (just removes them from the list
@@ -298,8 +364,6 @@ Modelling Steps
 
 
 
-
-
 .. autofunction:: CloseGaps
 
 .. autofunction:: CloseSmallDeletions
diff --git a/modelling/pymod/_closegaps.py b/modelling/pymod/_closegaps.py
index 191010924689f6ddb46ac38a945044a8b36a4fbc..0ed500e5689e09124f1245478b81630e49db8c1a 100644
--- a/modelling/pymod/_closegaps.py
+++ b/modelling/pymod/_closegaps.py
@@ -104,19 +104,15 @@ def _CombineScores(all_scores, weights):
     return combined_scores
 
 def _GetBestLC(mhandle, loop_candidates, start_resnum, chain_idx,
-               db_scores={}, all_atom=False):
+               db_scores={}, max_num_all_atom=0):
     # returns (min_idx, min_score)
 
     # dummy check
     if len(loop_candidates) == 0:
         raise RuntimeError("Need at least 1 candidate to choose from!")
-
-    # TODO: move hard-coded setting somewhere else
-    if all_atom:
-        max_num_aa = 5
     
     # setup weights
-    # weights = _GetWeightsOld()
+    all_atom = (max_num_all_atom > 0)
     weights = _GetWeights(bool(db_scores), all_atom)
 
     # setup all scores object (we collect needed scores there)
@@ -145,7 +141,7 @@ def _GetBestLC(mhandle, loop_candidates, start_resnum, chain_idx,
         for i,v in enumerate(non_aa_scores):
             arg_sorted_scores.append((v,i))
         arg_sorted_scores.sort()
-        min_indices = [i for v,i in arg_sorted_scores[:max_num_aa]]
+        min_indices = [i for v,i in arg_sorted_scores[:max_num_all_atom]]
         # extract relevant loop candidates and scores
         aa_loop_candidates = loop_candidates.Extract(min_indices)
         for key in all_scores:
@@ -217,8 +213,18 @@ def _GetGapExtender(mhandle, actual_gap, use_scoring_extender,
             return GapExtender(actual_gap,
                                mhandle.seqres[actual_chain_idx])
 
+def _ResolveLogInfo(gap_orig, optimal_gap, n_candidates, with_db, with_aa):
+    # helper for consistent logging...
+    scor_str = "BB"
+    if with_db:
+        scor_str += "_DB"
+    if with_aa:
+        scor_str += "_AA"
+    ost.LogInfo("Resolved %s by filling %s (%d candidates, %s)" % \
+                (str(gap_orig), str(optimal_gap), n_candidates, scor_str))
+
 def _CloseLoopFrame(mhandle, gap_orig, actual_candidates, actual_extended_gaps,
-                    actual_db_scores=[], all_atom=False):
+                    actual_db_scores=[], max_num_all_atom=0):
     '''Rank candidates with "frame-approach".
     All found candidates are extended prior to scoring so they match in size.
     '''
@@ -274,13 +280,15 @@ def _CloseLoopFrame(mhandle, gap_orig, actual_candidates, actual_extended_gaps,
         # get best
         min_idx, min_score = _GetBestLC(mhandle, final_loop_candidates,
                                         min_before_resnum, actual_chain_idx,
-                                        db_scores, all_atom)
+                                        db_scores, max_num_all_atom)
         ost.LogVerbose("Gap %s - %d candidates, best (min) score %g" %
                        (str(gap_orig), len(final_loop_candidates), min_score))
-
         # resolve loop
         idx_a = back_mapper[min_idx][0]
         idx_b = back_mapper[min_idx][1]
+        _ResolveLogInfo(gap_orig, actual_extended_gaps[idx_a],
+                        len(final_loop_candidates), bool(actual_db_scores),
+                        max_num_all_atom > 0)
         # update model
         start_resnum = actual_extended_gaps[idx_a].before.GetNumber()
         bb_list = actual_candidates[idx_a][idx_b]
@@ -288,17 +296,9 @@ def _CloseLoopFrame(mhandle, gap_orig, actual_candidates, actual_extended_gaps,
         # update score env.
         mhandle.backbone_scorer_env.SetEnvironment(bb_list, start_resnum,
                                                    actual_chain_idx)
-        if all_atom:
+        if IsAllAtomScoringSetUp(mhandle):
             mhandle.all_atom_sidechain_env.SetEnvironment(bb_list, start_resnum,
                                                           actual_chain_idx)
-        scor_str = "BB"
-        if actual_db_scores:
-            scor_str += "_DB"
-        if all_atom:
-            scor_str += "_AA"
-        ost.LogInfo("Resolved %s by filling %s (%d candidates, %s)" % \
-                    (str(gap_orig), str(actual_extended_gaps[idx_a]),
-                     len(final_loop_candidates), scor_str))
         # will return -1 if last gap removed
         return ClearGaps(mhandle, actual_extended_gaps[idx_a])
     else:
@@ -307,7 +307,8 @@ def _CloseLoopFrame(mhandle, gap_orig, actual_candidates, actual_extended_gaps,
 
 
 def _CloseLoopBare(mhandle, gap_orig, actual_candidates, actual_extended_gaps,
-                   actual_db_scores=[], penalize_length=True):
+                   actual_db_scores=[], penalize_length=True,
+                   max_num_all_atom=0):
     '''Rank candidates directly.
     All candidates are scored directly and optionally penalized for gap length.
     '''
@@ -328,7 +329,8 @@ def _CloseLoopBare(mhandle, gap_orig, actual_candidates, actual_extended_gaps,
         if actual_db_scores:
             db_scores = actual_db_scores[i]
         best_idx, score = _GetBestLC(mhandle, loop_candidates, before_resnum,
-                                     actual_chain_idx, db_scores)
+                                     actual_chain_idx, db_scores,
+                                     max_num_all_atom)
         # compare with others
         if penalize_length:
             # penalized by gap length
@@ -344,6 +346,9 @@ def _CloseLoopBare(mhandle, gap_orig, actual_candidates, actual_extended_gaps,
 
     # finally resolve loop
     if optimal_candidate is not None:
+        # report
+        _ResolveLogInfo(gap_orig, optimal_gap, n_candidates,
+                        bool(actual_db_scores), max_num_all_atom > 0)
         # update model
         start_resnum = optimal_gap.before.GetNumber()
         optimal_candidate.InsertInto(mhandle.model.chains[actual_chain_idx],
@@ -352,11 +357,10 @@ def _CloseLoopBare(mhandle, gap_orig, actual_candidates, actual_extended_gaps,
         mhandle.backbone_scorer_env.SetEnvironment(optimal_candidate,
                                                    start_resnum,
                                                    actual_chain_idx)
-        scor_str = "BB"
-        if actual_db_scores:
-            scor_str += "_DB"
-        ost.LogInfo("Resolved %s by filling %s (%d candidates, %s)" % \
-                    (str(gap_orig), str(optimal_gap), n_candidates, scor_str))
+        if IsAllAtomScoringSetUp(mhandle):
+            mhandle.all_atom_sidechain_env.SetEnvironment(optimal_candidate,
+                                                          start_resnum,
+                                                          actual_chain_idx)
         # will return -1 if last gap removed
         return ClearGaps(mhandle, optimal_gap)
     else:
@@ -364,15 +368,17 @@ def _CloseLoopBare(mhandle, gap_orig, actual_candidates, actual_extended_gaps,
         return -2
 
 def _CloseLoop(mhandle, gap_orig, actual_candidates,
-               actual_extended_gaps, variant=0, actual_db_scores=[]):
+               actual_extended_gaps, variant=0, actual_db_scores=[],
+               max_num_all_atom=0):
     '''Choose best scoring loop candidate and close loop in mhandle.
     :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)
-    :param variant: 0 = _CloseLoopFrame(all_atom=False)
+    :param variant: 0 = _CloseLoopFrame()
                     1 = _CloseLoopBare(penalize_length=False)
                     2 = _CloseLoopBare(penalize_length=True)
-                    3 = _CloseLoopFrame(all_atom=True)
+    :param actual_db_scores: List of DB scores (same size as actual_candidates)
+    :param max_num_all_atom: Num. of all atom LC to consider
     :return: gap-index as returned by ClearGaps or -2 if fail.
     '''
     prof = core.StaticRuntimeProfiler.StartScoped('closegaps::_CloseLoop')
@@ -386,14 +392,14 @@ def _CloseLoop(mhandle, gap_orig, actual_candidates,
         ost.LogInfo("Failed at loop insertion (%s)" % str(gap_orig))
         return -2
     # choose variant
-    if variant in [0,3]:
+    if variant == 0:
         return _CloseLoopFrame(mhandle, gap_orig, actual_candidates,
                                actual_extended_gaps, actual_db_scores,
-                               variant == 3)
+                               max_num_all_atom)
     elif variant in [1,2]:
         return _CloseLoopBare(mhandle, gap_orig, actual_candidates,
                               actual_extended_gaps, actual_db_scores,
-                              variant == 2)
+                              variant == 2, max_num_all_atom)
     else:
         raise RuntimeError("Unknown variant %d" % variant);
 
@@ -498,7 +504,7 @@ def CloseSmallDeletions(mhandle, max_extension=9, clash_thresh=1.0,
 
     # check/setup scoring
     if not IsBackboneScoringSetUp(mhandle):
-        SetupDefaultBackboneScorer(mhandle)
+        SetupDefaultBackboneScoring(mhandle)
     clash_scorer = mhandle.backbone_scorer.Get("clash")
 
     # iterating mhandle.gaps. The number of gaps may change during the process,
@@ -664,7 +670,7 @@ def FillLoopsByDatabase(mhandle, fragment_db, structure_db,
                         extended_search=True, use_scoring_extender=True,
                         use_full_extender=True, score_variant=0,
                         ring_punch_detection=1, chain_idx=None,
-                        resnum_range=None):
+                        resnum_range=None, max_num_all_atom=0):
     '''Try to fill up loops from a structural database.
 
     Usually this will extend the gaps a bit to match candidates from the
@@ -731,8 +737,6 @@ def FillLoopsByDatabase(mhandle, fragment_db, structure_db,
                             non-modelled residues!
                           - **1**: score candidates directly
                           - **2**: like **1** but penalize length of candidate
-                          - **3**: like **0** but adding all atom scores
-                                   (slower but slightly more accurate)
                           
     :type score_variant:  :class:`int`
 
@@ -751,6 +755,15 @@ def FillLoopsByDatabase(mhandle, fragment_db, structure_db,
     :param resnum_range: If not None, only gaps within this resnum range get
                          processed
     :type resnum_range: :class:`tuple` containing two :class:`int`
+
+    :param max_num_all_atom: If > 0, we prefilter loop candidates based on
+                             non-all-atom-scores and apply all atom scoring to
+                             the best *max_num_all_atom* candidates. If desired,
+                             *5* is a good value here (larger values give only
+                             numerical improvement). With *5*, this will be
+                             approx. 2x slower than without and will give a
+                             slight improvement in loop selection.
+    :type max_num_all_atom:  :class:`int`
     '''
 
     prof_name = 'closegaps::FillLoopsByDatabase'
@@ -763,31 +776,14 @@ def FillLoopsByDatabase(mhandle, fragment_db, structure_db,
 
     # check/setup scoring
     if not IsBackboneScoringSetUp(mhandle):
-        SetupDefaultBackboneScorer(mhandle)
+        SetupDefaultBackboneScoring(mhandle)
+    if max_num_all_atom > 0 and not IsAllAtomScoringSetUp(mhandle):
+        SetupDefaultAllAtomScoring(mhandle)
 
     # some score variants cannot deal with multiple insertions in one "gap"
-    disallow_ins_merge = (score_variant in [0,3])
+    disallow_ins_merge = (score_variant == 0)
+    # do we want DB features?
     add_db_features = (len(mhandle.profiles) > 0)
-    add_all_atom = (score_variant == 3)
-    # global setup for AA scoring (TODO: move to mhandle cleanly...)
-    if add_all_atom:
-        # scoring
-        aa_scorer = scoring.AllAtomOverallScorer()
-        aa_scorer["aa_interaction"] = scoring.LoadAllAtomInteractionScorer()
-        aa_scorer["aa_packing"] = scoring.LoadAllAtomPackingScorer()
-        aa_scorer["aa_clash"] = scoring.AllAtomClashScorer()
-        aa_score_env = loop.AllAtomEnv(mhandle.seqres)
-        aa_score_env.SetInitialEnvironment(mhandle.model)
-        aa_scorer.AttachEnvironment(aa_score_env)
-        mhandle.all_atom_scorer = aa_scorer
-        mhandle.all_atom_scorer_env = aa_score_env
-        # sidechaining
-        aa_sc_env = loop.AllAtomEnv(mhandle.seqres)
-        aa_sc_env.SetInitialEnvironment(mhandle.model)
-        sc_rec = sidechain.SidechainReconstructor()
-        sc_rec.AttachEnvironment(aa_sc_env)
-        mhandle.all_atom_sidechain_env = aa_sc_env
-        mhandle.sidechain_reconstructor = sc_rec
 
     # check min_loops_required
     if min_loops_required < 0:
@@ -927,7 +923,7 @@ def FillLoopsByDatabase(mhandle, fragment_db, structure_db,
         ##################################
         new_idx = _CloseLoop(mhandle, gap_orig, actual_candidates,
                              actual_extended_gaps, score_variant,
-                             actual_db_scores)
+                             actual_db_scores, max_num_all_atom)
         if new_idx == -2:
             # try next one if we failed
             gap_idx += 1
@@ -1023,7 +1019,7 @@ def FillLoopsByMonteCarlo(mhandle, torsion_sampler, max_loops_to_search=6,
 
     # check/setup scoring
     if not IsBackboneScoringSetUp(mhandle):
-        SetupDefaultBackboneScorer(mhandle)
+        SetupDefaultBackboneScoring(mhandle)
 
     # disable AllAtom scoring here
     if score_variant == 3:
@@ -1306,7 +1302,7 @@ def ModelTermini(mhandle, torsion_sampler, fragger_handles=None,
 
     # check/setup scoring
     if not IsBackboneScoringSetUp(mhandle):
-        SetupDefaultBackboneScorer(mhandle)
+        SetupDefaultBackboneScoring(mhandle)
 
     # model them
     for actual_gap in terminal_gaps:
@@ -1439,7 +1435,7 @@ def CloseLargeDeletions(mhandle, structure_db, linker_length=8,
 
     # check/setup scoring
     if not IsBackboneScoringSetUp(mhandle):
-        SetupDefaultBackboneScorer(mhandle)
+        SetupDefaultBackboneScoring(mhandle)
 
     # point to the current gap
     gap_idx = 0
diff --git a/modelling/pymod/_mtm.py b/modelling/pymod/_mtm.py
index 90cd6fdcce367c43ba2d04f33d7e7ee4bbef44cb..4e7385ee7680b642b6a32121153a7f5ae2739580 100644
--- a/modelling/pymod/_mtm.py
+++ b/modelling/pymod/_mtm.py
@@ -560,7 +560,7 @@ def _FindNonOverlappingExtension(seed_rawmodel, arm,
     copied_arm = arm.Copy()
 
     ost.PushVerbosityLevel(0)
-    SetupDefaultBackboneScorer(copied_arm)    
+    SetupDefaultBackboneScoring(copied_arm)
     CloseGaps(copied_arm, chain_idx = arm_ch_idx, resnum_range = arm_range)
     ost.PopVerbosityLevel()
 
@@ -822,7 +822,7 @@ def _FindOverlappingExtension(seed_rawmodel, arm,
     copied_arm = arm.Copy()
     arm_chain = copied_arm.model.chains[arm_ch_idx]
     ost.PushVerbosityLevel(0)
-    SetupDefaultBackboneScorer(copied_arm)
+    SetupDefaultBackboneScoring(copied_arm)
     if termini_type == "nter":
         CloseGaps(copied_arm, chain_idx = arm_ch_idx,
                   resnum_range = (1, rb_end_rnum))
@@ -972,7 +972,7 @@ def ModelExtensions(seed_rawmodel, alternative_rawmodels,
 
     # make sure the seed has a scorer
     if not IsBackboneScoringSetUp(seed_rawmodel):
-        SetupDefaultBackboneScorer(seed_rawmodel)
+        SetupDefaultBackboneScoring(seed_rawmodel)
     
     # assign default weights if not given
     if scoring_weights == None:
diff --git a/modelling/pymod/_pipeline.py b/modelling/pymod/_pipeline.py
index acc14cf57955f881310a76d999b4da13968bdbf2..ccfae92766986d40b3d36192f18c18190221f2f6 100644
--- a/modelling/pymod/_pipeline.py
+++ b/modelling/pymod/_pipeline.py
@@ -415,10 +415,10 @@ def BuildFromRawModel(mhandle, alternative_mhandles=None,
     modelling pipeline. For reproducibility, we recommend that you keep copies
     of custom pipelines.
 
-    If you wish to adapt the scoring used during loop closing, you can set the
-    scorers manually, but you must ensure consistency yourself! Alternatively,
-    you can call :func:`SetupDefaultBackboneScorer` and adapt the default scorer
-    and score environment for your purposes.
+    To adapt the scoring used during loop closing, you can call
+    :func:`SetupDefaultBackboneScoring` and :func:`SetupDefaultAllAtomScoring`
+    and adapt the default scoring members. Alternatively, you can setup the
+    scoring manually, but you must ensure consistency yourself!
 
     If the function fails to close all gaps, it will produce a warning and
     return an incomplete model.
diff --git a/modelling/pymod/export_model.cc b/modelling/pymod/export_model.cc
index 8781f1b2c28ae557b3fc13d3c2a875e1f94edbf9..542934720aa121d053924c05e262e32fd70abd0c 100644
--- a/modelling/pymod/export_model.cc
+++ b/modelling/pymod/export_model.cc
@@ -23,7 +23,7 @@ int WrapCountEnclosedIns(ModellingHandle& mhandle, const StructuralGap& gap) {
   return CountEnclosedGaps(mhandle, gap, true);
 }
 
-promod3::scoring::BackboneOverallScorerPtr 
+promod3::scoring::BackboneOverallScorerPtr
 WrapGetBackboneScorer(ModellingHandle& mhandle) {
   if (!mhandle.backbone_scorer) {
     throw promod3::Error("The backbone_scorer must be properly initialized "
@@ -32,12 +32,12 @@ WrapGetBackboneScorer(ModellingHandle& mhandle) {
   return mhandle.backbone_scorer;
 }
 
-void WrapSetBackboneScorer(ModellingHandle& mhandle, 
+void WrapSetBackboneScorer(ModellingHandle& mhandle,
                            promod3::scoring::BackboneOverallScorerPtr scorer) {
   mhandle.backbone_scorer = scorer;
 }
 
-promod3::scoring::BackboneScoreEnvPtr 
+promod3::scoring::BackboneScoreEnvPtr
 WrapGetBackboneScorerEnv(ModellingHandle& mhandle) {
   if (!mhandle.backbone_scorer_env) {
     throw promod3::Error("The backbone_scorer_env must be properly initialized "
@@ -46,11 +46,67 @@ WrapGetBackboneScorerEnv(ModellingHandle& mhandle) {
   return mhandle.backbone_scorer_env;
 }
 
-void WrapSetBackboneScorerEnv(ModellingHandle& mhandle, 
+void WrapSetBackboneScorerEnv(ModellingHandle& mhandle,
                               promod3::scoring::BackboneScoreEnvPtr env) {
   mhandle.backbone_scorer_env = env;
 }
 
+promod3::scoring::AllAtomOverallScorerPtr
+WrapGetAllAtomScorer(ModellingHandle& mhandle) {
+  if (!mhandle.all_atom_scorer) {
+    throw promod3::Error("The all_atom_scorer must be properly initialized "
+                         "before it can be used!");
+  }
+  return mhandle.all_atom_scorer;
+}
+
+void WrapSetAllAtomScorer(ModellingHandle& mhandle,
+                          promod3::scoring::AllAtomOverallScorerPtr scorer) {
+  mhandle.all_atom_scorer = scorer;
+}
+
+promod3::loop::AllAtomEnvPtr
+WrapGetAllAtomScorerEnv(ModellingHandle& mhandle) {
+  if (!mhandle.all_atom_scorer_env) {
+    throw promod3::Error("The all_atom_scorer_env must be properly initialized "
+                         "before it can be used!");
+  }
+  return mhandle.all_atom_scorer_env;
+}
+
+void WrapSetAllAtomScorerEnv(ModellingHandle& mhandle,
+                             promod3::loop::AllAtomEnvPtr env) {
+  mhandle.all_atom_scorer_env = env;
+}
+
+promod3::loop::AllAtomEnvPtr
+WrapGetAllAtomSidechainEnv(ModellingHandle& mhandle) {
+  if (!mhandle.all_atom_sidechain_env) {
+    throw promod3::Error("The all_atom_sidechain_env must be properly "
+                         "initialized before it can be used!");
+  }
+  return mhandle.all_atom_sidechain_env;
+}
+
+void WrapSetAllAtomSidechainEnv(ModellingHandle& mhandle,
+                                promod3::loop::AllAtomEnvPtr env) {
+  mhandle.all_atom_sidechain_env = env;
+}
+
+promod3::sidechain::SidechainReconstructorPtr
+WrapGetSidechainRec(ModellingHandle& mhandle) {
+  if (!mhandle.sidechain_reconstructor) {
+    throw promod3::Error("The sidechain_reconstructor must be properly "
+                         "initialized before it can be used!");
+  }
+  return mhandle.sidechain_reconstructor;
+}
+
+void WrapSetSidechainRec(ModellingHandle& mhandle,
+                         promod3::sidechain::SidechainReconstructorPtr sc_rec) {
+  mhandle.sidechain_reconstructor = sc_rec;
+}
+
 void WrapSetSequenceProfiles(ModellingHandle& mhandle,
                              const boost::python::list& profiles){
   ost::seq::ProfileHandleList v_profiles;
@@ -82,7 +138,7 @@ boost::python::list WrapProfileAccess(ModellingHandle& mhandle){
 void export_model()
 {
   class_<ModellingHandle>("ModellingHandle", init<>())
-    .def("Copy",&ModellingHandle::Copy)
+    .def("Copy", &ModellingHandle::Copy)
     .def_readwrite("model", &ModellingHandle::model)
     .def_readwrite("gaps", &ModellingHandle::gaps)
     .add_property("seqres", &ModellingHandle::seqres)
@@ -92,6 +148,14 @@ void export_model()
                                      &WrapSetBackboneScorer)
     .add_property("backbone_scorer_env", &WrapGetBackboneScorerEnv,
                                          &WrapSetBackboneScorerEnv)
+    .add_property("all_atom_scorer", &WrapGetAllAtomScorer,
+                                     &WrapSetAllAtomScorer)
+    .add_property("all_atom_scorer_env", &WrapGetAllAtomScorerEnv,
+                                         &WrapSetAllAtomScorerEnv)
+    .add_property("all_atom_sidechain_env", &WrapGetAllAtomSidechainEnv,
+                                            &WrapSetAllAtomSidechainEnv)
+    .add_property("sidechain_reconstructor", &WrapGetSidechainRec,
+                                             &WrapSetSidechainRec)
   ;
 
   def("ClearGaps", ClearGaps, (arg("mhandle"),arg("gap")));
@@ -102,8 +166,12 @@ void export_model()
   def("MergeGaps", MergeGaps, (arg("mhandle"),arg("index")));
   def("RemoveTerminalGaps", RemoveTerminalGaps, (arg("mhandle")));
   def("ReorderGaps", &ReorderGaps, (arg("mhandle")));
-  def("SetupDefaultBackboneScorer", &SetupDefaultBackboneScorer,
+  def("SetupDefaultBackboneScoring", &SetupDefaultBackboneScoring,
       (arg("mhandle")));
+  def("IsBackboneScoringSetUp", &IsBackboneScoringSetUp, (arg("mhandle")));
+  def("SetupDefaultAllAtomScoring", &SetupDefaultAllAtomScoring,
+      (arg("mhandle")));
+  def("IsAllAtomScoringSetUp", &IsAllAtomScoringSetUp, (arg("mhandle")));
   def("SetSequenceProfiles", &WrapSetSequenceProfiles,
       (arg("mhandle"), arg("profiles")));
   def("SetPsipredPredictions", &WrapSetPsipredPredictions,
@@ -116,7 +184,6 @@ void export_model()
                                       arg("end_resnum"),
                                       arg("transform"),
                                       arg("reset_scoring_env") = true));
-  def("IsBackboneScoringSetUp", &IsBackboneScoringSetUp, (arg("mhandle")));
   def("BuildRawModel", BuildRawModelHandle, 
       (arg("aln"),
        arg("include_ligands")=false,
diff --git a/modelling/src/gap.cc b/modelling/src/gap.cc
index 46f18c3e40ee5c080fb512cf906618ff388be058..df052586abaab7fa9dea6db806a4f713647a4ed8 100644
--- a/modelling/src/gap.cc
+++ b/modelling/src/gap.cc
@@ -1,6 +1,6 @@
 #include <ost/log.hh>
 
-#include "gap.hh"
+#include <promod3/modelling/gap.hh>
 
 using namespace ost::mol;
 using namespace ost;
diff --git a/modelling/src/model.cc b/modelling/src/model.cc
index 5cd31c4cd0bf1e220132cb2dec89bf82070c3b8d..59371f1cfee9d87823b5d480407b4df37234190f 100644
--- a/modelling/src/model.cc
+++ b/modelling/src/model.cc
@@ -11,11 +11,12 @@
 #include <ost/conop/compound_lib.hh>
 #include <promod3/core/geom_base.hh>
 #include <promod3/core/runtime_profiling.hh>
-#include <promod3/scoring/scoring_object_loader.hh>
-#include <promod3/scoring/pairwise_score.hh>
-#include <promod3/scoring/density_score.hh>
+#include <promod3/scoring/all_atom_clash_score.hh>
 #include <promod3/scoring/clash_score.hh>
-#include "model.hh"
+#include <promod3/scoring/density_score.hh>
+#include <promod3/scoring/pairwise_score.hh>
+#include <promod3/scoring/scoring_object_loader.hh>
+#include <promod3/modelling/model.hh>
 
 using namespace ost::mol;
 using namespace ost;
@@ -280,7 +281,7 @@ void ReorderGaps(ModellingHandle& mhandle){
   mhandle.gaps = sorted_gaps;
 }
 
-void SetupDefaultBackboneScorer(ModellingHandle& mhandle){
+void SetupDefaultBackboneScoring(ModellingHandle& mhandle){
   
   // setup environment
   BackboneScoreEnvPtr env(new BackboneScoreEnv(mhandle.seqres));
@@ -301,7 +302,34 @@ void SetupDefaultBackboneScorer(ModellingHandle& mhandle){
 
   mhandle.backbone_scorer_env = env;
   mhandle.backbone_scorer = scorer;
-  LOG_INFO("Initialized default backbone scorer for modelling.");
+  LOG_INFO("Initialized default backbone scoring for modelling.");
+}
+
+void SetupDefaultAllAtomScoring(ModellingHandle& mhandle){
+  
+  // setup scoring
+  loop::AllAtomEnvPtr env(new loop::AllAtomEnv(mhandle.seqres));
+  env->SetInitialEnvironment(mhandle.model);
+  AllAtomOverallScorerPtr scorer(new AllAtomOverallScorer);
+  (*scorer)["aa_interaction"] = LoadAllAtomInteractionScorer();
+  (*scorer)["aa_packing"] = LoadAllAtomPackingScorer();
+  (*scorer)["aa_clash"] = AllAtomClashScorerPtr(new AllAtomClashScorer);
+  scorer->AttachEnvironment(*env);
+
+  // setup sidechaining needed for scoring
+  loop::AllAtomEnvPtr env_sc(new loop::AllAtomEnv(mhandle.seqres));
+  env_sc->SetInitialEnvironment(mhandle.model);
+  sidechain::SidechainReconstructorPtr sc_rec;
+  sc_rec.reset(new sidechain::SidechainReconstructor);
+  sc_rec->AttachEnvironment(*env_sc);
+
+  // set mhandle values
+  mhandle.all_atom_scorer_env = env;
+  mhandle.all_atom_scorer = scorer;
+  mhandle.all_atom_sidechain_env = env_sc;
+  mhandle.sidechain_reconstructor = sc_rec;
+
+  LOG_INFO("Initialized default all atom scoring for modelling.");
 }
 
 void SetSequenceProfiles(ModellingHandle& mhandle, 
diff --git a/modelling/src/model.hh b/modelling/src/model.hh
index 330dc17209050df5e1cb3f2b62e3e5dde986e2ea..8ef7ac4044c857464bb300ffbf326ac5b5ab760a 100644
--- a/modelling/src/model.hh
+++ b/modelling/src/model.hh
@@ -4,13 +4,15 @@
 #include <ost/seq/alignment_handle.hh>
 #include <ost/seq/sequence_list.hh>
 
+#include <ost/seq/profile_handle.hh>
 #include <promod3/core/message.hh>
+#include <promod3/loop/all_atom_env.hh>
 #include <promod3/loop/psipred_prediction.hh>
-#include <ost/seq/profile_handle.hh>
-#include <promod3/scoring/backbone_score_base.hh>
+#include <promod3/modelling/gap.hh>
+#include <promod3/scoring/all_atom_overall_scorer.hh>
 #include <promod3/scoring/backbone_overall_scorer.hh>
-
-#include "gap.hh"
+#include <promod3/scoring/backbone_score_base.hh>
+#include <promod3/sidechain/sidechain_reconstructor.hh>
 
 namespace promod3 { namespace modelling {
 
@@ -40,6 +42,10 @@ struct ModellingHandle {
   ost::seq::ProfileHandleList profiles;
   promod3::scoring::BackboneScoreEnvPtr backbone_scorer_env;
   promod3::scoring::BackboneOverallScorerPtr backbone_scorer;
+  promod3::loop::AllAtomEnvPtr all_atom_scorer_env; // tmp only for scoring
+  promod3::scoring::AllAtomOverallScorerPtr all_atom_scorer;
+  promod3::loop::AllAtomEnvPtr all_atom_sidechain_env;
+  promod3::sidechain::SidechainReconstructorPtr sidechain_reconstructor;
 };
 
 // see Python doc
@@ -59,12 +65,22 @@ int RemoveTerminalGaps(ModellingHandle& mhandle);
 void ReorderGaps(ModellingHandle& mhandle);
 
 // see Python doc
-void SetupDefaultBackboneScorer(ModellingHandle& mhandle);
+void SetupDefaultBackboneScoring(ModellingHandle& mhandle);
 // see Python doc
 inline bool IsBackboneScoringSetUp(ModellingHandle& mhandle) {
   return bool(mhandle.backbone_scorer) && bool(mhandle.backbone_scorer_env);
 }
 
+// see Python doc
+void SetupDefaultAllAtomScoring(ModellingHandle& mhandle);
+// see Python doc
+inline bool IsAllAtomScoringSetUp(ModellingHandle& mhandle) {
+  return    bool(mhandle.all_atom_scorer_env)
+         && bool(mhandle.all_atom_scorer)
+         && bool(mhandle.all_atom_sidechain_env)
+         && bool(mhandle.sidechain_reconstructor);
+}
+
 // see Python doc
 void SetSequenceProfiles(ModellingHandle& mhandle, 
                          const ost::seq::ProfileHandleList& profiles);