diff --git a/loop/pymod/CMakeLists.txt b/loop/pymod/CMakeLists.txt
index aa24d300115eb879c8fc6cc0b9043ca4661c6e63..73227c37add89c571803a481160540a938e1a15c 100644
--- a/loop/pymod/CMakeLists.txt
+++ b/loop/pymod/CMakeLists.txt
@@ -15,6 +15,7 @@ wrap_loop.cc
 
 set(LOOP_PYMOD
 __init__.py
+_fragger.py
 )
 
 pymod(NAME loop CPP ${LOOP_CPP} PY ${LOOP_PYMOD})
diff --git a/loop/pymod/__init__.py b/loop/pymod/__init__.py
index deb832b06e6ae037c1805c83b63870610c01c5c5..e760a6c05a5b0f9d1eb9f1d0fd72646ca9b79a90 100644
--- a/loop/pymod/__init__.py
+++ b/loop/pymod/__init__.py
@@ -1,169 +1,3 @@
-'''__init__.py of the loop module
-'''
+"""Initialise the loop module."""
 from _loop import *
-
-# TODO: extract this into some _....py file and import here (like in modelling)
-from ost.conop import OneLetterCodeToResidueName
-
-def _AssembleTorsionSamplers(psipred_pred,
-                             torsion_sampler_coil,
-                             torsion_sampler_helix,
-                             torsion_sampler_extended):
-
-    samplers = [torsion_sampler_coil]*len(psipred_pred)
-    for i in range(len(psipred_pred)):
-        if psipred_pred.GetPrediction(i) == 'H' and psipred_pred.GetConfidence(i) >= 6:
-            samplers[i] = torsion_sampler_helix  
-        if psipred_pred.GetPrediction(i) == 'E' and psipred_pred.GetConfidence(i) >= 6:
-            samplers[i] = torsion_sampler_extended
-    return samplers
-
-def _GenerateFragger(prof,psipred_pred,
-                     num_fragments,
-                     rmsd_thresh,
-                     ss_agreement_weight,
-                     sequence_profile_weight,
-                     structure_profile_weight,
-                     torsion_weight,
-                     aa_before,
-                     aa_after,
-                     structure_db,
-                     torsion_sampler_coil,
-                     torsion_sampler_helix,
-                     torsion_sampler_extended):
-    
-    torsion_samplers = _AssembleTorsionSamplers(psipred_pred,
-                                                torsion_sampler_coil,
-                                                torsion_sampler_helix,
-                                                torsion_sampler_extended)
-
-    fragger = Fragger(prof.sequence)
-    fragger.AddSSAgreeParameters(ss_agreement_weight,psipred_pred)
-    fragger.AddSequenceProfileParameters(sequence_profile_weight,prof)
-    fragger.AddStructureProfileParameters(structure_profile_weight,prof)
-    fragger.AddTorsionProbabilityParameters(torsion_weight,torsion_samplers,
-                                            aa_before,aa_after)
-
-    fragger.Fill(structure_db,rmsd_thresh,num_fragments)
-
-    return fragger
-
-
-def GenerateFragger(prof, psipred_pred, 
-                    num_fragments = 100,
-                    rmsd_thresh = 0.0, 
-                    ss_agreement_weight = 1.0, 
-                    sequence_profile_weight = 0.8, 
-                    structure_profile_weight = 2.0,
-                    torsion_weight = 13.0,
-                    aa_before = "ALA",
-                    aa_after = "ALA",
-                    structure_db = None,
-                    torsion_sampler_coil = None,
-                    torsion_sampler_helix = None,
-                    torsion_sampler_extended = None):
-
-    if len(prof) != len(psipred_pred):
-        raise ValueError("Length of profile must be consistent with Psipred!")
-
-    if structure_db == None:
-        structure_db = LoadStructureDB()
-
-    if torsion_sampler_coil == None:
-        torsion_sampler_coil = LoadTorsionSamplerCoil()
-
-    if torsion_sampler_helix == None:
-        torsion_sampler_helix = LoadTorsionSamplerHelical()
-
-    if torsion_sampler_extended == None:
-        torsion_sampler_extended = LoadTorsionSamplerExtended()
-
-    if len(aa_before) == 1:
-        #seems to be a one_letter_code, let's try our best
-        aa_before = OneLetterCodeToResidueName(aa_before)
-
-    if len(aa_after) == 1:
-        #seems to be a one_letter_code, let's try our best
-        aa_after = OneLetterCodeToResidueName(aa_after)
-
-    return _GenerateFragger(prof, psipred_pred, 
-                            num_fragments,
-                            rmsd_thresh, 
-                            ss_agreement_weight, 
-                            sequence_profile_weight, 
-                            structure_profile_weight,
-                            torsion_weight,
-                            aa_before,
-                            aa_after,
-                            structure_db,
-                            torsion_sampler_coil,
-                            torsion_sampler_helix,
-                            torsion_sampler_extended)
-
-
-def GenerateFraggerList(prof, psipred_pred,
-                        fragment_length = 9,
-                        fragments_per_position = 100,
-                        rmsd_thresh = 0.0, 
-                        ss_agreement_weight = 1.0, 
-                        sequence_profile_weight = 0.8, 
-                        structure_profile_weight = 2.0,
-                        torsion_weight = 13.0,
-                        structure_db = None,
-                        torsion_sampler_coil = None,
-                        torsion_sampler_helix = None,
-                        torsion_sampler_extended = None):
-
-
-    if len(prof) != len(psipred_pred):
-        raise ValueError("Length of profile must be consistent with Psipred!")
-
-    if structure_db == None:
-        structure_db = LoadStructureDB()
-
-    if torsion_sampler_coil == None:
-        torsion_sampler_coil = LoadTorsionSamplerCoil()
-
-    if torsion_sampler_helix == None:
-        torsion_sampler_helix = LoadTorsionSamplerHelical()
-
-    if torsion_sampler_extended == None:
-        torsion_sampler_extended = LoadTorsionSamplerExtended()
-
-    sequence = prof.sequence
-    num_positions = len(sequence) - fragment_length + 1
-
-    fragger_list = list()
-
-    for i in range(num_positions):
-
-        aa_before = "ALA"
-        aa_after = "ALA"
-
-        if i > 0:
-            aa_before = OneLetterCodeToResidueName(sequence[i-1])
-
-        if i + fragment_length < len(sequence):
-            aa_after = OneLetterCodeToResidueName(sequence[i+fragment_length])
-
-        sub_prof = prof.Extract(i,i+fragment_length)
-        sub_psipred_pred = psipred_pred.Extract(i,i+fragment_length)
-
-        fragger = _GenerateFragger(sub_prof, sub_psipred_pred, 
-                                   fragments_per_position,
-                                   rmsd_thresh, 
-                                   ss_agreement_weight, 
-                                   sequence_profile_weight, 
-                                   structure_profile_weight,
-                                   torsion_weight,
-                                   aa_before,
-                                   aa_before,
-                                   structure_db,
-                                   torsion_sampler_coil,
-                                   torsion_sampler_helix,
-                                   torsion_sampler_extended)
-
-        fragger_list.append(fragger)
-
-    return fragger_list
-
+from _fragger import *
diff --git a/loop/pymod/_fragger.py b/loop/pymod/_fragger.py
new file mode 100644
index 0000000000000000000000000000000000000000..63759f705b8f1fcf80d8e2ac2b0deb2d79d4e7ea
--- /dev/null
+++ b/loop/pymod/_fragger.py
@@ -0,0 +1,171 @@
+'''Python functionality to generate fraggers.'''
+
+# internal
+from _loop import *
+# external
+from ost.conop import OneLetterCodeToResidueName
+
+def _AssembleTorsionSamplers(psipred_pred,
+                             torsion_sampler_coil,
+                             torsion_sampler_helix,
+                             torsion_sampler_extended):
+
+    samplers = [torsion_sampler_coil]*len(psipred_pred)
+    for i in range(len(psipred_pred)):
+        if psipred_pred.GetPrediction(i) == 'H' and psipred_pred.GetConfidence(i) >= 6:
+            samplers[i] = torsion_sampler_helix  
+        if psipred_pred.GetPrediction(i) == 'E' and psipred_pred.GetConfidence(i) >= 6:
+            samplers[i] = torsion_sampler_extended
+    return samplers
+
+def _GenerateFragger(prof,psipred_pred,
+                     num_fragments,
+                     rmsd_thresh,
+                     ss_agreement_weight,
+                     sequence_profile_weight,
+                     structure_profile_weight,
+                     torsion_weight,
+                     aa_before,
+                     aa_after,
+                     structure_db,
+                     torsion_sampler_coil,
+                     torsion_sampler_helix,
+                     torsion_sampler_extended):
+    
+    torsion_samplers = _AssembleTorsionSamplers(psipred_pred,
+                                                torsion_sampler_coil,
+                                                torsion_sampler_helix,
+                                                torsion_sampler_extended)
+
+    fragger = Fragger(prof.sequence)
+    fragger.AddSSAgreeParameters(ss_agreement_weight,psipred_pred)
+    fragger.AddSequenceProfileParameters(sequence_profile_weight,prof)
+    fragger.AddStructureProfileParameters(structure_profile_weight,prof)
+    fragger.AddTorsionProbabilityParameters(torsion_weight,torsion_samplers,
+                                            aa_before,aa_after)
+
+    fragger.Fill(structure_db,rmsd_thresh,num_fragments)
+
+    return fragger
+
+
+def GenerateFragger(prof, psipred_pred, 
+                    num_fragments = 100,
+                    rmsd_thresh = 0.0, 
+                    ss_agreement_weight = 1.0, 
+                    sequence_profile_weight = 0.8, 
+                    structure_profile_weight = 2.0,
+                    torsion_weight = 13.0,
+                    aa_before = "ALA",
+                    aa_after = "ALA",
+                    structure_db = None,
+                    torsion_sampler_coil = None,
+                    torsion_sampler_helix = None,
+                    torsion_sampler_extended = None):
+
+    if len(prof) != len(psipred_pred):
+        raise ValueError("Length of profile must be consistent with Psipred!")
+
+    if structure_db == None:
+        structure_db = LoadStructureDB()
+
+    if torsion_sampler_coil == None:
+        torsion_sampler_coil = LoadTorsionSamplerCoil()
+
+    if torsion_sampler_helix == None:
+        torsion_sampler_helix = LoadTorsionSamplerHelical()
+
+    if torsion_sampler_extended == None:
+        torsion_sampler_extended = LoadTorsionSamplerExtended()
+
+    if len(aa_before) == 1:
+        #seems to be a one_letter_code, let's try our best
+        aa_before = OneLetterCodeToResidueName(aa_before)
+
+    if len(aa_after) == 1:
+        #seems to be a one_letter_code, let's try our best
+        aa_after = OneLetterCodeToResidueName(aa_after)
+
+    return _GenerateFragger(prof, psipred_pred, 
+                            num_fragments,
+                            rmsd_thresh, 
+                            ss_agreement_weight, 
+                            sequence_profile_weight, 
+                            structure_profile_weight,
+                            torsion_weight,
+                            aa_before,
+                            aa_after,
+                            structure_db,
+                            torsion_sampler_coil,
+                            torsion_sampler_helix,
+                            torsion_sampler_extended)
+
+
+def GenerateFraggerList(prof, psipred_pred,
+                        fragment_length = 9,
+                        fragments_per_position = 100,
+                        rmsd_thresh = 0.0, 
+                        ss_agreement_weight = 1.0, 
+                        sequence_profile_weight = 0.8, 
+                        structure_profile_weight = 2.0,
+                        torsion_weight = 13.0,
+                        structure_db = None,
+                        torsion_sampler_coil = None,
+                        torsion_sampler_helix = None,
+                        torsion_sampler_extended = None):
+
+
+    if len(prof) != len(psipred_pred):
+        raise ValueError("Length of profile must be consistent with Psipred!")
+
+    if structure_db == None:
+        structure_db = LoadStructureDB()
+
+    if torsion_sampler_coil == None:
+        torsion_sampler_coil = LoadTorsionSamplerCoil()
+
+    if torsion_sampler_helix == None:
+        torsion_sampler_helix = LoadTorsionSamplerHelical()
+
+    if torsion_sampler_extended == None:
+        torsion_sampler_extended = LoadTorsionSamplerExtended()
+
+    sequence = prof.sequence
+    num_positions = len(sequence) - fragment_length + 1
+
+    fragger_list = list()
+
+    for i in range(num_positions):
+
+        aa_before = "ALA"
+        aa_after = "ALA"
+
+        if i > 0:
+            aa_before = OneLetterCodeToResidueName(sequence[i-1])
+
+        if i + fragment_length < len(sequence):
+            aa_after = OneLetterCodeToResidueName(sequence[i+fragment_length])
+
+        sub_prof = prof.Extract(i,i+fragment_length)
+        sub_psipred_pred = psipred_pred.Extract(i,i+fragment_length)
+
+        fragger = _GenerateFragger(sub_prof, sub_psipred_pred, 
+                                   fragments_per_position,
+                                   rmsd_thresh, 
+                                   ss_agreement_weight, 
+                                   sequence_profile_weight, 
+                                   structure_profile_weight,
+                                   torsion_weight,
+                                   aa_before,
+                                   aa_before,
+                                   structure_db,
+                                   torsion_sampler_coil,
+                                   torsion_sampler_helix,
+                                   torsion_sampler_extended)
+
+        fragger_list.append(fragger)
+
+    return fragger_list
+
+# these methods will be exported into module
+__all__ = ('GenerateFragger', 'GenerateFraggerList',)
diff --git a/modelling/pymod/__init__.py b/modelling/pymod/__init__.py
index e1f66ecc45c3fd4bc9e9532fe527daeac94e1128..67f70831467adf6707d4c14826b295738ba8d75e 100644
--- a/modelling/pymod/__init__.py
+++ b/modelling/pymod/__init__.py
@@ -1,6 +1,4 @@
-"""
-Initialise the modelling module.
-"""
+"""Initialise the modelling module."""
 from _modelling import *
 from _closegaps import *
 from _pipeline import *
\ No newline at end of file
diff --git a/modelling/pymod/_closegaps.py b/modelling/pymod/_closegaps.py
index 048a8ea025b1e38fb4471c50822b471354b566b2..8cbf086b15ad964e697de80e19b0997bcb2a6818 100644
--- a/modelling/pymod/_closegaps.py
+++ b/modelling/pymod/_closegaps.py
@@ -3,10 +3,11 @@ __init__.py file. To be used directly by passing a ModellingHandle instance
 as argument.
 '''
 
-import ost
-#pylint: disable=no-name-in-module
-from . import _modelling as modelling
+# internal
 from promod3 import loop
+from _modelling import *
+# external
+import ost
 import sys
 
 ###############################################################################
@@ -25,22 +26,22 @@ def _GetGapExtender(mhandle, actual_gap, use_scoring_extender,
                 extender_penalties[num-1] = 1.0
         # setup scoring extender
         if use_full_extender:
-            return modelling.ScoringGapExtender(actual_gap, 0.8,
-                                    extender_penalties,
-                                    mhandle.seqres[actual_chain_idx],
-                                    max_length)
+            return ScoringGapExtender(actual_gap, 0.8,
+                                      extender_penalties,
+                                      mhandle.seqres[actual_chain_idx],
+                                      max_length)
         else:
-            return modelling.ScoringGapExtender(actual_gap, 0.8,
-                                    extender_penalties,
-                                    mhandle.seqres[actual_chain_idx])
+            return ScoringGapExtender(actual_gap, 0.8,
+                                      extender_penalties,
+                                      mhandle.seqres[actual_chain_idx])
     else:
         if use_full_extender:
-            return modelling.FullGapExtender(actual_gap,
-                                    mhandle.seqres[actual_chain_idx],
-                                    max_length)
+            return FullGapExtender(actual_gap,
+                                   mhandle.seqres[actual_chain_idx],
+                                   max_length)
         else:
-            return modelling.GapExtender(actual_gap,
-                                    mhandle.seqres[actual_chain_idx])
+            return GapExtender(actual_gap,
+                               mhandle.seqres[actual_chain_idx])
 
 def _GetWeights():
     # weights optimized by Niklaus Johner
@@ -132,7 +133,7 @@ def _CloseLoopFrame(mhandle, scorer, gap_orig, actual_candidates,
                      str(actual_extended_gaps[idx_a]),
                      len(final_loop_candidates)))
         # will return -1 if last gap removed
-        return modelling.ClearGaps(mhandle, actual_extended_gaps[idx_a])
+        return ClearGaps(mhandle, actual_extended_gaps[idx_a])
     else:
         ost.LogInfo("Failed at loop insertion (%s)" % str(gap_orig))
         return -2
@@ -189,7 +190,7 @@ def _CloseLoopBare(mhandle, scorer, gap_orig, actual_candidates,
         ost.LogInfo("Resolved %s by filling %s (%d candidates)" % \
                     (str(gap_orig), str(optimal_gap), n_candidates))
         # will return -1 if last gap removed
-        return modelling.ClearGaps(mhandle, optimal_gap)
+        return ClearGaps(mhandle, optimal_gap)
     else:
         ost.LogInfo("Failed at loop insertion (%s)" % str(gap_orig))
         return -2
@@ -363,7 +364,7 @@ def CloseSmallDeletions(mhandle, scorer, max_extension=9, clash_thresh=1.0,
                                        current_chain_index)
                     scorer.SetEnvironment(bb_list, n_stem_resnum,
                                           current_chain_index)
-                    modelling.ClearGaps(mhandle, current_gap)
+                    ClearGaps(mhandle, current_gap)
                     success = True
                     break
 
@@ -416,7 +417,7 @@ def MergeGapsByDistance(mhandle, distance):
                    - current_gap.after.GetNumber().GetNum()
             if dist <= distance:
                 # gaps are close enough, combine! combine!
-                modelling.MergeGaps(mhandle, i)
+                MergeGaps(mhandle, i)
                 ost.LogInfo("Merged gap %s and %s into %s" % \
                                (current_gap, next_gap, mhandle.gaps[i]))
                 try_again = True
@@ -476,10 +477,11 @@ def FillLoopsByDatabase(mhandle, scorer, fragment_db, structure_db,
 
     :param score_variant: How to score loop candidates. Options:
 
-                          - 0: put frame of backbones enclosing all candidates
-                               and score frame (i.e. incl. non-loop residues)
-                          - 1: score candidates directly
-                          - 2: like 1 but penalize length of candidate
+                          - **0**: put frame of backbone residues enclosing all
+                            candidates and score frame. This will also "score"
+                            non-modelled residues!
+                          - **1**: score candidates directly
+                          - **2**: like **1** but penalize length of candidate
                           
     :type score_variant:  :class:`int`
 
@@ -922,7 +924,7 @@ def CloseLargeDeletions(mhandle, scorer, structure_db, linker_length = 8,
         # update scorer
         scorer.SetEnvironment(bb_list, first_num, actual_chain_idx)
         # will return -1 if last gap removed
-        gap_idx = modelling.ClearGaps(mhandle, actual_gap)
+        gap_idx = ClearGaps(mhandle, actual_gap)
 
         ost.LogInfo("Resolved %s by sampling %s as linker" % \
                     (str(gap_orig), str(actual_gap)))
diff --git a/modelling/pymod/_pipeline.py b/modelling/pymod/_pipeline.py
index 1f493b8e74263df30ba792f1372b9ff49c25b348..defcdf08753ec193bf10160f97272fd2c8412397 100644
--- a/modelling/pymod/_pipeline.py
+++ b/modelling/pymod/_pipeline.py
@@ -3,13 +3,15 @@ the __init__.py file. To be used directly by passing a ModellingHandle instance
 as argument.
 '''
 
+# internal
+from promod3 import loop
+from promod3 import sidechain
+from _modelling import *
+from _closegaps import *
+# external
 import ost
 from ost import mol,conop
 from ost.mol import mm
-from promod3 import loop
-from promod3 import sidechain
-from . import _modelling
-from . import _closegaps
 
 def BuildSidechains(mhandle):
     '''Build sidechains for model.
@@ -148,15 +150,15 @@ def BuildFromRawModel(mhandle):
     torsion_sampler = loop.LoadTorsionSamplerCoil()
     merge_distance = 4
 
-    scorer = _closegaps.SetupBackboneScorer(mhandle)
+    scorer = SetupBackboneScorer(mhandle)
 
     # step 1a: close small deletions in the raw model
     ost.LogInfo("Trying to close small deletions (no. of gaps: %d)." % \
                    len(mhandle.gaps))
-    _closegaps.CloseSmallDeletions(mhandle, scorer)
+    CloseSmallDeletions(mhandle, scorer)
     
     # step 1b: remove terminal gaps since we cannot deal with them below
-    num_gaps_removed = _modelling.RemoveTerminalGaps(mhandle)
+    num_gaps_removed = RemoveTerminalGaps(mhandle)
     ost.LogInfo("Removed %d terminal gaps." % num_gaps_removed)
 
     # step 2: simple handling of further gaps: merge, then fill from db
@@ -164,11 +166,11 @@ def BuildFromRawModel(mhandle):
         # step 2a: Combine gaps living close to each other
         ost.LogInfo("Trying to merge %d gap(s) with distance %d." % \
                        (len(mhandle.gaps), distance))
-        _closegaps.MergeGapsByDistance(mhandle, distance)
+        MergeGapsByDistance(mhandle, distance)
         # step 2b: fit loops into the model
         ost.LogInfo("Trying to fill %d gap(s) by database." % len(mhandle.gaps))
-        _closegaps.FillLoopsByDatabase(mhandle, scorer, fragment_db,
-                                       structure_db, torsion_sampler)
+        FillLoopsByDatabase(mhandle, scorer, fragment_db, structure_db,
+                            torsion_sampler)
         # check if we can abort
         ost.LogInfo("%d gap(s) left after database search." % len(mhandle.gaps))
         if len(mhandle.gaps) == 0:
@@ -177,12 +179,12 @@ def BuildFromRawModel(mhandle):
     # step 3: close remaining gaps by Monte Carlo
     if len(mhandle.gaps) > 0:
         ost.LogInfo("Trying to fill %d gap(s) by Monte Carlo." % len(mhandle.gaps))
-        _closegaps.FillLoopsByMonteCarlo(mhandle, scorer, torsion_sampler)
+        FillLoopsByMonteCarlo(mhandle, scorer, torsion_sampler)
 
     if len(mhandle.gaps) > 0:
         ost.LogInfo("There are still unsolved gaps, possibly large deletions. "
                     "Try to resolve them by sampling a linker region.")
-        _closegaps.CloseLargeDeletions(mhandle, scorer, structure_db)
+        CloseLargeDeletions(mhandle, scorer, structure_db)
 
     # check if we succeeded
     if len(mhandle.gaps) > 0: