diff --git a/CHANGELOG b/CHANGELOG
index d9a954345652cb563d9261c50444ca44bdb5dec2..b55f179828bf98b9ca00232a969ccc30e12cd6fe 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,7 +12,7 @@ Release X
   This simplifies the addition of other scoring functions in the future.
   Be aware of breaking changes introduced in the process!
   (SCWRLRotamerConstructor -> SCWRL4RotamerConstructor, changed interface of
-  Particle class).
+  Particle and RotamerConstructor classes).
 * Several minor bug fixes, improvements, and speed-ups  
 
 
diff --git a/doc/tests/scripts/sidechain_steps.py b/doc/tests/scripts/sidechain_steps.py
index d73a626dd775fd254e62cd1e085f355a278f7d01..6f66e5ee139ae5a9148b33146fd5dd4ea3d4a0ba 100644
--- a/doc/tests/scripts/sidechain_steps.py
+++ b/doc/tests/scripts/sidechain_steps.py
@@ -37,7 +37,9 @@ frame_residues = list()
 for i,r in enumerate(prot.residues):
     frame_residue = rot_constructor.ConstructBackboneFrameResidue(
                         r, rotamer_ids[i], i,
-                        torsion_angles[i][0], i == 0,
+                        torsion_angles[i][0],
+                        torsion_angles[i][1], 
+                        i == 0,
                         i == (len(rotamer_ids)-1))
     frame_residues.append(frame_residue)
 
@@ -54,7 +56,8 @@ for i,r in enumerate(prot.residues):
 
     rot_group = rot_constructor.ConstructFRMRotamerGroup(
                     r, rotamer_ids[i], i, library,
-                    torsion_angles[i][0], torsion_angles[i][1])
+                    torsion_angles[i][0], torsion_angles[i][1],
+                    i == 0, i == (len(rotamer_ids)-1), 0.98)
 
     # calculate pairwise energies towards the rigid frame
     # the values will be stored and used by the solving algorithm
diff --git a/modelling/pymod/_reconstruct_sidechains.py b/modelling/pymod/_reconstruct_sidechains.py
index 969df78d40bcda96d881abf800892d8de6a0fd3a..b94c37c93c389fb54b3d8661777e7f720c58dced 100644
--- a/modelling/pymod/_reconstruct_sidechains.py
+++ b/modelling/pymod/_reconstruct_sidechains.py
@@ -84,14 +84,14 @@ def _GetDihedrals(res_list):
     return phi_angles, psi_angles
 
 def _AddBackboneFrameResidues(frame_residues, res_list, rotamer_ids,
-                              rotamer_constructor, phi_angles):
+                              rotamer_constructor, phi_angles, psi_angles):
     '''Update frame_residues (list) with BackboneFrameResidues for res_list.'''
     for i,r in enumerate(res_list):
         try:
             frame_residue = rotamer_constructor.ConstructBackboneFrameResidue(\
                                 r.handle, rotamer_ids[i], i,
-                                phi_angles[i], r.HasProp("n_ter"),
-                                r.HasProp("c_ter"))
+                                phi_angles[i], psi_angles[i], 
+                                r.HasProp("n_ter"), r.HasProp("c_ter"))
             frame_residues.append(frame_residue)
         except:
             continue
@@ -110,6 +110,7 @@ def _AddLigandFrameResidues(frame_residues, ent_lig, rotamer_constructor, offset
             if rot_id != sidechain.XXX:
                 # get more info
                 phi = _GetPhiAngle(res)
+                psi = _GetPsiAngle(res)
                 r_prev = res.handle.prev
                 n_ter = not r_prev.IsValid() \
                         or not mol.InSequence(r_prev, res.handle)
@@ -120,10 +121,10 @@ def _AddLigandFrameResidues(frame_residues, ent_lig, rotamer_constructor, offset
                 try:
                     fr1 = rotamer_constructor.ConstructBackboneFrameResidue(\
                               res.handle, rot_id, res_idx,
-                              phi, n_ter, c_ter)
+                              phi, psi, n_ter, c_ter)
 
                     fr2 = rotamer_constructor.ConstructSidechainFrameResidue(\
-                              res.handle, rot_id, res_idx)
+                              res.handle, rot_id, res_idx, phi, psi, n_ter, c_ter)
 
                     frame_residues.extend([fr1,fr2])
                 except:
@@ -137,7 +138,7 @@ def _AddLigandFrameResidues(frame_residues, ent_lig, rotamer_constructor, offset
                 # NOTES:
                 # - ConstructFrameResidueHeuristic has fall back if res unknown
                 # - it only deals with few possible ligand cases and has not
-                #   been tested extensively!
+                #   been tested extensively! 
                 comp_lib = conop.GetDefaultLib()
                 fr = rotamer_constructor.ConstructFrameResidueHeuristic(\
                          res.handle, res_idx, comp_lib)
@@ -147,6 +148,7 @@ def _AddLigandFrameResidues(frame_residues, ent_lig, rotamer_constructor, offset
 
 def _AddSidechainFrameResidues(frame_residues, incomplete_sidechains,
                                keep_sidechains, res_list, rotamer_ids,
+                               phi_angles, psi_angles,
                                rotamer_constructor, cystein_indices=None):
     '''Update frame_residues (list) with SidechainFrameResidues for res_list,
     incomplete_sidechains (list of indices) with sidechains to be constructed,
@@ -165,7 +167,8 @@ def _AddSidechainFrameResidues(frame_residues, incomplete_sidechains,
 
             try:
                 frame_residue = rotamer_constructor.ConstructSidechainFrameResidue(\
-                                    r.handle, rotamer_ids[i], i)
+                                    r.handle, rotamer_ids[i], i, phi_angles[i],
+                                    psi_angles[i], r.HasProp("n_ter"), r.HasProp("c_ter"))
                 frame_residues.append(frame_residue)
             except:
                 incomplete_sidechains.append(i)
@@ -182,6 +185,7 @@ def _AddSidechainFrameResidues(frame_residues, incomplete_sidechains,
 
 def _AddCysteinFrameResidues(frame_residues, incomplete_sidechains,
                              keep_sidechains, res_list, rotamer_ids,
+                             phi_angles, psi_angles,
                              rot_constructor, cystein_indices,
                              disulfid_indices, disulfid_rotamers):
     '''Update frame_residues (list) with cysteins.
@@ -206,7 +210,9 @@ def _AddCysteinFrameResidues(frame_residues, incomplete_sidechains,
             try:
                 frame_residue = rot_constructor.ConstructSidechainFrameResidue(\
                                     res_list[idx].handle, rotamer_ids[idx],
-                                    idx)
+                                    idx, phi_angles[idx], psi_angles[idx],
+                                    res_list[idx].handle.HasProp("n_ter"),
+                                    res_list[idx].handle.HasProp("c_ter"))
                 frame_residues.append(frame_residue)
             except:
                 incomplete_sidechains.append(idx) 
@@ -214,27 +220,24 @@ def _AddCysteinFrameResidues(frame_residues, incomplete_sidechains,
             incomplete_sidechains.append(idx)
 
 def _GetRotamerGroup(res_handle, rot_id, res_idx, rot_lib, rot_constructor,
-                     phi, psi, use_frm, bbdep, probability_cutoff = 0.98):
+                     phi, psi, use_frm, bbdep, 
+                     probability_cutoff = 0.98):
+
     if use_frm:
-        if bbdep:
-            return rot_constructor.ConstructFRMRotamerGroup(res_handle, rot_id,
-                                                            res_idx, rot_lib,
-                                                            phi, psi,
-                                                            probability_cutoff)
-        else:
-            return rot_constructor.ConstructFRMRotamerGroup(res_handle, rot_id,
-                                                            res_idx, rot_lib,
-                                                            probability_cutoff)
-    else:
-        if bbdep:
-            return rot_constructor.ConstructRRMRotamerGroup(res_handle, rot_id,
-                                                            res_idx, rot_lib,
-                                                            phi, psi,
-                                                            probability_cutoff)
-        else:
-            return rot_constructor.ConstructRRMRotamerGroup(res_handle, rot_id,
-                                                            res_idx, rot_lib,
-                                                            probability_cutoff)
+        return rot_constructor.ConstructFRMRotamerGroup(res_handle, rot_id,
+                                                        res_idx, rot_lib,
+                                                        phi, psi, 
+                                                        res_handle.HasProp("n_ter"),
+                                                        res_handle.HasProp("c_ter"),
+                                                        probability_cutoff)
+    else:        
+        return rot_constructor.ConstructRRMRotamerGroup(res_handle, rot_id,
+                                                        res_idx, rot_lib,
+                                                        phi, psi,
+                                                        res_handle.HasProp("n_ter"),
+                                                        res_handle.HasProp("c_ter"),
+                                                        probability_cutoff)
+
 
 def _GetRotamerGroups(res_list, rot_ids, indices, rot_lib, rot_constructor,
                       phi_angles, psi_angles, use_frm, bbdep, frame_residues):
@@ -341,10 +344,14 @@ def _GetDisulfidBridges(frame_residues, keep_sidechains, cystein_indices,
             if sg.IsValid():
                 # we're constructing the required particle through a frame 
                 # residue in the rotamer constructor
+                phi = _GetPhiAngle(r)
+                psi = _GetPsiAngle(r)
                 cys_frame_res = \
                 rotamer_constructor.ConstructSidechainFrameResidue(r.handle, 
                                                                    sidechain.CYD, 
-                                                                   0)
+                                                                   0, phi, psi,
+                                                                   r.HasProp("n_ter"),
+                                                                   r.HasProp("c_ter"))
                 for j in range(len(cys_frame_res)):
                     if cys_frame_res[j].GetName() == "SG":
                         particle_list = [cys_frame_res[j]]
@@ -474,7 +481,7 @@ def ReconstructSidechains(ent, keep_sidechains=False, build_disulfids=True,
     frame_residues = list()         # list of frame residues connected to frame
     incomplete_sidechains = list()  # residue indices
     _AddBackboneFrameResidues(frame_residues, prot.residues, rotamer_ids,
-                              rotamer_constructor, phi_angles)
+                              rotamer_constructor, phi_angles, psi_angles)
     
     # add ligands?
     if consider_ligands:
@@ -489,6 +496,7 @@ def ReconstructSidechains(ent, keep_sidechains=False, build_disulfids=True,
         # update frame_residues, incomplete_sidechains, cystein_indices
         _AddSidechainFrameResidues(frame_residues, incomplete_sidechains,
                                    keep_sidechains, prot.residues, rotamer_ids,
+                                   phi_angles, psi_angles,
                                    rotamer_constructor, cystein_indices)
         # update frame_residues, incomplete_sidechains with cysteins (if needed)
         if len(cystein_indices) > 0:
@@ -501,12 +509,14 @@ def ReconstructSidechains(ent, keep_sidechains=False, build_disulfids=True,
             # update frame_residues, incomplete_sidechains
             _AddCysteinFrameResidues(frame_residues, incomplete_sidechains,
                                      keep_sidechains, prot.residues, rotamer_ids,
+                                     phi_angles, psi_angles,
                                      rotamer_constructor, cystein_indices,
                                      disulfid_indices, disulfid_rotamers)
     else:
         # update frame_residues, incomplete_sidechains
         _AddSidechainFrameResidues(frame_residues, incomplete_sidechains,
                                    keep_sidechains, prot.residues, rotamer_ids,
+                                   phi_angles, psi_angles,
                                    rotamer_constructor)
     
     # get rotamer groups and residues they're linked to
diff --git a/modelling/src/sidechain_env_listener.cc b/modelling/src/sidechain_env_listener.cc
index 19d97aa12f345b8c6b81bc184457b9c7cb7e7226..160a06755b141872796f646b2e808b0c7ee8f76f 100644
--- a/modelling/src/sidechain_env_listener.cc
+++ b/modelling/src/sidechain_env_listener.cc
@@ -193,6 +193,7 @@ void SidechainEnvListener::SetResidue_(loop::ConstAllAtomPositionsPtr all_pos,
       = rot_constructor_.ConstructBackboneFrameResidue(*all_pos, res_idx, 
                                                        r_id, res_idx, 
                                                        phi_angle_[res_idx], 
+                                                       psi_angle_[res_idx],
                                                        n_ter_[res_idx], 
                                                        c_ter_[res_idx]);
     
@@ -200,7 +201,11 @@ void SidechainEnvListener::SetResidue_(loop::ConstAllAtomPositionsPtr all_pos,
     if (all_set) {
       sc_frame_residue_[res_idx]
         = rot_constructor_.ConstructSidechainFrameResidue(*all_pos, res_idx, 
-                                                           r_id, res_idx);
+                                                           r_id, res_idx,
+                                                           phi_angle_[res_idx],
+                                                           psi_angle_[res_idx],
+                                                           n_ter_[res_idx],
+                                                           c_ter_[res_idx]);
     } else {
       sc_frame_residue_[res_idx].reset();
     }
diff --git a/modelling/src/sidechain_env_listener.hh b/modelling/src/sidechain_env_listener.hh
index cc8c2709a42e01b56f41cabd54a994460acd5de5..8c919cc298bd61b9435dcf24fa9345cbbd8d330d 100644
--- a/modelling/src/sidechain_env_listener.hh
+++ b/modelling/src/sidechain_env_listener.hh
@@ -142,13 +142,19 @@ public:
                                                             r_id, res_idx,
                                                             bbdep_library_,
                                                             phi_angle_[res_idx],
-                                                            psi_angle_[res_idx]);
+                                                            psi_angle_[res_idx],
+                                                            n_ter_[res_idx],
+                                                            c_ter_[res_idx]);
     } else {
       rot_group = rot_constructor_.ConstructFRMRotamerGroup(*all_pos, res_idx, 
                                                             r_id, res_idx,
-                                                            library_);
+                                                            library_,
+                                                            phi_angle_[res_idx],
+                                                            psi_angle_[res_idx],
+                                                            n_ter_[res_idx],
+                                                            c_ter_[res_idx]);
     }
-    rot_constructor_.AssignInternalEnergies(rot_group);
+    rot_constructor_.AssignInternalEnergies(rot_group, r_id, res_idx);
   }
   void CreateRotamerGroup(sidechain::RRMRotamerGroupPtr& rot_group,
                           loop::ConstAllAtomPositionsPtr all_pos, 
@@ -158,13 +164,19 @@ public:
                                                             r_id, res_idx,
                                                             bbdep_library_,
                                                             phi_angle_[res_idx],
-                                                            psi_angle_[res_idx]);
+                                                            psi_angle_[res_idx],
+                                                            n_ter_[res_idx],
+                                                            c_ter_[res_idx]);
     } else {
       rot_group = rot_constructor_.ConstructRRMRotamerGroup(*all_pos, res_idx,
                                                             r_id, res_idx,
-                                                            library_);
+                                                            library_,
+                                                            phi_angle_[res_idx],
+                                                            psi_angle_[res_idx],
+                                                            n_ter_[res_idx],
+                                                            c_ter_[res_idx]);
     }
-    rot_constructor_.AssignInternalEnergies(rot_group);
+    rot_constructor_.AssignInternalEnergies(rot_group, r_id, res_idx);
   }
 
 private:
diff --git a/sidechain/doc/rotamer_constructor.rst b/sidechain/doc/rotamer_constructor.rst
index b36d7d88619892d046e8ebe09aeaca7f71713046..3a297d5d0846dd0808cad22419dad15add0bf11b 100644
--- a/sidechain/doc/rotamer_constructor.rst
+++ b/sidechain/doc/rotamer_constructor.rst
@@ -34,22 +34,23 @@ Constructing Rotamers and Frame Residues
   (e.g. :class:`SCWRL4RotamerConstructor`). 
 
   .. method:: ConstructRRMRotamerGroup(res, id, residue_index, rot_lib,\
-                                       [probability_cutoff = 0.98])
-  .. method:: ConstructRRMRotamerGroup(all_atom_pos, aa_res_idx, id,\
-                                       residue_index, rot_lib,\
-                                       [probability_cutoff = 0.98])
-  .. method:: ConstructRRMRotamerGroup(res, id, residue_index, rot_lib,\
-                                       [phi = -1.0472, psi = -0.7854,\
+                                       [phi = -1.0472, psi = -0.7854, \
+                                        n_ter = False, c_ter = False, \
                                         probability_cutoff = 0.98])
   .. method:: ConstructRRMRotamerGroup(all_atom_pos, aa_res_idx, id,\
                                        residue_index, rot_lib,\
-                                       [phi = -1.0472, psi = -0.7854,\
+                                       [phi = -1.0472, psi = -0.7854, \
+                                        n_ter = False, c_ter = False, \
                                         probability_cutoff = 0.98])
   .. method:: ConstructRRMRotamerGroup(res, id, residue_index, rot_lib_entries,\
-                                       [probability_cutoff = 0.98])
+                                       [phi = -1.0472, psi = -0.7854, \
+                                        n_ter = False, c_ter = False, \
+                                        probability_cutoff = 0.98])
   .. method:: ConstructRRMRotamerGroup(all_atom_pos, aa_res_idx, id,\
                                        residue_index, rot_lib_entries,\
-                                       [probability_cutoff = 0.98])
+                                       [phi = -1.0472, psi = -0.7854, \
+                                        n_ter = False, c_ter = False, \
+                                        probability_cutoff = 0.98])
 
     All functions are also avaible for their flexible rotamer model counterpart.
     =>ConstructFRMRotamerGroup(...) with the same parameters. 
@@ -66,10 +67,10 @@ Constructing Rotamers and Frame Residues
     :param rot_lib:     To search for rotamers
     :param rot_lib_entries: :class:`RotamerLibEntry` objects to circumvent the 
                             direct use of a rotamer library
-    :param phi:         Phi dihedral angle used to search for rotamers if a 
-                        :class:`BBDepRotamerLib` is given as input
-    :param psi:         Psi dihedral angle used to search for rotamers if a 
-                        :class:`BBDepRotamerLib` is given as input
+    :param phi:         Phi dihedral angle 
+    :param psi:         Psi dihedral angle 
+    :param n_ter:       Whether the residue is n-terminal
+    :param c_ter:       Whether the residue is c-terminal
     :param probability_cutoff: For some rotamers, there might be many low 
                         probability entries in the library. 
                         The function adds single rotamers to the group until 
@@ -77,8 +78,7 @@ Constructing Rotamers and Frame Residues
                         larger or equal **probability_cutoff**.
 
     :returns:           The rotamer group containing all constructed rotamers 
-                        with internal energies assigned based on the 
-                        probabilities extracted from the rotamer library. 
+                        with internal energies assigned. 
 
     :type res:          :class:`ost.mol.ResidueHandle`
     :type all_atom_pos: :class:`promod3.loop.AllAtomPositions`
@@ -87,6 +87,10 @@ Constructing Rotamers and Frame Residues
     :type residue_index: :class:`int`
     :type rot_lib:      :class:`RotamerLib` / :class:`BBDepRotamerLib`
     :type rot_lib_entries: :class:`list`
+    :type phi:          :class:`float`
+    :type psi:          :class:`float`
+    :type n_ter:        :class:`bool`
+    :type c_ter:        :class:`bool`
     :type probability_cutoff: :class:`float`
     :rtype:             :class:`RRMRotamerGroup`
 
@@ -96,12 +100,13 @@ Constructing Rotamers and Frame Residues
 
 
   .. method:: ConstructBackboneFrameResidue(res, id, residue_index, \
-                                            [ phi = -1.0472, n_ter = False, \
-                                            c_ter = False])
+                                            [phi = -1.0472, psi = -0.7854, \
+                                             n_ter = False, c_ter = False])
 
   .. method:: ConstructBackboneFrameResidue(all_atom_pos, aa_res_idx, id,\
-                                            residue_index, [phi = -1.0472,\
-                                            n_ter = False, c_ter = False])
+                                            residue_index, \
+                                            [phi = -1.0472, psi = -0.7854\
+                                             n_ter = False, c_ter = False])
 
     Constructs frame residues only containing backbone atoms (the ones that 
     don't show up in a rotamer).
@@ -115,19 +120,17 @@ Constructing Rotamers and Frame Residues
                           :class:`Frame` you don't want to calculate a pairwise
                           energy of the sidechain particles towards particles
                           representing the own backbone...
-    :param phi:         The dihedral angle of the current residue, required to 
-                        construct the polar nitrogen hydrogen 
-    :param n_ter:       Whether to add additional hydrogens at the nitrogen
-                        to represent a proper n-terminus
-    :param c_ter:       Whether to add an additional oxygen at the carbon to
-                        represent a proper c-terminus
-
+    :param phi:         The dihedral angle of the current residue
+    :param psi:         The dihedral angle of the current residue
+    :param n_ter:       Whether the residue is n-terminal
+    :param c_ter:       Whether the residue is c-terminal
     :type res:          :class:`ost.mol.ResidueHandle`
     :type all_atom_pos: :class:`promod3.loop.AllAtomPositions`
     :type aa_res_idx:   :class:`int`
     :type id:           :class:`RotamerID`
     :type residue_index: :class:`int`
     :type phi:          :class:`float`
+    :type psi:          :class:`float`
     :type n_ter:        :class:`bool`
     :type c_ter:        :class:`bool`
 
@@ -139,26 +142,40 @@ Constructing Rotamers and Frame Residues
               positions are set in **all_atom_pos**.
 
 
-  .. method:: ConstructSidechainFrameResidue(res, id, residue_index)
+  .. method:: ConstructSidechainFrameResidue(res, id, residue_index, \
+                                             [phi = -1.0472, psi = -0.7854, \
+                                              n_ter = False, c_ter = False])
 
-  .. method:: ConstructSidechainFrameResidue(all_atom, aa_res_idx, id,\ 
-                                             residue_index)
+  .. method:: ConstructSidechainFrameResidue(all_atom_pos, aa_res_idx, id,\
+                                             residue_index, \
+                                             [phi = -1.0472, psi = -0.7854\
+                                             n_ter = False, c_ter = False])
 
     Constructs frame residues only containing sidechain atoms (the ones that
     you observe in a rotamer).
 
-    :param res:         Residue from which to extract the sidechain positions
-    :param all_atom_pos: To extract the sidechain positions
+    :param res:         Residue from which to extract the backbone positions
+    :param all_atom_pos: To extract the backbone positions
     :param aa_res_idx:  Index of residue in **all_atom_pos** from which to 
-                        extract the sidechain positions
+                        extract the backbone positions
     :param id:          Identifies the sidechain
-    :param residue_index: idenfifies residue in frame
-
+    :param residue_index: Important for the energy calculations towards the 
+                          :class:`Frame` you don't want to calculate a pairwise
+                          energy of the sidechain particles towards particles
+                          representing the own backbone...
+    :param phi:         The dihedral angle of the current residue
+    :param psi:         The dihedral angle of the current residue
+    :param n_ter:       Whether the residue is n-terminal
+    :param c_ter:       Whether the residue is c-terminal
     :type res:          :class:`ost.mol.ResidueHandle`
     :type all_atom_pos: :class:`promod3.loop.AllAtomPositions`
     :type aa_res_idx:   :class:`int`
     :type id:           :class:`RotamerID`
     :type residue_index: :class:`int`
+    :type phi:          :class:`float`
+    :type psi:          :class:`float`
+    :type n_ter:        :class:`bool`
+    :type c_ter:        :class:`bool`
 
     :rtype:             :class:`FrameResidue`
 
@@ -167,7 +184,9 @@ Constructing Rotamers and Frame Residues
               atoms are present in **residue** or not all required sidechain 
               atom positions are set in **all_atom_pos**.
 
-  .. method:: AssignInternalEnergies(rot_group)
+  .. method:: AssignInternalEnergies(rot_group, id, residue_index, \
+                                     [phi = -1.0472, psi = -0.7854, \
+                                      n_ter = False, c_ter = False])
 
     Assigns an internal energy to every rotamer in *rot_group*, i.e. an energy
     value before looking at any structural component of the energy function.
@@ -176,8 +195,21 @@ Constructing Rotamers and Frame Residues
 
     :param rot_group:   containing all rotamers for which internal energies have
                         to be assigned
+    :param id:          Identifies the sidechain
+    :param residue_index: The index of the residue which is represented by 
+                          *rot_group*    
+    :param phi:         The dihedral angle of the current residue
+    :param psi:         The dihedral angle of the current residue
+    :param n_ter:       Whether the residue is n-terminal
+    :param c_ter:       Whether the residue is c-terminal
 
     :type rot_group:    :class:`RRMRotamerGroup` / :class:`FRMRotamerGroup`
+    :type id:           :class:`RotamerID`
+    :type residue_index: :class:`int`
+    :type phi:          :class:`float`
+    :type psi:          :class:`float`
+    :type n_ter:        :class:`bool`
+    :type c_ter:        :class:`bool`
 
 
 
@@ -244,7 +276,9 @@ Constructing Rotamers and Frame Residues
   
     :returns:             :class:`FrameResidue`
 
-  .. method:: AssignInternalEnergies(rot_group)
+  .. method:: AssignInternalEnergies(rot_group, id, residue_index, \
+                                     [phi = -1.0472, psi = -0.7854, \
+                                      n_ter = False, c_ter = False])
 
     Overrides the method defined in :class:`RotamerConstructor`.
     Takes the rotamer group and assigns every single rotamer its internal
@@ -257,6 +291,18 @@ Constructing Rotamers and Frame Residues
 
     :param rot_group:   containing all rotamers for which internal energies have
                         to be assigned
+    :param id:          Identifies the sidechain
+    :param residue_index: The index of the residue which is represented by 
+                          *rot_group*    
+    :param phi:         The dihedral angle of the current residue
+    :param psi:         The dihedral angle of the current residue
+    :param n_ter:       Whether the residue is n-terminal
+    :param c_ter:       Whether the residue is c-terminal
 
     :type rot_group:    :class:`RRMRotamerGroup` / :class:`FRMRotamerGroup`
-
+    :type id:           :class:`RotamerID`
+    :type residue_index: :class:`int`
+    :type phi:          :class:`float`
+    :type psi:          :class:`float`
+    :type n_ter:        :class:`bool`
+    :type c_ter:        :class:`bool`
diff --git a/sidechain/pymod/export_rotamer_constructor.cc b/sidechain/pymod/export_rotamer_constructor.cc
index 8b6b6890e0a65cda168fc55e89001f8e95ac6fe6..cf28f603746dd64ab52ecb8a238057ee7081f05f 100644
--- a/sidechain/pymod/export_rotamer_constructor.cc
+++ b/sidechain/pymod/export_rotamer_constructor.cc
@@ -39,9 +39,11 @@ RRMRotamerGroupPtr WrapRRMGroup_res(RotamerConstructorPtr constructor,
                                     RotamerID id,
                                     uint residue_idx,
                                     RotamerLibPtr rot_lib,
+                                    Real phi, Real psi, bool n_ter, bool c_ter,
                                     Real probability_cutoff){
   return constructor->ConstructRRMRotamerGroup(res, id, residue_idx, 
-                                               rot_lib, probability_cutoff);
+                                               rot_lib, phi, psi, n_ter, c_ter,
+                                               probability_cutoff);
 }
 
 RRMRotamerGroupPtr WrapRRMGroup_aa(RotamerConstructorPtr constructor,
@@ -50,20 +52,27 @@ RRMRotamerGroupPtr WrapRRMGroup_aa(RotamerConstructorPtr constructor,
                                    RotamerID rotamer_id,
                                    uint residue_idx,
                                    RotamerLibPtr rot_lib,
+                                   Real phi, Real psi,
+                                   bool n_ter, bool c_ter,
                                    Real probability_cutoff){
   return constructor->ConstructRRMRotamerGroup(all_atom_pos, all_atom_pos_idx,
                                                rotamer_id, residue_idx,
-                                               rot_lib, probability_cutoff);
+                                               rot_lib, phi, psi, n_ter, c_ter, 
+                                               probability_cutoff);
 }
 
 FRMRotamerGroupPtr WrapFRMGroup_res(RotamerConstructorPtr constructor,
                                     const ost::mol::ResidueHandle& res,
                                     RotamerID id,
                                     uint residue_idx,
-                                    RotamerLibPtr rot_lib,
+                                    RotamerLibPtr rot_lib, 
+                                    Real phi, Real psi,
+                                    bool n_ter, bool c_ter,
                                     Real probability_cutoff){
   return constructor->ConstructFRMRotamerGroup(res, id, residue_idx, 
-                                               rot_lib, probability_cutoff);
+                                               rot_lib, phi, psi,
+                                               n_ter, c_ter, 
+                                               probability_cutoff);
 }
 
 FRMRotamerGroupPtr WrapFRMGroup_aa(RotamerConstructorPtr constructor,
@@ -72,10 +81,12 @@ FRMRotamerGroupPtr WrapFRMGroup_aa(RotamerConstructorPtr constructor,
                                    RotamerID rotamer_id,
                                    uint residue_idx,
                                    RotamerLibPtr rot_lib,
+                                   Real phi, Real psi, bool n_ter, bool c_ter,
                                    Real probability_cutoff){
   return constructor->ConstructFRMRotamerGroup(all_atom_pos, all_atom_pos_idx,
                                                rotamer_id, residue_idx,
-                                               rot_lib, probability_cutoff);
+                                               rot_lib, phi, psi, n_ter, c_ter,
+                                               probability_cutoff);
 }
 
 RRMRotamerGroupPtr WrapRRMGroup_bbdep_res(RotamerConstructorPtr constructor,
@@ -84,9 +95,10 @@ RRMRotamerGroupPtr WrapRRMGroup_bbdep_res(RotamerConstructorPtr constructor,
                                           uint residue_idx,
                                           BBDepRotamerLibPtr rot_lib,
                                           Real phi, Real  psi,
+                                          bool n_ter, bool c_ter,
                                           Real probability_cutoff){
   return constructor->ConstructRRMRotamerGroup(res, id, residue_idx, 
-                                               rot_lib, phi, psi, 
+                                               rot_lib, phi, psi, n_ter, c_ter, 
                                                probability_cutoff);
 }
 
@@ -97,6 +109,7 @@ RRMRotamerGroupPtr WrapRRMGroup_bbdep_aa(RotamerConstructorPtr constructor,
                                          uint residue_idx,
                                          BBDepRotamerLibPtr rot_lib,
                                          Real phi, Real psi,
+                                         bool n_ter, bool c_ter,
                                          Real probability_cutoff){
   return constructor->ConstructRRMRotamerGroup(all_atom_pos, all_atom_pos_idx,
                                                rotamer_id, residue_idx,
@@ -110,9 +123,10 @@ FRMRotamerGroupPtr WrapFRMGroup_bbdep_res(RotamerConstructorPtr constructor,
                                           uint residue_idx,
                                           BBDepRotamerLibPtr rot_lib,
                                           Real phi, Real  psi,
+                                          bool n_ter, bool c_ter,
                                           Real probability_cutoff){
   return constructor->ConstructFRMRotamerGroup(res, id, residue_idx, 
-                                              rot_lib, phi, psi, 
+                                              rot_lib, phi, psi, n_ter, c_ter,
                                               probability_cutoff);
 }
 
@@ -123,10 +137,11 @@ FRMRotamerGroupPtr WrapFRMGroup_bbdep_aa(RotamerConstructorPtr constructor,
                                          uint residue_idx,
                                          BBDepRotamerLibPtr rot_lib,
                                          Real phi, Real  psi,
+                                         bool n_ter, bool c_ter,
                                          Real probability_cutoff){
   return constructor->ConstructFRMRotamerGroup(all_atom_pos, all_atom_pos_idx,
                                                rotamer_id, residue_idx,
-                                               rot_lib, phi, psi, 
+                                               rot_lib, phi, psi, n_ter, c_ter, 
                                                probability_cutoff);
 }
 
@@ -135,11 +150,14 @@ RRMRotamerGroupPtr WrapRRMGroup_entries_res(RotamerConstructorPtr constructor,
                                             RotamerID id,
                                             uint residue_idx,
                                             const boost::python::list& entries,
+                                            Real phi, Real psi, 
+                                            bool n_ter, bool c_ter,
                                             Real probability_cutoff){
   std::vector<RotamerLibEntry> v_entries;
   core::ConvertListToVector(entries, v_entries);
   return constructor->ConstructRRMRotamerGroup(res, id, residue_idx, 
-                                               v_entries, 
+                                               v_entries, phi, psi, 
+                                               n_ter, c_ter,
                                                probability_cutoff);
 }
 
@@ -149,12 +167,14 @@ RRMRotamerGroupPtr WrapRRMGroup_entries_aa(RotamerConstructorPtr constructor,
                                            RotamerID rotamer_id,
                                            uint residue_idx,
                                            const boost::python::list& entries,
+                                           Real phi, Real psi, 
+                                           bool n_ter, bool c_ter,
                                            Real probability_cutoff){
   std::vector<RotamerLibEntry> v_entries;
   core::ConvertListToVector(entries, v_entries);
   return constructor->ConstructRRMRotamerGroup(all_atom_pos, all_atom_pos_idx,
                                                rotamer_id, residue_idx,
-                                               v_entries, 
+                                               v_entries, phi, psi, n_ter, c_ter,
                                                probability_cutoff);
 }
 
@@ -163,11 +183,14 @@ FRMRotamerGroupPtr WrapFRMGroup_entries_res(RotamerConstructorPtr constructor,
                                             RotamerID id,
                                             uint residue_idx,
                                             const boost::python::list& entries,
+                                            Real phi, Real psi, 
+                                            bool n_ter, bool c_ter,
                                             Real probability_cutoff){
   std::vector<RotamerLibEntry> v_entries;
   core::ConvertListToVector(entries, v_entries);
   return constructor->ConstructFRMRotamerGroup(res, id, residue_idx, 
                                                v_entries, 
+                                               phi, psi, n_ter, c_ter,
                                                probability_cutoff);
 }
 
@@ -177,56 +200,68 @@ FRMRotamerGroupPtr WrapFRMGroup_entries_aa(RotamerConstructorPtr constructor,
                                            RotamerID rotamer_id,
                                            uint residue_idx,
                                            const boost::python::list& entries,
+                                           Real phi, Real psi, bool n_ter, 
+                                           bool c_ter,
                                            Real probability_cutoff){
   std::vector<RotamerLibEntry> v_entries;
   core::ConvertListToVector(entries, v_entries);
   return constructor->ConstructFRMRotamerGroup(all_atom_pos, all_atom_pos_idx,
                                                rotamer_id, residue_idx,
-                                               v_entries,
+                                               v_entries, phi, psi, n_ter, c_ter,
                                                probability_cutoff);
 }
 
 FrameResiduePtr WrapBBFrame_res(RotamerConstructorPtr constructor,
                                 const ost::mol::ResidueHandle& residue,
                                 RotamerID id, uint residue_index,
-                                Real phi, bool n_ter, bool c_ter){
+                                Real phi, Real psi, bool n_ter, bool c_ter){
     return constructor->ConstructBackboneFrameResidue(residue, id, residue_index,
-                                                      phi, n_ter, c_ter);
+                                                      phi, psi, n_ter, c_ter);
 }
 
 FrameResiduePtr WrapBBFrame_aa(RotamerConstructorPtr constructor,
                                const promod3::loop::AllAtomPositions& all_atom_pos,
                                uint all_atom_pos_idx,
                                RotamerID id, uint residue_index,
-                               Real phi, bool n_ter, bool c_ter){
+                               Real phi, Real psi, bool n_ter, bool c_ter){
     return constructor->ConstructBackboneFrameResidue(all_atom_pos, all_atom_pos_idx, 
                                                       id, residue_index,
-                                                      phi, n_ter, c_ter);
+                                                      phi, psi, n_ter, c_ter);
 }
 
 
 FrameResiduePtr WrapSCFrame_res(RotamerConstructorPtr constructor,
                                 const ost::mol::ResidueHandle& residue,
-                                RotamerID id, uint residue_index){
-    return constructor->ConstructSidechainFrameResidue(residue, id, residue_index);
+                                RotamerID id, uint residue_index,
+                                Real phi, Real psi, bool n_ter, bool c_ter){
+    return constructor->ConstructSidechainFrameResidue(residue, id, residue_index,
+                                                       phi, psi, n_ter, c_ter);
 }
 
 FrameResiduePtr WrapSCFrame_aa(RotamerConstructorPtr constructor,
                                const promod3::loop::AllAtomPositions& all_atom_pos,
                                uint all_atom_pos_idx,
-                               RotamerID id, uint residue_index){
+                               RotamerID id, uint residue_index,
+                               Real phi, Real psi, bool n_ter, bool c_ter){
     return constructor->ConstructSidechainFrameResidue(all_atom_pos, all_atom_pos_idx, 
-                                                      id, residue_index);
+                                                      id, residue_index, phi, psi,
+                                                      n_ter, c_ter);
 }
 
 void AssignInternalEnergiesRRM(RotamerConstructorPtr constructor,
-                               RRMRotamerGroupPtr group){
-  constructor->AssignInternalEnergies(group);
+                               RRMRotamerGroupPtr group, RotamerID id,
+                               uint residue_index,
+                               Real phi, Real psi, bool n_ter, bool c_ter){
+  constructor->AssignInternalEnergies(group, id, residue_index, phi, psi,
+                                      n_ter, c_ter);
 }
 
 void AssignInternalEnergiesFRM(RotamerConstructorPtr constructor,
-                               FRMRotamerGroupPtr group){
-  constructor->AssignInternalEnergies(group);
+                               FRMRotamerGroupPtr group, RotamerID id,
+                               uint residue_index,
+                               Real phi, Real psi, bool n_ter, bool c_ter){
+  constructor->AssignInternalEnergies(group, id, residue_index, phi, psi, 
+                                      n_ter, c_ter);
 }
 
 } // anon ns
@@ -240,23 +275,39 @@ void export_RotamerConstructor(){
                                                         arg("rotamer_id"),
                                                         arg("residue_idx"),
                                                         arg("rot_lib"),
+                                                        arg("phi") = -1.0472,
+                                                        arg("psi") = -0.7854,
+                                                        arg("n_ter") = false,
+                                                        arg("c_ter") = false,
                                                         arg("probability_cutoff") = 0.98))
     .def("ConstructRRMRotamerGroup", &WrapRRMGroup_aa,(arg("all_atom_pos"),
                                                        arg("all_atom_pos_idx"),
                                                        arg("rotamer_id"),
                                                        arg("residue_idx"),
                                                        arg("rot_lib"),
+                                                       arg("phi") = -1.0472,
+                                                       arg("psi") = -0.7854,
+                                                       arg("n_ter") = false,
+                                                       arg("c_ter") = false,                                                       
                                                        arg("probability_cutoff") = 0.98))
     .def("ConstructFRMRotamerGroup", &WrapFRMGroup_res,(arg("residue"),
                                                         arg("rotamer_id"),
                                                         arg("residue_idx"),
                                                         arg("rot_lib"),
+                                                        arg("phi") = -1.0472,
+                                                        arg("psi") = -0.7854,
+                                                        arg("n_ter") = false,
+                                                        arg("c_ter") = false,
                                                         arg("probability_cutoff") = 0.98))
     .def("ConstructFRMRotamerGroup", &WrapFRMGroup_aa,(arg("all_atom_pos"),
                                                        arg("all_atom_pos_idx"),
                                                        arg("rotamer_id"),
                                                        arg("residue_idx"),
                                                        arg("rot_lib"),
+                                                       arg("phi") = -1.0472,
+                                                       arg("psi") = -0.7854,
+                                                       arg("n_ter") = false,
+                                                       arg("c_ter") = false,
                                                        arg("probability_cutoff") = 0.98))
     .def("ConstructRRMRotamerGroup", &WrapRRMGroup_bbdep_res,(arg("residue"),
                                                               arg("rotamer_id"),
@@ -264,6 +315,8 @@ void export_RotamerConstructor(){
                                                               arg("rot_lib"),
                                                               arg("phi") = -1.0472,
                                                               arg("psi") = -0.7854,
+                                                              arg("n_ter") = false,
+                                                              arg("c_ter") = false,
                                                               arg("probability_cutoff") = 0.98))
     .def("ConstructRRMRotamerGroup", &WrapRRMGroup_bbdep_aa,(arg("all_atom_pos"),
                                                              arg("all_atom_pos_idx"),
@@ -272,6 +325,8 @@ void export_RotamerConstructor(){
                                                              arg("rot_lib"),
                                                              arg("phi") = -1.0472,
                                                              arg("psi") = -0.7854,
+                                                             arg("n_ter") = false,
+                                                             arg("c_ter") = false,
                                                              arg("probability_cutoff") = 0.98))
     .def("ConstructFRMRotamerGroup", &WrapFRMGroup_bbdep_res,(arg("residue"),
                                                               arg("rotamer_id"),
@@ -279,6 +334,8 @@ void export_RotamerConstructor(){
                                                               arg("rot_lib"),
                                                               arg("phi") = -1.0472,
                                                               arg("psi") = -0.7854,
+                                                              arg("n_ter") = false,
+                                                              arg("c_ter") = false,
                                                               arg("probability_cutoff") = 0.98))
     .def("ConstructFRMRotamerGroup", &WrapFRMGroup_bbdep_aa,(arg("all_atom_pos"),
                                                              arg("all_atom_pos_idx"),
@@ -287,33 +344,52 @@ void export_RotamerConstructor(){
                                                              arg("rot_lib"),
                                                              arg("phi") = -1.0472,
                                                              arg("psi") = -0.7854,
+                                                             arg("phi") = false,
+                                                             arg("psi") = false,
                                                              arg("probability_cutoff") = 0.98))
     .def("ConstructRRMRotamerGroup", &WrapRRMGroup_entries_res,(arg("residue"),
                                                                 arg("rotamer_id"),
                                                                 arg("residue_idx"),
                                                                 arg("entries"),
+                                                                arg("phi") = -1.0472,
+                                                                arg("psi") = -0.7854,
+                                                                arg("n_ter") = false,
+                                                                arg("c_ter") = false,
                                                                 arg("probability_cutoff") = 0.98))
     .def("ConstructRRMRotamerGroup", &WrapRRMGroup_entries_aa,(arg("all_atom_pos"),
                                                                arg("all_atom_pos_idx"),
                                                                arg("rotamer_id"),
                                                                arg("residue_idx"),
                                                                arg("entries"),
+                                                               arg("phi") = -1.0472,
+                                                               arg("psi") = -0.7854,
+                                                               arg("n_ter") = false,
+                                                               arg("c_ter") = false,
                                                                arg("probability_cutoff") = 0.98))
     .def("ConstructFRMRotamerGroup", &WrapFRMGroup_entries_res,(arg("residue"),
                                                                 arg("rotamer_id"),
                                                                 arg("residue_idx"),
                                                                 arg("entries"),
+                                                                arg("phi") = -1.0472,
+                                                                arg("psi") = -0.7854,
+                                                                arg("n_ter") = false,
+                                                                arg("c_ter") = false,
                                                                 arg("probability_cutoff") = 0.98))
     .def("ConstructFRMRotamerGroup", &WrapFRMGroup_entries_aa,(arg("all_atom_pos"),
                                                                arg("all_atom_pos_idx"),
                                                                arg("rotamer_id"),
                                                                arg("residue_idx"),
                                                                arg("entries"),
+                                                               arg("phi") = -1.0472,
+                                                               arg("psi") = -0.7854,
+                                                               arg("n_ter") = false,
+                                                               arg("c_ter") = false,
                                                                arg("probability_cutoff") = 0.98))
     .def("ConstructBackboneFrameResidue", &WrapBBFrame_res,(arg("residue"),
                                                             arg("rotamer_id"),
                                                             arg("residue_index"),
                                                             arg("phi") = -1.0472,
+                                                            arg("psi") = -0.7854,
                                                             arg("n_ter")=false,
                                                             arg("c_ter")=false))
     .def("ConstructBackboneFrameResidue", &WrapBBFrame_aa,(arg("all_atom_pos"),
@@ -321,17 +397,38 @@ void export_RotamerConstructor(){
                                                            arg("rotamer_id"),
                                                            arg("residue_index"),
                                                            arg("phi") = -1.0472,
+                                                           arg("psi") = -0.7854,
                                                            arg("n_ter")=false,
                                                            arg("c_ter")=false))
     .def("ConstructSidechainFrameResidue", &WrapSCFrame_res,(arg("residue"),
                                                              arg("rotamer_id"),
-                                                             arg("residue_index")))
+                                                             arg("residue_index"),
+                                                             arg("phi") = -1.0472,
+                                                             arg("psi") = -0.7854,
+                                                             arg("n_ter")=false,
+                                                             arg("c_ter")=false))
     .def("ConstructSidechainFrameResidue", &WrapSCFrame_aa,(arg("all_atom_pos"),
                                                             arg("all_atom_pos_idx"),
                                                             arg("rotamer_id"),
-                                                            arg("residue_index")))
-    .def("AssignInternalEnergies", &AssignInternalEnergiesRRM)
-    .def("AssignInternalEnergies", &AssignInternalEnergiesFRM)
+                                                            arg("residue_index"),
+                                                            arg("phi") = -1.0472,
+                                                            arg("psi") = -0.7854,
+                                                            arg("n_ter")=false,
+                                                            arg("c_ter")=false))
+    .def("AssignInternalEnergies", &AssignInternalEnergiesRRM, (arg("rot_group"),
+                                                                arg("rotamer_id"),
+                                                                arg("residue_index"),
+                                                                arg("phi")=-1.0472,
+                                                                arg("psi")=-0.7854,
+                                                                arg("n_ter")=false,
+                                                                arg("c_ter")=false))
+    .def("AssignInternalEnergies", &AssignInternalEnergiesFRM, (arg("rot_group"),
+                                                                arg("rotamer_id"),
+                                                                arg("residue_index"),
+                                                                arg("phi")=-1.0472,
+                                                                arg("psi")=-0.7854,
+                                                                arg("n_ter")=false,
+                                                                arg("c_ter")=false))
   ;
 
 
diff --git a/sidechain/src/CMakeLists.txt b/sidechain/src/CMakeLists.txt
index ac3b4ed867e19ba8c82c75c02dbc454206686938..953b809ad3108aa9ae82d9431483ecdc8e6eaedc 100644
--- a/sidechain/src/CMakeLists.txt
+++ b/sidechain/src/CMakeLists.txt
@@ -18,6 +18,7 @@ set(SIDECHAIN_HEADERS
   sidechain_connector.hh
   sidechain_object_loader.hh
   rotamer_constructor.hh
+  rotamer_lookup.hh
   scwrl4_rotamer_constructor.hh
   subrotamer_optimizer.hh
 )
@@ -39,6 +40,7 @@ set(SIDECHAIN_SOURCES
   sidechain_connector.cc
   sidechain_object_loader.cc
   rotamer_constructor.cc
+  rotamer_lookup.cc
   scwrl4_rotamer_constructor.cc
   subrotamer_optimizer.cc
 )
diff --git a/sidechain/src/disulfid.cc b/sidechain/src/disulfid.cc
index 5cdb808cf97ab4b6dcba60b7d88b16419d51f00d..bfa4c682e95769d0a8ce303aab584698519e21c0 100644
--- a/sidechain/src/disulfid.cc
+++ b/sidechain/src/disulfid.cc
@@ -433,8 +433,8 @@ void ResolveCysteins(const std::vector<FRMRotamerGroupPtr>& rot_groups,
                      std::vector<std::pair<uint, uint> >& rotamer_indices) {
 
   CysteinResolve<FRMRotamerGroupPtr>(rot_groups, ca_pos, cb_pos,
-                                      disulfid_score_thresh, disulfid_indices,
-                                      rotamer_indices);
+                                     disulfid_score_thresh, disulfid_indices,
+                                     rotamer_indices);
 
   if(optimize_subrotamers) {
 
diff --git a/sidechain/src/rotamer_constructor.cc b/sidechain/src/rotamer_constructor.cc
index 3dfe130fcb331240a44ae2ab2b691af6dd4a95af..354e2c4b22b199c632d7f8ffa9536476c98ea320 100644
--- a/sidechain/src/rotamer_constructor.cc
+++ b/sidechain/src/rotamer_constructor.cc
@@ -14,239 +14,957 @@
 // limitations under the License.
 
 #include <promod3/sidechain/rotamer_constructor.hh>
+#include <promod3/loop/amino_acid_atoms.hh>
+#include <promod3/loop/sidechain_atom_constructor.hh>
 
 
+#include <promod3/sidechain/scwrl4_particle_scoring.hh>
+
 namespace promod3 { namespace sidechain{
 
-RotamerConstructor::RotamerConstructor() {
+RotamerConstructor::RotamerConstructor(bool cb_in_sidechain, 
+                                       RotamerLookupMode mode,
+                                       const RotamerLookupParam& param):
+                                  rotamer_lookup_(cb_in_sidechain, mode, param),
+                                  mode_(mode) {
+
   String s(XXX,'X');
   for(uint i = 0; i < XXX; ++i){
     s[i] = RotIDToOLC(RotamerID(i));
   }
   pos_buffer_ = boost::make_shared<promod3::loop::AllAtomPositions>(s);
+  hydrogen_buffer_ = boost::make_shared<promod3::loop::HydrogenStorage>();
 }
 
-
 // PUBLICLY ACCESSIBLE QUERY FUNCTIONS
 
 RRMRotamerGroupPtr RotamerConstructor::ConstructRRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
-        uint residue_index, RotamerLibPtr rot_lib, 
-        Real probability_cutoff) {
+        uint residue_idx, RotamerLibPtr rot_lib, Real phi,
+        Real psi, bool n_ter, bool c_ter, Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct RRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id);
-  this->SetPosBuffer(res, id);
-  return this->ConstructRRMGroup(id, residue_index, lib_entries, 
-                                 probability_cutoff);
+  this->SetPosBuffer(res);
+  return this->ConstructRRMGroup(lib_entries, probability_cutoff);
 }
 
+
 RRMRotamerGroupPtr RotamerConstructor::ConstructRRMRotamerGroup(
         const promod3::loop::AllAtomPositions& all_atom, 
-        uint aa_res_idx, RotamerID id, uint residue_index,
-        RotamerLibPtr rot_lib, Real probability_cutoff) {
+        uint aa_res_idx, RotamerID id, uint residue_idx,
+        RotamerLibPtr rot_lib, Real phi, Real psi, bool n_ter, bool c_ter,
+        Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct RRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id);
-  this->SetPosBuffer(all_atom, aa_res_idx, id);
-  return this->ConstructRRMGroup(id, residue_index, lib_entries, 
-                                 probability_cutoff);
+  this->SetPosBuffer(all_atom, aa_res_idx);
+  return this->ConstructRRMGroup(lib_entries, probability_cutoff);
 }
 
+
 FRMRotamerGroupPtr RotamerConstructor::ConstructFRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
-        uint residue_index, RotamerLibPtr rot_lib, 
-        Real probability_cutoff) {
+        uint residue_idx, RotamerLibPtr rot_lib, Real phi, Real psi,
+        bool n_ter, bool c_ter, Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct FRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id);
-  this->SetPosBuffer(res, id);
-  return this->ConstructFRMGroup(id, residue_index, lib_entries, 
-                                 probability_cutoff);
+  this->SetPosBuffer(res);
+  return this->ConstructFRMGroup(lib_entries, probability_cutoff);
 }
 
+
 FRMRotamerGroupPtr RotamerConstructor::ConstructFRMRotamerGroup(
         const promod3::loop::AllAtomPositions& all_atom, 
-        uint aa_res_idx, RotamerID id, uint residue_index,
-        RotamerLibPtr rot_lib, Real probability_cutoff) {
+        uint aa_res_idx, RotamerID id, uint residue_idx,
+        RotamerLibPtr rot_lib, Real phi, Real psi, bool n_ter, bool c_ter,
+        Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct FRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id);
-  this->SetPosBuffer(all_atom, aa_res_idx, id);
-  return this->ConstructFRMGroup(id, residue_index, lib_entries, 
-                                 probability_cutoff);
+  this->SetPosBuffer(all_atom, aa_res_idx);
+  return this->ConstructFRMGroup(lib_entries, probability_cutoff);
 }
 
+
 RRMRotamerGroupPtr RotamerConstructor::ConstructRRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
-        uint residue_index, BBDepRotamerLibPtr rot_lib, 
-        Real phi, Real psi, Real probability_cutoff) {
+        uint residue_idx, BBDepRotamerLibPtr rot_lib, 
+        Real phi, Real psi, bool n_ter, bool c_ter, Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct RRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id, phi, psi);
-  this->SetPosBuffer(res, id);
-  return this->ConstructRRMGroup(id, residue_index, lib_entries, 
-                                 probability_cutoff);
+  this->SetPosBuffer(res);
+  return this->ConstructRRMGroup(lib_entries, probability_cutoff);
 }
 
+
 RRMRotamerGroupPtr RotamerConstructor::ConstructRRMRotamerGroup(
         const promod3::loop::AllAtomPositions& all_atom, 
-        uint aa_res_idx, RotamerID id, uint residue_index,
+        uint aa_res_idx, RotamerID id, uint residue_idx,
         BBDepRotamerLibPtr rot_lib, 
-        Real phi, Real psi, Real probability_cutoff) {
+        Real phi, Real psi, bool n_ter, bool c_ter, Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct RRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id, phi, psi);
-  this->SetPosBuffer(all_atom, aa_res_idx, id);
-  return this->ConstructRRMGroup(id, residue_index, lib_entries, 
-                                 probability_cutoff);
+  this->SetPosBuffer(all_atom, aa_res_idx);
+  return this->ConstructRRMGroup(lib_entries, probability_cutoff);
 }
 
+
 FRMRotamerGroupPtr RotamerConstructor::ConstructFRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
-        uint residue_index, BBDepRotamerLibPtr rot_lib, 
-        Real phi, Real psi, Real probability_cutoff) {
+        uint residue_idx, BBDepRotamerLibPtr rot_lib, 
+        Real phi, Real psi, bool n_ter, bool c_ter, Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct FRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id, phi, psi);
-  this->SetPosBuffer(res, id);
-  return this->ConstructFRMGroup(id, residue_index, lib_entries, 
-                                 probability_cutoff);
+  this->SetPosBuffer(res);
+  return this->ConstructFRMGroup(lib_entries, probability_cutoff);
 }
 
+
 FRMRotamerGroupPtr RotamerConstructor::ConstructFRMRotamerGroup(
         const promod3::loop::AllAtomPositions& all_atom, 
-        uint aa_res_idx, RotamerID id, uint residue_index,
+        uint aa_res_idx, RotamerID id, uint residue_idx,
         BBDepRotamerLibPtr rot_lib, 
-        Real phi, Real psi, Real probability_cutoff) {
+        Real phi, Real psi, bool n_ter, bool c_ter, Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct FRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id, phi, psi);
-  this->SetPosBuffer(all_atom, aa_res_idx, id);
-  return this->ConstructFRMGroup(id, residue_index, lib_entries, 
-                                 probability_cutoff);
+  this->SetPosBuffer(all_atom, aa_res_idx);
+  return this->ConstructFRMGroup(lib_entries, probability_cutoff);
 }
 
+
 RRMRotamerGroupPtr RotamerConstructor::ConstructRRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
-        uint residue_index, 
+        uint residue_idx, 
         std::vector<RotamerLibEntry>& lib_entries, 
-        Real probability_cutoff) {
+        Real phi, Real psi, bool n_ter, bool c_ter, Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct RRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> I_LIKE_CHEESE = 
   std::make_pair(&lib_entries[0], lib_entries.size());
-  this->SetPosBuffer(res, id);
-  return this->ConstructRRMGroup(id, residue_index, I_LIKE_CHEESE, 
-                                 probability_cutoff);
+  this->SetPosBuffer(res);
+  return this->ConstructRRMGroup(I_LIKE_CHEESE, probability_cutoff);
 }
 
+
 RRMRotamerGroupPtr RotamerConstructor::ConstructRRMRotamerGroup(
         const promod3::loop::AllAtomPositions& all_atom, 
-        uint aa_res_idx, RotamerID id, uint residue_index,
+        uint aa_res_idx, RotamerID id, uint residue_idx,
         std::vector<RotamerLibEntry>& lib_entries, 
-        Real probability_cutoff) {
+        Real phi, Real psi, bool n_ter, bool c_ter, Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct RRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> I_LIKE_CHEESE = 
   std::make_pair(&lib_entries[0], lib_entries.size());
-  this->SetPosBuffer(all_atom, aa_res_idx, id);
-  return this->ConstructRRMGroup(id, residue_index, I_LIKE_CHEESE, 
-                                 probability_cutoff);
+  this->SetPosBuffer(all_atom, aa_res_idx);
+  return this->ConstructRRMGroup(I_LIKE_CHEESE, probability_cutoff);
 }
 
+
 FRMRotamerGroupPtr RotamerConstructor::ConstructFRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
-        uint residue_index, std::vector<RotamerLibEntry>& lib_entries, 
-        Real probability_cutoff) {
+        uint residue_idx, std::vector<RotamerLibEntry>& lib_entries, 
+        Real phi, Real psi, bool n_ter, bool c_ter, Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct FRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> I_LIKE_CHEESE = 
   std::make_pair(&lib_entries[0], lib_entries.size());
-  this->SetPosBuffer(res, id);
-  return this->ConstructFRMGroup(id, residue_index, I_LIKE_CHEESE, 
-                                 probability_cutoff);
+  this->SetPosBuffer(res);
+  return this->ConstructFRMGroup(I_LIKE_CHEESE, probability_cutoff);
 }
 
+
 FRMRotamerGroupPtr RotamerConstructor::ConstructFRMRotamerGroup(
         const promod3::loop::AllAtomPositions& all_atom, 
-        uint aa_res_idx, RotamerID id, uint residue_index,
+        uint aa_res_idx, RotamerID id, uint residue_idx,
         std::vector<RotamerLibEntry>& lib_entries, 
-        Real probability_cutoff) {
+        Real phi, Real psi, bool n_ter, bool c_ter, Real probability_cutoff) {
 
   if(id == XXX) {
     throw promod3::Error("Cannot construct FRMRotamerGroup for unknown "
                          "rotamer id!");
   }
 
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
   std::pair<RotamerLibEntry*,uint> I_LIKE_CHEESE = 
   std::make_pair(&lib_entries[0], lib_entries.size());
-  this->SetPosBuffer(all_atom, aa_res_idx, id);
-  return this->ConstructFRMGroup(id, residue_index, I_LIKE_CHEESE, 
-                                 probability_cutoff);
+  this->SetPosBuffer(all_atom, aa_res_idx);
+  return this->ConstructFRMGroup(I_LIKE_CHEESE, probability_cutoff);
 }
 
-void RotamerConstructor::AssignInternalEnergies(RRMRotamerGroupPtr group) {
+
+FrameResiduePtr RotamerConstructor::ConstructBackboneFrameResidue(
+          const ost::mol::ResidueHandle& res, RotamerID id, uint residue_idx,
+          Real phi, Real psi, bool n_ter, bool c_ter) {
+
+  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
+          "RotamerConstructor::ConstructBackboneFrameResidue", 2);
+
+  if(id == XXX) {
+    throw promod3::Error("Cannot construct FrameResidue for unknown "
+                         "rotamer id!");
+  }
+
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
+
+  const RotamerInfo& info = rotamer_lookup_.GetBackboneInfo(id);
+
+  for(uint i = 0; i < info.particles.size(); ++i){
+    if(!info.particles[i].is_hydrogen){
+      ost::mol::AtomHandle a = res.FindAtom(info.particles[i].name);
+      if(!a.IsValid()){
+        throw promod3::Error("Expected atom " + info.particles[i].name + 
+                             " to be present in input residue!");
+      }
+      pos_buffer_->SetPos(id, info.particles[i].atom_idx, a.GetPos());
+    }
+  }
+
+  return this->ConstructBackboneFrameResidue();
+}
+
+
+FrameResiduePtr RotamerConstructor::ConstructBackboneFrameResidue(
+          const promod3::loop::AllAtomPositions& all_atom, uint aa_res_idx, 
+          RotamerID id, uint residue_idx,
+          Real phi, Real psi, bool n_ter, bool c_ter) {
+
+  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
+          "RotamerConstructor::ConstructBackboneFrameResidue", 2);
+
+  if(id == XXX) {
+    throw promod3::Error("Cannot construct FrameResidue for unknown "
+                         "rotamer id!");
+  }
+
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
+
+  const RotamerInfo& info = rotamer_lookup_.GetBackboneInfo(id);
+
+  for(uint i = 0; i < info.particles.size(); ++i){
+    if(!info.particles[i].is_hydrogen){
+
+      if(!all_atom.IsSet(aa_res_idx, info.particles[i].atom_idx)){
+        throw promod3::Error("Expected atom " + info.particles[i].name +
+                             " to be set in all_atom");
+      }
+
+      pos_buffer_->SetPos(id, info.particles[i].atom_idx, 
+                          all_atom.GetPos(aa_res_idx, info.particles[i].atom_idx));
+    }
+  }
+
+  return this->ConstructBackboneFrameResidue();
+}
+
+
+FrameResiduePtr RotamerConstructor::ConstructSidechainFrameResidue(
+        const ost::mol::ResidueHandle& res, RotamerID id, uint residue_idx,
+        Real phi, Real psi, bool n_ter, bool c_ter) {
+
+  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
+          "RotamerConstructor::ConstructSidechainFrameResidue", 2);
+
+  if(id == XXX) {
+    throw promod3::Error("Cannot construct FrameResidue for unknown "
+                         "rotamer id!");
+  }
+
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
+
+  const RotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id);
+
+  for(uint i = 0; i < info.particles.size(); ++i){
+    if(!info.particles[i].is_hydrogen){
+      ost::mol::AtomHandle a = res.FindAtom(info.particles[i].name);
+      if(!a.IsValid()){
+        throw promod3::Error("Expected atom " + info.particles[i].name + 
+                             " to be present in input residue!");
+      }
+      pos_buffer_->SetPos(id, info.particles[i].atom_idx, a.GetPos());
+    }
+  }
+
+  //set bb hydrogen
+  if(info.has_hydrogens){
+    // to construct hydrogens, we might also need backbone atoms in the buffer
+    const RotamerInfo& bb_info = rotamer_lookup_.GetBackboneInfo(id);
+
+    for(uint i = 0; i < bb_info.particles.size(); ++i){
+      if(!bb_info.particles[i].is_hydrogen){
+        ost::mol::AtomHandle a = res.FindAtom(bb_info.particles[i].name);
+        if(!a.IsValid()){
+          throw promod3::Error("Expected atom " + bb_info.particles[i].name + 
+                               " to be present in input residue!");
+        }
+        pos_buffer_->SetPos(id, bb_info.particles[i].atom_idx, a.GetPos());
+      }
+    }
+
+    promod3::loop::ConstructHydrogens(*pos_buffer_, id, *hydrogen_buffer_, 
+                                      mode_ == POLAR_HYDROGEN_MODE, 
+                                      promod3::loop::PROT_STATE_HISH);
+  }
+
+  int num_particles = info.particles.size();
+  std::vector<Particle> particles(num_particles);
+
+  for(int i = 0; i < num_particles; ++i) {
+    const ParticleInfo& pi = info.particles[i];
+    particles[i].SetName(pi.name);
+    this->ParametrizeParticle(pi.atom_idx, pi.is_hydrogen, particles[i]);
+  }
+
+  FrameResiduePtr p = boost::make_shared<FrameResidue>(particles, 
+                                                       residue_idx);
+
+  return p;
+}
+
+
+FrameResiduePtr RotamerConstructor::ConstructSidechainFrameResidue(
+          const promod3::loop::AllAtomPositions& all_atom, uint aa_res_idx, 
+          RotamerID id, uint residue_idx, Real phi, Real psi, 
+          bool n_ter, bool c_ter) {
+
+  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
+          "RotamerConstructor::ConstructSidechainFrameResidue", 2);
+
+  if(id == XXX) {
+    throw promod3::Error("Cannot construct FrameResidue for unknown "
+                         "rotamer id!");
+  }
+
+  id_ = id;
+  residue_idx_ = residue_idx;
+  phi_ = phi;
+  psi_ = psi;
+  n_ter_ = n_ter;
+  c_ter_ = c_ter;
+
+  const RotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id);
+
+  for(uint i = 0; i < info.particles.size(); ++i){
+    if(!info.particles[i].is_hydrogen){
+      if(!all_atom.IsSet(aa_res_idx, info.particles[i].atom_idx)){
+        throw promod3::Error("Expected atom " + info.particles[i].name +
+                             " to be set in all_atom");
+      }
+      pos_buffer_->SetPos(id, info.particles[i].atom_idx, 
+                          all_atom.GetPos(aa_res_idx, info.particles[i].atom_idx));
+    }
+  }
+
+  //set hydrogens
+  if(info.has_hydrogens){
+    // to construct hydrogens, we might also need backbone atoms in the buffer
+    const RotamerInfo& bb_info = rotamer_lookup_.GetBackboneInfo(id);
+
+    for(uint i = 0; i < bb_info.particles.size(); ++i){
+      if(!bb_info.particles[i].is_hydrogen){
+        if(!all_atom.IsSet(aa_res_idx, bb_info.particles[i].atom_idx)){
+          throw promod3::Error("Expected atom " + bb_info.particles[i].name +
+                               " to be set in all_atom");
+        }
+        pos_buffer_->SetPos(id, bb_info.particles[i].atom_idx, 
+                            all_atom.GetPos(aa_res_idx, bb_info.particles[i].atom_idx));
+      }
+    }
+
+    promod3::loop::ConstructHydrogens(*pos_buffer_, id, *hydrogen_buffer_, 
+                                      mode_ == POLAR_HYDROGEN_MODE, 
+                                      promod3::loop::PROT_STATE_HISH);
+  }
+
+  int num_particles = info.particles.size();
+  std::vector<Particle> particles(num_particles);
+
+  for(int i = 0; i < num_particles; ++i) {
+    const ParticleInfo& pi = info.particles[i];
+    particles[i].SetName(pi.name);
+    this->ParametrizeParticle(pi.atom_idx, pi.is_hydrogen, particles[i]);
+  }
+
+  FrameResiduePtr p = boost::make_shared<FrameResidue>(particles, 
+                                                       residue_idx);
+
+  return p; 
+}
+
+
+void RotamerConstructor::AssignInternalEnergies(RRMRotamerGroupPtr group, 
+                                                RotamerID id,
+                                                uint residue_idx,
+                                                Real phi, Real psi,
+                                                bool n_ter, bool c_ter) {
   for(uint i = 0; i < group->size(); ++i){
     (*group)[i]->SetInternalEnergy(0.0);
   }
 }
 
-void RotamerConstructor::AssignInternalEnergies(FRMRotamerGroupPtr group) {
+
+void RotamerConstructor::AssignInternalEnergies(FRMRotamerGroupPtr group,
+                                                RotamerID id,
+                                                uint residue_idx,
+                                                Real phi, Real psi,
+                                                bool n_ter, bool c_ter) {
   for(uint i = 0; i < group->size(); ++i){
     (*group)[i]->SetInternalEnergy(0.0);
   }
 }
 
-void RotamerConstructor::SetPosBuffer(const ost::mol::ResidueHandle& res,
-                                           RotamerID id) {
+
+RRMRotamerGroupPtr RotamerConstructor::ConstructRRMGroup(
+          std::pair<RotamerLibEntry*,uint> lib_entries, 
+          Real probability_cutoff) {
+
+  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
+          "RotamerConstructor::ConstructRRMGroup", 2);
+
+  std::vector<RRMRotamerPtr> rotamers;
+  Real summed_prob = 0.0;
+
+  // in case of his, we have to move the backbone positions in the buffer
+  // to the locations defining his in the different protonation states
+  if(id_ == HIS && mode_ != HEAVY_ATOM_MODE){
+    MVBBPosBuffer(HIS, HSD);
+    MVBBPosBuffer(HIS, HSE);
+  }
+
+  // in case of alanine and glycine, the rotamer libraries won't have any 
+  // entries. For consistency we nevertheless construct rotamers.
+  // We simply add a fake RotamerLibEntry in this case that has
+  // no sidechain dihedrals set. In case of Alanine we might still have
+  // some atoms in (depending on cb_in_sidechain flag)
+  std::vector<RotamerLibEntry> fake_rotamers(1);
+  if(lib_entries.second == 0 && (id_ == ALA || id_ == GLY)) {
+    // we have to make sure, that the according probability really is one!
+    fake_rotamers[0].probability = 1.0;
+    lib_entries = std::make_pair(&fake_rotamers[0], 1);
+  }
+  else if(lib_entries.second == 0) {
+    throw promod3::Error("Did not find any rotamers in Rotamer Library!");
+  }
+
+  for(uint i = 0; i < lib_entries.second; ++i){
+
+    probability_ = lib_entries.first[i].probability;
+    summed_prob += probability_;
+    chi_angles_[0] = lib_entries.first[i].chi1;
+    chi_angles_[1] = lib_entries.first[i].chi2;
+    chi_angles_[2] = lib_entries.first[i].chi3;
+    chi_angles_[3] = lib_entries.first[i].chi4;
+
+    if(mode_ == HEAVY_ATOM_MODE) {
+      rotamers.push_back(ConstructRRM());
+    } else {
+      // in POLAR_HYDROGEN_MODE or FULL_ATOMIC_MODE we're sampling
+      // polar hydrogens of SER/THR/TYR and construct different
+      // rotamers for HIS
+      switch(id_){
+        case HIS:{
+          id_ = HSE;
+          rotamers.push_back(ConstructRRM());
+          id_ = HSD;
+          rotamers.push_back(ConstructRRM());
+          id_ = HIS;
+          break;
+        }
+        case SER:{
+          chi_angles_[1] = Real(M_PI);
+          rotamers.push_back(ConstructRRM());
+          chi_angles_[1] = Real(M_PI) / 3.0;
+          rotamers.push_back(ConstructRRM());
+          chi_angles_[1] = -Real(M_PI) / 3.0;
+          rotamers.push_back(ConstructRRM());
+          break;
+        }
+        case THR:{
+          chi_angles_[1] = Real(M_PI);
+          rotamers.push_back(ConstructRRM());
+          chi_angles_[1] = Real(M_PI) / 3.0;
+          rotamers.push_back(ConstructRRM());
+          chi_angles_[1] = -Real(M_PI) / 3.0;
+          rotamers.push_back(ConstructRRM()); 
+          break;       
+        }
+        case TYR:{
+          chi_angles_[2] = Real(M_PI);
+          rotamers.push_back(ConstructRRM());
+          chi_angles_[2] = Real(0.0);
+          rotamers.push_back(ConstructRRM());
+          break;
+        }
+        default:{
+          rotamers.push_back(ConstructRRM());
+        }
+      }
+    }
+
+    if(summed_prob >= probability_cutoff && !rotamers.empty()) break;
+  } 
+  
+  RRMRotamerGroupPtr group = boost::make_shared<RRMRotamerGroup>(rotamers,
+                                                                 residue_idx_);
+  this->AssignInternalEnergies(group, id_, residue_idx_, phi_, psi_, n_ter_, c_ter_);
+  return group;
+}
+
+
+FRMRotamerGroupPtr RotamerConstructor::ConstructFRMGroup(
+          std::pair<RotamerLibEntry*,uint> lib_entries, 
+          Real probability_cutoff) {
+
+  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
+          "RotamerConstructor::ConstructFRMGroup", 2);
+
+  std::vector<FRMRotamerPtr> rotamers;
+  Real summed_prob = 0.0;
+
+  // in case of his, we have to move the backbone positions in the buffer
+  // to the locations defining his in the different protonation states
+  if(id_ == HIS && mode_ != HEAVY_ATOM_MODE){
+    MVBBPosBuffer(HIS, HSD);
+    MVBBPosBuffer(HIS, HSE);
+  }
+
+  // in case of alanine and glycine, the rotamer libraries won't have any 
+  // entries. For consistency we nevertheless construct rotamers.
+  // We simply add a fake RotamerLibEntry in this case that has
+  // no sidechain dihedrals set. In case of Alanine we might still have
+  // some atoms in (depending on cb_in_sidechain flag)
+  std::vector<RotamerLibEntry> fake_rotamers(1);
+  if(lib_entries.second == 0 && (id_ == ALA || id_ == GLY)) {
+    // we have to make sure, that the according probability really is one!
+    fake_rotamers[0].probability = 1.0;
+    lib_entries = std::make_pair(&fake_rotamers[0], 1);
+  }
+  else if(lib_entries.second == 0) {
+    throw promod3::Error("Did not find any rotamers in Rotamer Library!");
+  }
+
+  for(uint i = 0; i < lib_entries.second; ++i){
+    probability_ = lib_entries.first[i].probability;
+    summed_prob += probability_;
+    chi_angles_[0] = lib_entries.first[i].chi1;
+    chi_angles_[1] = lib_entries.first[i].chi2;
+    chi_angles_[2] = lib_entries.first[i].chi3;
+    chi_angles_[3] = lib_entries.first[i].chi4;
+    chi_dev_[0] = lib_entries.first[i].sig1;
+    chi_dev_[1] = lib_entries.first[i].sig2;
+    chi_dev_[2] = lib_entries.first[i].sig3;
+    chi_dev_[3] = lib_entries.first[i].sig4;
+    if(mode_ == HEAVY_ATOM_MODE) {
+      rotamers.push_back(ConstructFRM());
+    } else {
+      switch(id_){
+        case HIS:{
+          id_ = HSE;
+          rotamers.push_back(ConstructFRM());
+          id_ = HSD;
+          rotamers.push_back(ConstructFRM());
+          id_ = HIS;
+          break;
+        }
+        case SER:{
+          chi_dev_[1] = Real(0.17453);
+          chi_angles_[1] = Real(M_PI);
+          rotamers.push_back(ConstructFRM());
+          chi_angles_[1] = Real(M_PI) / Real(3.0);
+          rotamers.push_back(ConstructFRM());
+          chi_angles_[1] = -Real(M_PI) / Real(3.0);
+          rotamers.push_back(ConstructFRM());
+          break;
+        }
+        case THR:{
+          chi_dev_[1] = Real(0.17453);
+          chi_angles_[1] = Real(M_PI);
+          rotamers.push_back(ConstructFRM());
+          chi_angles_[1] = Real(M_PI) / Real(3.0);
+          rotamers.push_back(ConstructFRM());
+          chi_angles_[1] = -Real(M_PI) / Real(3.0);
+          rotamers.push_back(ConstructFRM()); 
+          break;       
+        }
+        case TYR:{
+          chi_dev_[2] = Real(0.17453);
+          chi_angles_[2] = Real(M_PI);
+          rotamers.push_back(ConstructFRM());
+          chi_angles_[2] = Real(0.0);
+          rotamers.push_back(ConstructFRM());
+          break;
+        }
+        default: rotamers.push_back(ConstructFRM());
+      }
+    }
+
+    if(summed_prob >= probability_cutoff && !rotamers.empty()) break;
+  } 
+  
+  FRMRotamerGroupPtr group = boost::make_shared<FRMRotamerGroup>(rotamers,
+                                                                 residue_idx_);
+  this->AssignInternalEnergies(group, id_, residue_idx_, phi_, psi_, n_ter_, c_ter_);
+
+  return group;
+}
+
+
+RRMRotamerPtr RotamerConstructor::ConstructRRM() {
+
+  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
+          "RotamerConstructor::ConstructRRM", 2);
+
+  const RotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id_);
+
+  //set the positions
+  promod3::loop::ConstructSidechainAtoms(*pos_buffer_, id_, chi_angles_[0], 
+                                         chi_angles_[1], chi_angles_[2],
+                                         chi_angles_[3]);
+
+  if(info.has_hydrogens){
+
+    promod3::loop::ConstructHydrogens(*pos_buffer_, id_, *hydrogen_buffer_, 
+                                      mode_ == POLAR_HYDROGEN_MODE, 
+                                      promod3::loop::PROT_STATE_HISH);
+
+    // If there are any custom rules, we apply them now and overrule the
+    // default hydrogen construction
+    if(!info.custom_hydrogens.empty()){
+      for(uint i = 0; i < info.custom_hydrogens.size(); ++i){
+        const CustomHydrogenInfo& h_info = info.custom_hydrogens[i];
+        geom::Vec3 anchor_one, anchor_two, anchor_three, new_h_pos;
+        anchor_one = pos_buffer_->GetPos(id_, h_info.anchor_idx_one);
+        anchor_two = pos_buffer_->GetPos(id_, h_info.anchor_idx_two);
+        anchor_three = pos_buffer_->GetPos(id_, h_info.anchor_idx_three);
+        promod3::core::ConstructAtomPos(anchor_one, anchor_two, anchor_three,
+                                        h_info.bond_length, h_info.angle, 
+                                        chi_angles_[h_info.chi_idx], new_h_pos);
+        hydrogen_buffer_->SetPos(h_info.atom_idx, new_h_pos);
+      }
+    }
+  }
+
+  int num_particles = info.particles.size();
+  std::vector<Particle> particles(num_particles);
+  for(int i = 0; i < num_particles; ++i) {
+    const ParticleInfo& pi = info.particles[i];
+    particles[i].SetName(pi.name);
+    this->ParametrizeParticle(pi.atom_idx, pi.is_hydrogen, particles[i]);
+  }
+
+  RRMRotamerPtr rot = boost::make_shared<RRMRotamer>(particles, 
+                                                     probability_, 
+                                                     info.internal_e_prefactor);
+
+  return rot; 
+}
+
+
+FRMRotamerPtr RotamerConstructor::ConstructFRM() {
+
+  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
+          "RotamerConstructor::ConstructFRM", 2);
+
+  const RotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id_);
+
+  //set the positions
+  promod3::loop::ConstructSidechainAtoms(*pos_buffer_, id_, chi_angles_[0], 
+                                         chi_angles_[1], chi_angles_[2],
+                                         chi_angles_[3]);
+  if(info.has_hydrogens){
+    promod3::loop::ConstructHydrogens(*pos_buffer_, id_, *hydrogen_buffer_, 
+                                      mode_ == POLAR_HYDROGEN_MODE, 
+                                      promod3::loop::PROT_STATE_HISH);
+    // If there are any custom rules, we apply them now an overrule the
+    // default hydrogen construction
+    if(!info.custom_hydrogens.empty()){
+      for(uint i = 0; i < info.custom_hydrogens.size(); ++i){
+        const CustomHydrogenInfo& h_info = info.custom_hydrogens[i];
+        geom::Vec3 anchor_one, anchor_two, anchor_three, new_h_pos;
+        anchor_one = pos_buffer_->GetPos(id_, h_info.anchor_idx_one);
+        anchor_two = pos_buffer_->GetPos(id_, h_info.anchor_idx_two);
+        anchor_three = pos_buffer_->GetPos(id_, h_info.anchor_idx_three);
+        promod3::core::ConstructAtomPos(anchor_one, anchor_two, anchor_three,
+                                        h_info.bond_length, h_info.angle, 
+                                        chi_angles_[h_info.chi_idx], new_h_pos);
+        hydrogen_buffer_->SetPos(h_info.atom_idx, new_h_pos);
+      }
+    }
+  }
+
+  int num_rrm_particles = rotamer_lookup_.GetNumSidechainParticles(id_);
+  int num_particles = rotamer_lookup_.GetNumFRMSidechainParticles(id_);
+  std::vector<Particle> particles(num_particles);
+
+  for(int i = 0; i < num_rrm_particles; ++i) {
+    const ParticleInfo& pi = info.particles[i];
+    particles[i].SetName(pi.name);
+    this->ParametrizeParticle(pi.atom_idx, pi.is_hydrogen, particles[i]);
+  }
+
+  // Keep track of the subrotamers
+  std::vector<std::vector<int> > subrotamer_definitions;
+  std::vector<int> actual_definition;
+  actual_definition.resize(num_rrm_particles);
+  // Directly add the first particles as first subrotamer
+  for(int i = 0; i < num_rrm_particles; ++i) actual_definition[i] = i;
+  subrotamer_definitions.push_back(actual_definition);
+
+  const std::vector<FRMRule>& frm_rules = rotamer_lookup_.GetFRMRules(id_);
+  geom::Vec3 rot_axis, rot_anchor;
+  geom::Vec3 orig_pos, rot_pos;
+  geom::Mat4 transform;
+  int base_idx = num_rrm_particles;
+
+  for(uint frm_rule_idx = 0; frm_rule_idx < frm_rules.size(); ++frm_rule_idx){
+    const FRMRule& frm_rule = frm_rules[frm_rule_idx];
+    int num_fix_particles = frm_rule.fix_particles.size();
+    int num_rotating_particles = frm_rule.rotating_particles.size();
+
+    // Update the subrotamer definition... all particles that are fixed are 
+    // taken from the first subrotamer.
+    for(int i = 0; i < num_fix_particles; ++i) {
+      actual_definition[i] = frm_rule.fix_particles[i];
+    }
+
+    // The data required for the rotation around the specified axis
+    rot_anchor = pos_buffer_->GetPos(id_, frm_rule.anchor_idx_two);
+    rot_axis = rot_anchor - pos_buffer_->GetPos(id_, frm_rule.anchor_idx_one); 
+
+    // Every rotation results in a new subrotamer
+    for(uint prefac_idx = 0; prefac_idx < frm_rule.prefactors.size(); 
+        ++prefac_idx){
+
+      // Get the rotation matrix
+      Real rot_angle = frm_rule.prefactors[prefac_idx] * chi_dev_[frm_rule_idx];
+      transform = promod3::core::RotationAroundLine(rot_axis, rot_anchor,
+                                                    rot_angle);
+
+      for(int i = 0; i < num_rotating_particles; ++i){
+        int orig_particle_idx = frm_rule.rotating_particles[i];
+        int new_particle_idx = base_idx + i;
+
+        // replace the old with the new index...
+        actual_definition[orig_particle_idx] = new_particle_idx;
+
+        // construct the rotated particle
+        particles[new_particle_idx] = particles[orig_particle_idx];
+        particles[new_particle_idx].ApplyTransform(transform);
+      }
+
+      subrotamer_definitions.push_back(actual_definition);
+
+      // start of next subrotamer
+      base_idx += num_rotating_particles;
+    }
+  }
+
+  FRMRotamerPtr r = boost::make_shared<FRMRotamer>(particles,
+                                                   info.frm_t, probability_,
+                                                   info.internal_e_prefactor);
+
+
+
+  for(uint i = 0; i < subrotamer_definitions.size(); ++i) {
+    r->AddSubrotamerDefinition(subrotamer_definitions[i]);
+  }
+
+  return r;
+}
+
+
+FrameResiduePtr RotamerConstructor::ConstructBackboneFrameResidue() {
+
+  const RotamerInfo& info = rotamer_lookup_.GetBackboneInfo(id_);
+
+  // set hydrogens (also enter if its an n_ter because proline would have no 
+  // hydrogen)
+  if(info.has_hydrogens || n_ter_){
+    if(mode_ == FULL_ATOMIC_MODE) {
+      promod3::loop::ConstructHydrogens(*pos_buffer_, id_, *hydrogen_buffer_,
+                                        mode_ == POLAR_HYDROGEN_MODE,
+                                        promod3::loop::PROT_STATE_HISH);
+    }
+    if(n_ter_) {
+      promod3::loop::ConstructHydrogenNTerminal(*pos_buffer_, id_, 
+                                                *hydrogen_buffer_);
+    } else {
+      promod3::loop::ConstructHydrogenN(*pos_buffer_, id_, phi_, 
+                                        *hydrogen_buffer_); 
+    }
+  }
+  if(c_ter_) {
+    promod3::core::ConstructCTerminalOxygens(
+                            pos_buffer_->GetPos(id_, promod3::loop::BB_C_INDEX),
+                            pos_buffer_->GetPos(id_, promod3::loop::BB_CA_INDEX),
+                            pos_buffer_->GetPos(id_, promod3::loop::BB_N_INDEX),
+                            terminal_o_pos_, terminal_oxt_pos_); 
+  } 
+  std::vector<Particle> particles;
+  if(n_ter_ || c_ter_) {
+    RotamerInfo terminal_info = 
+    rotamer_lookup_.GetTerminalBackboneInfo(id_, n_ter_, c_ter_);
+    int num_particles = terminal_info.particles.size();
+    particles.resize(num_particles);
+    for(int i = 0; i < num_particles; ++i) {
+      ParticleInfo& pi = terminal_info.particles[i];
+      particles[i].SetName(pi.name);
+      this->ParametrizeParticle(pi.atom_idx, pi.is_hydrogen, particles[i]);
+    }
+  } else {
+    int num_particles = info.particles.size();
+    particles.resize(num_particles);
+    for(int i = 0; i < num_particles; ++i) {
+      const ParticleInfo& pi = info.particles[i];
+      particles[i].SetName(pi.name);
+      this->ParametrizeParticle(pi.atom_idx, pi.is_hydrogen, particles[i]);
+    }    
+  }
+
+  FrameResiduePtr p = boost::make_shared<FrameResidue>(particles, residue_idx_);
+  return p; 
+}
+
+
+void RotamerConstructor::SetPosBuffer(const ost::mol::ResidueHandle& res) {
 
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::SetPosBuffer_residue", 2);
+          "RotamerConstructor::SetPosBuffer_residue", 2);
 
   ost::mol::AtomHandle n = res.FindAtom("N");
   ost::mol::AtomHandle ca = res.FindAtom("CA");
@@ -259,25 +977,26 @@ void RotamerConstructor::SetPosBuffer(const ost::mol::ResidueHandle& res,
                          "rotamer!");
   }
 
-  pos_buffer_->SetPos(id, promod3::loop::BB_N_INDEX, n.GetPos());
-  pos_buffer_->SetPos(id, promod3::loop::BB_CA_INDEX, ca.GetPos());
-  pos_buffer_->SetPos(id, promod3::loop::BB_C_INDEX, c.GetPos());
-  pos_buffer_->SetPos(id, promod3::loop::BB_O_INDEX, o.GetPos());
+  pos_buffer_->SetPos(id_, promod3::loop::BB_N_INDEX, n.GetPos());
+  pos_buffer_->SetPos(id_, promod3::loop::BB_CA_INDEX, ca.GetPos());
+  pos_buffer_->SetPos(id_, promod3::loop::BB_C_INDEX, c.GetPos());
+  pos_buffer_->SetPos(id_, promod3::loop::BB_O_INDEX, o.GetPos());
 
-  if(id != GLY) {
+  if(id_ != GLY) {
     if(!cb.IsValid()) {
       throw promod3::Error("All backbone atoms must be valid to construct "
                            "rotamer!");
     }
-    pos_buffer_->SetPos(id, promod3::loop::BB_CB_INDEX, cb.GetPos());
+    pos_buffer_->SetPos(id_, promod3::loop::BB_CB_INDEX, cb.GetPos());
   }
 }
 
+
 void RotamerConstructor::SetPosBuffer(const promod3::loop::AllAtomPositions& all_atom_pos,
-                                           uint all_atom_idx, RotamerID id) {
+                                      uint all_atom_idx) {
 
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::SetPosBuffer_all_atom_pos", 2);
+          "RotamerConstructor::SetPosBuffer_all_atom_pos", 2);
 
 
   if(!(all_atom_pos.IsSet(all_atom_idx, promod3::loop::BB_N_INDEX) &&
@@ -288,29 +1007,45 @@ void RotamerConstructor::SetPosBuffer(const promod3::loop::AllAtomPositions& all
                          "rotamer!");
   }
 
-  pos_buffer_->SetPos(id, promod3::loop::BB_N_INDEX, 
+  pos_buffer_->SetPos(id_, promod3::loop::BB_N_INDEX, 
                       all_atom_pos.GetPos(all_atom_idx, 
                                           promod3::loop::BB_N_INDEX));
-  pos_buffer_->SetPos(id, promod3::loop::BB_CA_INDEX, 
+  pos_buffer_->SetPos(id_, promod3::loop::BB_CA_INDEX, 
                       all_atom_pos.GetPos(all_atom_idx, 
                                           promod3::loop::BB_CA_INDEX));
-  pos_buffer_->SetPos(id, promod3::loop::BB_C_INDEX, 
+  pos_buffer_->SetPos(id_, promod3::loop::BB_C_INDEX, 
                       all_atom_pos.GetPos(all_atom_idx, 
                                           promod3::loop::BB_C_INDEX));
-  pos_buffer_->SetPos(id, promod3::loop::BB_O_INDEX, 
+  pos_buffer_->SetPos(id_, promod3::loop::BB_O_INDEX, 
                       all_atom_pos.GetPos(all_atom_idx, 
                                           promod3::loop::BB_O_INDEX));  
 
-  if(id != GLY) {
+  if(id_ != GLY) {
     if(!all_atom_pos.IsSet(all_atom_idx, promod3::loop::BB_CB_INDEX)) {
       throw promod3::Error("All backbone atoms must be valid to construct "
                            "rotamer!");
     }
-    pos_buffer_->SetPos(id, promod3::loop::BB_CB_INDEX, 
+    pos_buffer_->SetPos(id_, promod3::loop::BB_CB_INDEX, 
                         all_atom_pos.GetPos(all_atom_idx, 
                                             promod3::loop::BB_CB_INDEX));
-
   }
 }
 
+
+void RotamerConstructor::MVBBPosBuffer(RotamerID from, RotamerID to) {
+  pos_buffer_->SetPos(to, promod3::loop::BB_N_INDEX, 
+                      pos_buffer_->GetPos(from, promod3::loop::BB_N_INDEX));
+  pos_buffer_->SetPos(to, promod3::loop::BB_CA_INDEX, 
+                      pos_buffer_->GetPos(from, promod3::loop::BB_CA_INDEX));
+  pos_buffer_->SetPos(to, promod3::loop::BB_C_INDEX, 
+                      pos_buffer_->GetPos(from, promod3::loop::BB_C_INDEX));
+  pos_buffer_->SetPos(to, promod3::loop::BB_O_INDEX, 
+                      pos_buffer_->GetPos(from, promod3::loop::BB_O_INDEX));
+  // Even though we officially count CB as a sidechain atom, we still move it
+  // since its completely independent of any sidechain dihedral angle and
+  // cannot be constructed anyway
+  pos_buffer_->SetPos(to, promod3::loop::BB_CB_INDEX, 
+                      pos_buffer_->GetPos(from, promod3::loop::BB_CB_INDEX));
+}
+
 }} // ns
diff --git a/sidechain/src/rotamer_constructor.hh b/sidechain/src/rotamer_constructor.hh
index 4a496ef0e13e68be29730a3be01c04022e18c2ec..759d49d41cbd7cf04b424a2dba72fc02cc0af396 100644
--- a/sidechain/src/rotamer_constructor.hh
+++ b/sidechain/src/rotamer_constructor.hh
@@ -27,18 +27,22 @@
 #include <promod3/sidechain/frame.hh>
 #include <promod3/sidechain/rotamer_lib.hh>
 #include <promod3/sidechain/bb_dep_rotamer_lib.hh>
+#include <promod3/sidechain/rotamer_lookup.hh>
 
 
 namespace promod3 { namespace sidechain {
 
+
 class RotamerConstructor;
 typedef boost::shared_ptr<RotamerConstructor> RotamerConstructorPtr;
 
+
 class RotamerConstructor {
 
 public:
 
-  RotamerConstructor();
+  RotamerConstructor(bool cb_in_sidechain, RotamerLookupMode mode,
+                     const RotamerLookupParam& param = RotamerLookupParam());
 
   virtual ~RotamerConstructor() { }
 
@@ -46,23 +50,39 @@ public:
   RRMRotamerGroupPtr ConstructRRMRotamerGroup(
                   const ost::mol::ResidueHandle& res, RotamerID id,
                   uint residue_index, RotamerLibPtr rot_lib, 
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
 
   RRMRotamerGroupPtr ConstructRRMRotamerGroup(
                   const promod3::loop::AllAtomPositions& all_atom, 
                   uint aa_res_idx, RotamerID id, uint residue_index,
                   RotamerLibPtr rot_lib, 
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
   
   FRMRotamerGroupPtr ConstructFRMRotamerGroup(
                   const ost::mol::ResidueHandle& res, RotamerID id,
-                  uint residue_index, RotamerLibPtr rot_lib, 
+                  uint residue_index, RotamerLibPtr rot_lib,
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false, 
                   Real probability_cutoff = 0.98);
 
   FRMRotamerGroupPtr ConstructFRMRotamerGroup(
                   const promod3::loop::AllAtomPositions& all_atom, 
                   uint aa_res_idx, RotamerID id, uint residue_index,
-                  RotamerLibPtr rot_lib, 
+                  RotamerLibPtr rot_lib,
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854, 
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
 
   // Construct rotamer groups from backbone dependent library
@@ -71,6 +91,8 @@ public:
                   uint residue_index, BBDepRotamerLibPtr rot_lib, 
                   Real phi = -1.0472, 
                   Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
 
   RRMRotamerGroupPtr ConstructRRMRotamerGroup(
@@ -79,6 +101,8 @@ public:
                   BBDepRotamerLibPtr rot_lib, 
                   Real phi = -1.0472, 
                   Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
   
   FRMRotamerGroupPtr ConstructFRMRotamerGroup(
@@ -86,6 +110,8 @@ public:
                   uint residue_index, BBDepRotamerLibPtr rot_lib, 
                   Real phi = -1.0472, 
                   Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
 
   FRMRotamerGroupPtr ConstructFRMRotamerGroup(
@@ -94,6 +120,8 @@ public:
                   BBDepRotamerLibPtr rot_lib, 
                   Real phi = -1.0472, 
                   Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
 
   // Construct rotamer groups directly from rotamerlib entries
@@ -101,75 +129,148 @@ public:
                   const ost::mol::ResidueHandle& res, RotamerID id,
                   uint residue_index, 
                   std::vector<RotamerLibEntry>& lib_entries, 
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
 
   RRMRotamerGroupPtr ConstructRRMRotamerGroup(
                   const promod3::loop::AllAtomPositions& all_atom, 
                   uint aa_res_idx, RotamerID id, uint residue_index,
                   std::vector<RotamerLibEntry>& lib_entries, 
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
   
   FRMRotamerGroupPtr ConstructFRMRotamerGroup(
                   const ost::mol::ResidueHandle& res, RotamerID id,
                   uint residue_index,
                   std::vector<RotamerLibEntry>& lib_entries, 
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
 
   FRMRotamerGroupPtr ConstructFRMRotamerGroup(
                   const promod3::loop::AllAtomPositions& all_atom, 
                   uint aa_res_idx, RotamerID id, uint residue_index,
                   std::vector<RotamerLibEntry>& lib_entries, 
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false,
                   Real probability_cutoff = 0.98);
 
   // Construct frame residues
-  virtual FrameResiduePtr ConstructBackboneFrameResidue(
+  FrameResiduePtr ConstructBackboneFrameResidue(
                   const ost::mol::ResidueHandle& res, RotamerID id, 
-                  uint residue_index, Real phi, bool n_ter = false,
-                  bool c_ter = false) = 0;
+                  uint residue_index, 
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false);
 
-  virtual FrameResiduePtr ConstructBackboneFrameResidue(
+  FrameResiduePtr ConstructBackboneFrameResidue(
                   const promod3::loop::AllAtomPositions& all_atom, 
                   uint aa_res_idx, RotamerID id, uint residue_index,
-                  Real phi = -1.0472, bool n_ter = false,
-                  bool c_ter = false) = 0;
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false);
   
-  virtual FrameResiduePtr ConstructSidechainFrameResidue(
+  FrameResiduePtr ConstructSidechainFrameResidue(
                   const ost::mol::ResidueHandle& res, RotamerID id, 
-                  uint residue_index) = 0;
+                  uint residue_index,
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false);
   
-  virtual FrameResiduePtr ConstructSidechainFrameResidue(
+  FrameResiduePtr ConstructSidechainFrameResidue(
                   const promod3::loop::AllAtomPositions& all_atom, 
-                  uint aa_res_idx, RotamerID id, uint residue_index) = 0;
+                  uint aa_res_idx, RotamerID id, uint residue_index,
+                  Real phi = -1.0472, 
+                  Real psi =  -0.7854,
+                  bool n_ter = false,
+                  bool c_ter = false);
 
   // Assign internal energies to rotamer groups
-  virtual void AssignInternalEnergies(RRMRotamerGroupPtr group);
+  // This implementation just sets the internal energy of every rotamer to 0.0
+  // Implement this function in the child class
+  virtual void AssignInternalEnergies(RRMRotamerGroupPtr group,
+                                      RotamerID id,
+                                      uint residue_index,
+                                      Real phi = -1.0472, 
+                                      Real psi =  -0.7854,
+                                      bool n_ter = false,
+                                      bool c_ter = false);
 
-  virtual void AssignInternalEnergies(FRMRotamerGroupPtr group);
+  virtual void AssignInternalEnergies(FRMRotamerGroupPtr group,
+                                      RotamerID id,
+                                      uint residue_index,
+                                      Real phi = -1.0472, 
+                                      Real psi =  -0.7854,
+                                      bool n_ter = false,
+                                      bool c_ter = false);
 
 protected:
 
-  // Construct the rotamer groups after all backbone position information has 
-  // been set into the internal positin buffer objects
-  virtual RRMRotamerGroupPtr ConstructRRMGroup(
-              RotamerID id, uint residue_index, 
-              std::pair<RotamerLibEntry*,uint> lib_entries, 
-              Real probability_cutoff) = 0;
-
-  virtual FRMRotamerGroupPtr ConstructFRMGroup(
-              RotamerID id, uint residue_index, 
-              std::pair<RotamerLibEntry*,uint> lib_entries, 
-              Real probability_cutoff) = 0;
+  // Function that must be implemented by child class
+  // there are two special cases that have to be treatet separately:
+  // the terminal oxygens.
+  // atom_idx for terminal O is set to -1
+  // atom_idx for terminal OXT is set to -2
+  virtual void ParametrizeParticle(int atom_idx, bool is_hydrogen, 
+                                   Particle& p) = 0;
 
+  // information that is available to the child class in order to parametrize
+  // the given particle
   promod3::loop::AllAtomPositionsPtr pos_buffer_;
+  promod3::loop::HydrogenStoragePtr hydrogen_buffer_;
+  geom::Vec3 terminal_o_pos_;
+  geom::Vec3 terminal_oxt_pos_;
+  RotamerID id_;
+  uint residue_idx_;
+  Real phi_;
+  Real psi_;
+  bool n_ter_;
+  bool c_ter_;
 
 private:
 
+  // Construct the rotamer groups after all backbone position information has 
+  // been set into the internal position buffer objects
+  virtual RRMRotamerGroupPtr ConstructRRMGroup( 
+              std::pair<RotamerLibEntry*,uint> lib_entries,
+              Real probability_cutoff);
+
+  virtual FRMRotamerGroupPtr ConstructFRMGroup(
+              std::pair<RotamerLibEntry*,uint> lib_entries,
+              Real probability_cutoff);
+
+  // assumes positions / probabilities, chi angles and chi deviations 
+  // to be set in buffer
+  RRMRotamerPtr ConstructRRM();
+  FRMRotamerPtr ConstructFRM();
+  FrameResiduePtr ConstructBackboneFrameResidue();
+
   // helpers
-  void SetPosBuffer(const ost::mol::ResidueHandle& res,
-                    RotamerID id);
+  void SetPosBuffer(const ost::mol::ResidueHandle& res);
 
   void SetPosBuffer(const promod3::loop::AllAtomPositions&,
-                    uint aa_res_index, RotamerID id);
+                    uint aa_res_index);
+
+  void MVBBPosBuffer(RotamerID from, RotamerID to);
+
+  RotamerLookup rotamer_lookup_;
+  RotamerLookupMode mode_;
+  Real chi_angles_[4];
+  Real chi_dev_[4];
+  Real probability_;
 };
 
 }} // ns
diff --git a/sidechain/src/rotamer_lookup.cc b/sidechain/src/rotamer_lookup.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6ca63be5dfd0a20ee08bfb680355243911f15140
--- /dev/null
+++ b/sidechain/src/rotamer_lookup.cc
@@ -0,0 +1,2140 @@
+// Copyright (c) 2013-2018, SIB - Swiss Institute of Bioinformatics and 
+//                          Biozentrum - University of Basel
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <promod3/sidechain/rotamer_lookup.hh>
+#include <promod3/core/runtime_profiling.hh>
+
+namespace promod3 { namespace sidechain{
+
+RotamerLookup::RotamerLookup(bool cb_in_sidechain, RotamerLookupMode mode,
+                             const RotamerLookupParam& param): mode_(mode) {
+
+  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
+                                "RotamerLookup::RotamerLookup", 2);
+
+  // ARG
+  sidechain_infos_[ARG].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[ARG].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::ARG];
+  sidechain_infos_[ARG].frm_t = param.frm_t[ost::conop::ARG];
+
+  AddInfo(ARG, "CG", promod3::loop::ARG_CG_INDEX, false);
+  AddInfo(ARG, "CD", promod3::loop::ARG_CD_INDEX, false);
+  AddInfo(ARG, "NE", promod3::loop::ARG_NE_INDEX, false);
+  AddInfo(ARG, "CZ", promod3::loop::ARG_CZ_INDEX, false);
+  AddInfo(ARG, "NH1", promod3::loop::ARG_NH1_INDEX, false);
+  AddInfo(ARG, "NH2", promod3::loop::ARG_NH2_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddInfo(ARG, "HE", promod3::loop::ARG_HE_INDEX, true);
+    AddInfo(ARG, "HH11", promod3::loop::ARG_HH11_INDEX, true);
+    AddInfo(ARG, "HH12", promod3::loop::ARG_HH12_INDEX, true);
+    AddInfo(ARG, "HH21", promod3::loop::ARG_HH21_INDEX, true);
+    AddInfo(ARG, "HH22", promod3::loop::ARG_HH22_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(ARG, "HB2", promod3::loop::ARG_HB2_INDEX, true);
+    AddInfo(ARG, "HB3", promod3::loop::ARG_HB3_INDEX, true);
+    AddInfo(ARG, "HG2", promod3::loop::ARG_HG2_INDEX, true);
+    AddInfo(ARG, "HG3", promod3::loop::ARG_HG3_INDEX, true);
+    AddInfo(ARG, "HD2", promod3::loop::ARG_HD2_INDEX, true);
+    AddInfo(ARG, "HD3", promod3::loop::ARG_HB3_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(ARG, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(ARG, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.ARG_CA_CB_prefactors);
+  AddFRMRotatingParticle(ARG, 0, 0); // CG
+  AddFRMRotatingParticle(ARG, 0, 1); // CD
+  AddFRMRotatingParticle(ARG, 0, 2); // NE
+  AddFRMRotatingParticle(ARG, 0, 3); // CZ
+  AddFRMRotatingParticle(ARG, 0, 4); // NH1
+  AddFRMRotatingParticle(ARG, 0, 5); // NH2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(ARG, 0, 6); // HE
+    AddFRMRotatingParticle(ARG, 0, 7); // HH11
+    AddFRMRotatingParticle(ARG, 0, 8); // HH12
+    AddFRMRotatingParticle(ARG, 0, 9); // HH21
+    AddFRMRotatingParticle(ARG, 0, 10); // HH22
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(ARG, 0, 11); // HB2
+    AddFRMRotatingParticle(ARG, 0, 12); // HB3
+    AddFRMRotatingParticle(ARG, 0, 13); // HG2
+    AddFRMRotatingParticle(ARG, 0, 14); // HG3
+    AddFRMRotatingParticle(ARG, 0, 15);  // HD2
+    AddFRMRotatingParticle(ARG, 0, 16);  // HD3
+  }
+
+  AddFRMRule(ARG, promod3::loop::BB_CB_INDEX, promod3::loop::ARG_CG_INDEX,
+             param.ARG_CB_CG_prefactors);
+  AddFRMFixParticle(ARG, 1, 0); // CG
+  AddFRMRotatingParticle(ARG, 1, 1); // CD
+  AddFRMRotatingParticle(ARG, 1, 2); // NE
+  AddFRMRotatingParticle(ARG, 1, 3); // CZ
+  AddFRMRotatingParticle(ARG, 1, 4); // NH1
+  AddFRMRotatingParticle(ARG, 1, 5); // NH2
+  
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(ARG, 1, 6); // HE
+    AddFRMRotatingParticle(ARG, 1, 7); // HH11
+    AddFRMRotatingParticle(ARG, 1, 8); // HH12
+    AddFRMRotatingParticle(ARG, 1, 9); // HH21
+    AddFRMRotatingParticle(ARG, 1, 10); // HH22
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(ARG, 1, 11); // HB2
+    AddFRMFixParticle(ARG, 1, 12); // HB3
+    AddFRMRotatingParticle(ARG, 1, 13); // HG2
+    AddFRMRotatingParticle(ARG, 1, 14); // HG3
+    AddFRMRotatingParticle(ARG, 1, 15);  // HD2
+    AddFRMRotatingParticle(ARG, 1, 16);  // HD3
+  }
+
+  AddFRMRule(ARG, promod3::loop::ARG_CG_INDEX, promod3::loop::ARG_CD_INDEX,
+             param.ARG_CG_CD_prefactors);
+  AddFRMFixParticle(ARG, 2, 0); // CG
+  AddFRMFixParticle(ARG, 2, 1); // CD
+  AddFRMRotatingParticle(ARG, 2, 2); // NE
+  AddFRMRotatingParticle(ARG, 2, 3); // CZ
+  AddFRMRotatingParticle(ARG, 2, 4); // NH1
+  AddFRMRotatingParticle(ARG, 2, 5); // NH2
+  
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(ARG, 2, 6); // HE
+    AddFRMRotatingParticle(ARG, 2, 7); // HH11
+    AddFRMRotatingParticle(ARG, 2, 8); // HH12
+    AddFRMRotatingParticle(ARG, 2, 9); // HH21
+    AddFRMRotatingParticle(ARG, 2, 10); // HH22
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(ARG, 2, 11); // HB2
+    AddFRMFixParticle(ARG, 2, 12); // HB3
+    AddFRMFixParticle(ARG, 2, 13); // HG2
+    AddFRMFixParticle(ARG, 2, 14); // HG3
+    AddFRMRotatingParticle(ARG, 2, 15);  // HD2
+    AddFRMRotatingParticle(ARG, 2, 16);  // HD3
+  }
+
+
+  AddFRMRule(ARG, promod3::loop::ARG_CD_INDEX, promod3::loop::ARG_NE_INDEX,
+             param.ARG_CD_NE_prefactors);
+  AddFRMFixParticle(ARG, 3, 0); // CG
+  AddFRMFixParticle(ARG, 3, 1); // CD
+  AddFRMFixParticle(ARG, 3, 2); // NE
+  AddFRMRotatingParticle(ARG, 3, 3); // CZ
+  AddFRMRotatingParticle(ARG, 3, 4); // NH1
+  AddFRMRotatingParticle(ARG, 3, 5); // NH2
+  
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(ARG, 3, 6); // HE
+    AddFRMRotatingParticle(ARG, 3, 7); // HH11
+    AddFRMRotatingParticle(ARG, 3, 8); // HH12
+    AddFRMRotatingParticle(ARG, 3, 9); // HH21
+    AddFRMRotatingParticle(ARG, 3, 10); // HH22
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(ARG, 3, 11); // HB2
+    AddFRMFixParticle(ARG, 3, 12); // HB3
+    AddFRMFixParticle(ARG, 3, 13); // HG2
+    AddFRMFixParticle(ARG, 3, 14); // HG3
+    AddFRMFixParticle(ARG, 3, 15);  // HD2
+    AddFRMFixParticle(ARG, 3, 16);  // HD3
+  }
+
+
+  if(cb_in_sidechain) {
+    int cb_idx = 6;
+    if(mode == POLAR_HYDROGEN_MODE) {
+      cb_idx = 11;
+    }
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 17;
+    }
+    AddFRMFixParticle(ARG, 0, cb_idx);
+    AddFRMFixParticle(ARG, 1, cb_idx);
+    AddFRMFixParticle(ARG, 2, cb_idx);
+    AddFRMFixParticle(ARG, 3, cb_idx);
+  }
+
+  backbone_infos_[ARG].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(ARG, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(ARG, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(ARG, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(ARG, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(ARG, "H", promod3::loop::ARG_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(ARG, "HA", promod3::loop::ARG_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(ARG, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // ASN
+  sidechain_infos_[ASN].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[ASN].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::ASN];
+  sidechain_infos_[ASN].frm_t = param.frm_t[ost::conop::ASN];
+
+  AddInfo(ASN, "CG", promod3::loop::ASN_CG_INDEX, false);
+  AddInfo(ASN, "OD1", promod3::loop::ASN_OD1_INDEX, false);
+  AddInfo(ASN, "ND2", promod3::loop::ASN_ND2_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddInfo(ASN, "HD21", promod3::loop::ASN_HD21_INDEX, true);
+    AddInfo(ASN, "HD22", promod3::loop::ASN_HD22_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(ASN, "HB2", promod3::loop::ASN_HB2_INDEX, true);
+    AddInfo(ASN, "HB3", promod3::loop::ASN_HB3_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(ASN, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(ASN, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.ASN_CA_CB_prefactors);
+  AddFRMRotatingParticle(ASN, 0, 0); // CG
+  AddFRMRotatingParticle(ASN, 0, 1); // OD1
+  AddFRMRotatingParticle(ASN, 0, 2); // ND2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(ASN, 0, 3); // HD21
+    AddFRMRotatingParticle(ASN, 0, 4); // HD22    
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(ASN, 0, 5); // HB2
+    AddFRMRotatingParticle(ASN, 0, 6); // HB3       
+  }
+
+  AddFRMRule(ASN, promod3::loop::BB_CB_INDEX, promod3::loop::ASN_CG_INDEX,
+             param.ASN_CB_CG_prefactors);
+  AddFRMFixParticle(ASN, 1, 0); // CG
+  AddFRMRotatingParticle(ASN, 1, 1); // OD1
+  AddFRMRotatingParticle(ASN, 1, 2); // ND2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(ASN, 1, 3); // HD21
+    AddFRMRotatingParticle(ASN, 1, 4); // HD22
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(ASN, 1, 5); // HB2
+    AddFRMFixParticle(ASN, 1, 6); // HB3
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 3;
+    if(mode == POLAR_HYDROGEN_MODE) {
+      cb_idx = 5;
+    }
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 7;
+    }
+    AddFRMFixParticle(ASN, 0, cb_idx);
+    AddFRMFixParticle(ASN, 1, cb_idx);
+  }
+
+
+  backbone_infos_[ASN].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(ASN, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(ASN, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(ASN, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(ASN, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(ASN, "H", promod3::loop::ASN_H_INDEX,true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(ASN, "HA", promod3::loop::ASN_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(ASN, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // ASP
+  sidechain_infos_[ASP].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[ASP].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::ASP];
+  sidechain_infos_[ASP].frm_t = param.frm_t[ost::conop::ASP];
+
+  AddInfo(ASP, "CG", promod3::loop::ASP_CG_INDEX, false);
+  AddInfo(ASP, "OD1", promod3::loop::ASP_OD1_INDEX, false);
+  AddInfo(ASP, "OD2", promod3::loop::ASP_OD2_INDEX, false);
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(ASP, "HB2", promod3::loop::ASP_HB2_INDEX, true);
+    AddInfo(ASP, "HB3", promod3::loop::ASP_HB3_INDEX, true);     
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(ASP, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(ASP, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.ASP_CA_CB_prefactors);
+  AddFRMRotatingParticle(ASP, 0, 0); // CG
+  AddFRMRotatingParticle(ASP, 0, 1); // OD1
+  AddFRMRotatingParticle(ASP, 0, 2); // OD2
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(ASP, 0, 3); // HB2
+    AddFRMRotatingParticle(ASP, 0, 4); // HB3           
+  }
+
+  AddFRMRule(ASP, promod3::loop::BB_CB_INDEX, promod3::loop::ASP_CG_INDEX,
+             param.ASP_CB_CG_prefactors);
+  AddFRMFixParticle(ASP, 1, 0); // CG
+  AddFRMRotatingParticle(ASP, 1, 1); // OD1
+  AddFRMRotatingParticle(ASP, 1, 2); // OD2
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(ASP, 1, 3); // HB2
+    AddFRMFixParticle(ASP, 1, 4); // HB3                 
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 3;
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 5;
+    }
+    AddFRMFixParticle(ASP, 0, cb_idx);
+    AddFRMFixParticle(ASP, 1, cb_idx);
+  }
+
+  backbone_infos_[ASP].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(ASP, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(ASP, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(ASP, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(ASP, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(ASP, "H", promod3::loop::ASP_H_INDEX,true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(ASP, "HA", promod3::loop::ASP_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(ASP, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // GLN
+  sidechain_infos_[GLN].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[GLN].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::GLN];
+  sidechain_infos_[GLN].frm_t = param.frm_t[ost::conop::GLN];
+
+  AddInfo(GLN, "CG", promod3::loop::GLN_CG_INDEX, false);
+  AddInfo(GLN, "CD", promod3::loop::GLN_CD_INDEX, false);
+  AddInfo(GLN, "OE1", promod3::loop::GLN_OE1_INDEX, false);
+  AddInfo(GLN, "NE2", promod3::loop::GLN_NE2_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddInfo(GLN, "HE21", promod3::loop::GLN_HE21_INDEX, true);
+    AddInfo(GLN, "HE22", promod3::loop::GLN_HE22_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(GLN, "HB2", promod3::loop::GLN_HB2_INDEX, true);
+    AddInfo(GLN, "HB3", promod3::loop::GLN_HB3_INDEX, true);
+    AddInfo(GLN, "HG2", promod3::loop::GLN_HG2_INDEX, true);
+    AddInfo(GLN, "HG3", promod3::loop::GLN_HG3_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(GLN, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(GLN, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.GLN_CA_CB_prefactors);
+  AddFRMRotatingParticle(GLN, 0, 0); // CG
+  AddFRMRotatingParticle(GLN, 0, 1); // CD
+  AddFRMRotatingParticle(GLN, 0, 2); // OE1
+  AddFRMRotatingParticle(GLN, 0, 3); // NE2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(GLN, 0, 4); // HE21
+    AddFRMRotatingParticle(GLN, 0, 5); // HE22
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(GLN, 0, 6); // HB2
+    AddFRMRotatingParticle(GLN, 0, 7); // HB3
+    AddFRMRotatingParticle(GLN, 0, 8); // HG2
+    AddFRMRotatingParticle(GLN, 0, 9); // HG3
+  }
+
+  AddFRMRule(GLN, promod3::loop::BB_CB_INDEX, promod3::loop::GLN_CG_INDEX,
+             param.GLN_CB_CG_prefactors);
+  AddFRMFixParticle(GLN, 1, 0); // CG
+  AddFRMRotatingParticle(GLN, 1, 1); // CD
+  AddFRMRotatingParticle(GLN, 1, 2); // OE1
+  AddFRMRotatingParticle(GLN, 1, 3); // NE2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(GLN, 1, 4); // HE21
+    AddFRMRotatingParticle(GLN, 1, 5); // HE22
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(GLN, 1, 6); // HB2
+    AddFRMFixParticle(GLN, 1, 7); // HB3
+    AddFRMRotatingParticle(GLN, 1, 8); // HG2
+    AddFRMRotatingParticle(GLN, 1, 9); // HG3
+  }
+
+  AddFRMRule(GLN, promod3::loop::GLN_CG_INDEX, promod3::loop::GLN_CD_INDEX,
+             param.GLN_CG_CD_prefactors);
+  AddFRMFixParticle(GLN, 2, 0); // CG
+  AddFRMFixParticle(GLN, 2, 1); // CD
+  AddFRMRotatingParticle(GLN, 2, 2); // OE1
+  AddFRMRotatingParticle(GLN, 2, 3); // NE2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(GLN, 2, 4); // HE21
+    AddFRMRotatingParticle(GLN, 2, 5); // HE22
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(GLN, 2, 6); // HB2
+    AddFRMFixParticle(GLN, 2, 7); // HB3
+    AddFRMFixParticle(GLN, 2, 8); // HG2
+    AddFRMFixParticle(GLN, 2, 9); // HG3      
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 4;
+    if(mode == POLAR_HYDROGEN_MODE) {
+      cb_idx = 6;
+    }
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 10;
+    }
+    AddFRMFixParticle(GLN, 0, cb_idx);
+    AddFRMFixParticle(GLN, 1, cb_idx);
+    AddFRMFixParticle(GLN, 2, cb_idx);
+  }
+
+
+  backbone_infos_[GLN].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+
+  AddBBInfo(GLN, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(GLN, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(GLN, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(GLN, "O", promod3::loop::BB_O_INDEX, false);
+
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(GLN, "H", promod3::loop::GLN_H_INDEX,true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(GLN, "HA", promod3::loop::GLN_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(GLN, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // GLU
+  sidechain_infos_[GLU].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[GLU].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::GLU];
+  sidechain_infos_[GLU].frm_t = param.frm_t[ost::conop::GLU];
+
+  AddInfo(GLU, "CG", promod3::loop::GLU_CG_INDEX, false);
+  AddInfo(GLU, "CD", promod3::loop::GLU_CD_INDEX, false);
+  AddInfo(GLU, "OE1", promod3::loop::GLU_OE1_INDEX, false);
+  AddInfo(GLU, "OE2", promod3::loop::GLU_OE2_INDEX, false);
+
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(GLU, "HB2", promod3::loop::GLU_HB2_INDEX, true);
+    AddInfo(GLU, "HB3", promod3::loop::GLU_HB3_INDEX, true);
+    AddInfo(GLU, "HG2", promod3::loop::GLU_HG2_INDEX, true);
+    AddInfo(GLU, "HG3", promod3::loop::GLU_HG3_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(GLU, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(GLU, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.GLU_CA_CB_prefactors);
+  AddFRMRotatingParticle(GLU, 0, 0); // CG
+  AddFRMRotatingParticle(GLU, 0, 1); // CD
+  AddFRMRotatingParticle(GLU, 0, 2); // OE1
+  AddFRMRotatingParticle(GLU, 0, 3); // OE2
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(GLU, 0, 4); // HB2
+    AddFRMRotatingParticle(GLU, 0, 5); // HB3
+    AddFRMRotatingParticle(GLU, 0, 6); // HG2
+    AddFRMRotatingParticle(GLU, 0, 7); // HG3
+  }
+
+  AddFRMRule(GLU, promod3::loop::BB_CB_INDEX, promod3::loop::GLU_CG_INDEX,
+             param.GLU_CB_CG_prefactors);
+  AddFRMFixParticle(GLU, 1, 0); // CG
+  AddFRMRotatingParticle(GLU, 1, 1); // CD
+  AddFRMRotatingParticle(GLU, 1, 2); // OE1
+  AddFRMRotatingParticle(GLU, 1, 3); // OE2
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(GLU, 1, 4); // HB2
+    AddFRMFixParticle(GLU, 1, 5); // HB3
+    AddFRMRotatingParticle(GLU, 1, 6); // HG2
+    AddFRMRotatingParticle(GLU, 1, 7); // HG3
+  }
+
+  AddFRMRule(GLU, promod3::loop::GLU_CG_INDEX, promod3::loop::GLU_CD_INDEX,
+             param.GLU_CG_CD_prefactors);
+  AddFRMFixParticle(GLU, 2, 0); // CG
+  AddFRMFixParticle(GLU, 2, 1); // CD
+  AddFRMRotatingParticle(GLU, 2, 2); // OE1
+  AddFRMRotatingParticle(GLU, 2, 3); // OE2
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(GLU, 2, 4); // HB2
+    AddFRMFixParticle(GLU, 2, 5); // HB3
+    AddFRMFixParticle(GLU, 2, 6); // HG2
+    AddFRMFixParticle(GLU, 2, 7); // HG3      
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 4;
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 8;
+    }
+    AddFRMFixParticle(GLU, 0, cb_idx);
+    AddFRMFixParticle(GLU, 1, cb_idx);
+    AddFRMFixParticle(GLU, 2, cb_idx);
+  }
+
+
+  backbone_infos_[GLU].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+
+  AddBBInfo(GLU, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(GLU, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(GLU, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(GLU, "O", promod3::loop::BB_O_INDEX, false);
+
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(GLU, "H", promod3::loop::GLU_H_INDEX,true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(GLU, "HA", promod3::loop::GLU_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(GLU, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // LYS
+  sidechain_infos_[LYS].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[LYS].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::LYS];
+  sidechain_infos_[LYS].frm_t = param.frm_t[ost::conop::LYS];
+
+  AddInfo(LYS, "CG", promod3::loop::LYS_CG_INDEX,false);
+  AddInfo(LYS, "CD", promod3::loop::LYS_CD_INDEX,false);
+  AddInfo(LYS, "CE", promod3::loop::LYS_CE_INDEX,false);
+  AddInfo(LYS, "NZ", promod3::loop::LYS_NZ_INDEX,false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddInfo(LYS, "HZ1", promod3::loop::LYS_HZ1_INDEX,true);
+    AddInfo(LYS, "HZ2", promod3::loop::LYS_HZ2_INDEX,true);
+    AddInfo(LYS, "HZ3", promod3::loop::LYS_HZ3_INDEX,true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(LYS, "HB2", promod3::loop::LYS_HB2_INDEX, true);
+    AddInfo(LYS, "HB3", promod3::loop::LYS_HB3_INDEX, true);
+    AddInfo(LYS, "HG2", promod3::loop::LYS_HG2_INDEX, true);
+    AddInfo(LYS, "HG3", promod3::loop::LYS_HG3_INDEX, true);
+    AddInfo(LYS, "HD2", promod3::loop::LYS_HD2_INDEX, true);
+    AddInfo(LYS, "HD3", promod3::loop::LYS_HD3_INDEX, true);
+    AddInfo(LYS, "HE2", promod3::loop::LYS_HE2_INDEX, true);
+    AddInfo(LYS, "HE3", promod3::loop::LYS_HE3_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(LYS, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(LYS, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.LYS_CA_CB_prefactors);
+  AddFRMRotatingParticle(LYS, 0, 0); // CG
+  AddFRMRotatingParticle(LYS, 0, 1); // CD
+  AddFRMRotatingParticle(LYS, 0, 2); // CE
+  AddFRMRotatingParticle(LYS, 0, 3); // NZ
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(LYS, 0, 4); // HZ1
+    AddFRMRotatingParticle(LYS, 0, 5); // HZ2
+    AddFRMRotatingParticle(LYS, 0, 6); // HZ3
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(LYS, 0, 7); // HB2
+    AddFRMRotatingParticle(LYS, 0, 8); // HB3
+    AddFRMRotatingParticle(LYS, 0, 9); // HG2
+    AddFRMRotatingParticle(LYS, 0, 10); // HG3
+    AddFRMRotatingParticle(LYS, 0, 11); // HD2
+    AddFRMRotatingParticle(LYS, 0, 12); // HD3
+    AddFRMRotatingParticle(LYS, 0, 13); // HE2
+    AddFRMRotatingParticle(LYS, 0, 14); // HE3
+  }
+
+  AddFRMRule(LYS, promod3::loop::BB_CB_INDEX, promod3::loop::LYS_CG_INDEX,
+             param.LYS_CB_CG_prefactors);
+  AddFRMFixParticle(LYS, 1, 0); // CG
+  AddFRMRotatingParticle(LYS, 1, 1); // CD
+  AddFRMRotatingParticle(LYS, 1, 2); // CE
+  AddFRMRotatingParticle(LYS, 1, 3); // NZ
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(LYS, 1, 4); // HZ1
+    AddFRMRotatingParticle(LYS, 1, 5); // HZ2
+    AddFRMRotatingParticle(LYS, 1, 6); // HZ3
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(LYS, 1, 7); // HB2
+    AddFRMFixParticle(LYS, 1, 8); // HB3
+    AddFRMRotatingParticle(LYS, 1, 9); // HG2
+    AddFRMRotatingParticle(LYS, 1, 10); // HG3
+    AddFRMRotatingParticle(LYS, 1, 11); // HD2
+    AddFRMRotatingParticle(LYS, 1, 12); // HD3
+    AddFRMRotatingParticle(LYS, 1, 13); // HE2
+    AddFRMRotatingParticle(LYS, 1, 14); // HE3      
+  }
+
+  AddFRMRule(LYS, promod3::loop::LYS_CG_INDEX, promod3::loop::LYS_CD_INDEX,
+             param.LYS_CG_CD_prefactors);
+  AddFRMFixParticle(LYS, 2, 0); // CG
+  AddFRMFixParticle(LYS, 2, 1); // CD
+  AddFRMRotatingParticle(LYS, 2, 2); // CE
+  AddFRMRotatingParticle(LYS, 2, 3); // NZ
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(LYS, 2, 4); // HZ1
+    AddFRMRotatingParticle(LYS, 2, 5); // HZ2
+    AddFRMRotatingParticle(LYS, 2, 6); // HZ3
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(LYS, 2, 7); // HB2
+    AddFRMFixParticle(LYS, 2, 8); // HB3
+    AddFRMFixParticle(LYS, 2, 9); // HG2
+    AddFRMFixParticle(LYS, 2, 10); // HG3
+    AddFRMRotatingParticle(LYS, 2, 11); // HD2
+    AddFRMRotatingParticle(LYS, 2, 12); // HD3
+    AddFRMRotatingParticle(LYS, 2, 13); // HE2
+    AddFRMRotatingParticle(LYS, 2, 14); // HE3          
+  }
+
+  AddFRMRule(LYS, promod3::loop::LYS_CD_INDEX, promod3::loop::LYS_CE_INDEX,
+             param.LYS_CD_CE_prefactors);
+  AddFRMFixParticle(LYS, 3, 0); // CG
+  AddFRMFixParticle(LYS, 3, 1); // CD
+  AddFRMFixParticle(LYS, 3, 2); // CE
+  AddFRMRotatingParticle(LYS, 3, 3); // NZ
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(LYS, 3, 4); // HZ1
+    AddFRMRotatingParticle(LYS, 3, 5); // HZ2
+    AddFRMRotatingParticle(LYS, 3, 6); // HZ3
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(LYS, 3, 7); // HB2
+    AddFRMFixParticle(LYS, 3, 8); // HB3
+    AddFRMFixParticle(LYS, 3, 9); // HG2
+    AddFRMFixParticle(LYS, 3, 10); // HG3
+    AddFRMFixParticle(LYS, 3, 11); // HD2
+    AddFRMFixParticle(LYS, 3, 12); // HD3
+    AddFRMRotatingParticle(LYS, 3, 13); // HE2
+    AddFRMRotatingParticle(LYS, 3, 14); // HE3                
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 4;
+    if(mode == POLAR_HYDROGEN_MODE) {
+      cb_idx = 7;
+    }
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 15;
+    }
+    AddFRMFixParticle(LYS, 0, cb_idx);
+    AddFRMFixParticle(LYS, 1, cb_idx);
+    AddFRMFixParticle(LYS, 2, cb_idx);
+    AddFRMFixParticle(LYS, 3, cb_idx);
+  }
+
+  backbone_infos_[LYS].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(LYS, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(LYS, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(LYS, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(LYS, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(LYS, "H", promod3::loop::LYS_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(LYS, "HA", promod3::loop::LYS_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(LYS, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // SER
+  sidechain_infos_[SER].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[SER].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::SER];
+  sidechain_infos_[SER].frm_t = param.frm_t[ost::conop::SER];
+
+  AddInfo(SER, "OG", promod3::loop::SER_OG_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddInfo(SER, "HG", promod3::loop::SER_HG_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(SER, "HB2", promod3::loop::SER_HB2_INDEX, true);
+    AddInfo(SER, "HB3", promod3::loop::SER_HB3_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(SER, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddCustomHydrogenInfo(SER, promod3::loop::SER_HG_INDEX, 
+                          promod3::loop::BB_CA_INDEX, 
+                          promod3::loop::BB_CB_INDEX, 
+                          promod3::loop::SER_OG_INDEX,
+                          0.96, 1.85, 1);
+  }
+
+  AddFRMRule(SER, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.SER_CA_CB_prefactors);
+  AddFRMRotatingParticle(SER, 0, 0); // OG
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(SER, 0, 1); // HG
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(SER, 0, 2); // HB2
+    AddFRMRotatingParticle(SER, 0, 3); // HB3
+  }
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRule(SER, promod3::loop::BB_CB_INDEX, promod3::loop::SER_OG_INDEX,
+               param.SER_CB_OG_prefactors);
+    AddFRMFixParticle(SER, 1, 0); // OG
+    AddFRMRotatingParticle(SER, 1, 1); // HG
+    
+    if(mode == FULL_ATOMIC_MODE) {
+      AddFRMFixParticle(SER, 1, 2); // HB2
+      AddFRMFixParticle(SER, 1, 3); // HB3    
+    }
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 1;
+    if(mode == POLAR_HYDROGEN_MODE) {
+      cb_idx = 2;
+    }
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 4;
+    }
+    AddFRMFixParticle(SER, 0, cb_idx);
+    if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+      AddFRMFixParticle(SER, 1, cb_idx);
+    }
+  }
+
+  backbone_infos_[SER].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(SER, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(SER, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(SER, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(SER, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(SER, "H", promod3::loop::SER_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(SER, "HA", promod3::loop::SER_HA_INDEX, true);    
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(SER, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // CYS
+  sidechain_infos_[CYS].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[CYS].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::CYS];
+  sidechain_infos_[CYS].frm_t = param.frm_t[ost::conop::CYS];
+
+  AddInfo(CYS, "SG", promod3::loop::CYS_SG_INDEX, false);
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(CYS, "HB2", promod3::loop::CYS_HB2_INDEX, true);
+    AddInfo(CYS, "HB3", promod3::loop::CYS_HB3_INDEX, true);
+    AddInfo(CYS, "HG", promod3::loop::CYS_HG_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(CYS, "CB", promod3::loop::BB_CB_INDEX, false);  
+  }
+
+  AddFRMRule(CYS, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.CYS_CA_CB_prefactors);
+  AddFRMRotatingParticle(CYS, 0, 0); // SG
+
+  if(FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(CYS, 0, 1); // HB2
+    AddFRMRotatingParticle(CYS, 0, 2); // HB3
+    AddFRMRotatingParticle(CYS, 0, 3); // HG
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 1;
+    if(FULL_ATOMIC_MODE) {
+      cb_idx = 4;
+    }
+    AddFRMFixParticle(CYS, 0, cb_idx);
+  }
+
+  backbone_infos_[CYS].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(CYS, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(CYS, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(CYS, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(CYS, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(CYS, "H", promod3::loop::CYS_H_INDEX,true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(CYS, "HA", promod3::loop::CYS_HA_INDEX,true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(CYS, "CB", promod3::loop::BB_CB_INDEX, false);   
+  }
+
+
+  // CYH
+  sidechain_infos_[CYH] = sidechain_infos_[CYS];
+  frm_rules_[CYH] = frm_rules_[CYS];
+  backbone_infos_[CYH] = backbone_infos_[CYS];
+
+
+  // CYD
+  sidechain_infos_[CYD].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[CYD].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::CYS];
+  sidechain_infos_[CYD].frm_t = param.frm_t[ost::conop::CYS];
+
+  AddInfo(CYD, "SG", promod3::loop::CYS_SG_INDEX, false);
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(CYD, "HB2", promod3::loop::CYS_HB2_INDEX, true);
+    AddInfo(CYD, "HB3", promod3::loop::CYS_HB3_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(CYD, "CB", promod3::loop::BB_CB_INDEX, false);  
+  }
+
+  AddFRMRule(CYD, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.CYS_CA_CB_prefactors);
+  AddFRMRotatingParticle(CYD, 0, 0); // SG
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(CYD, 0, 1); // HB2
+    AddFRMRotatingParticle(CYD, 0, 2); // HB3
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 1;
+    if(FULL_ATOMIC_MODE) {
+      cb_idx = 3;
+    }
+    AddFRMFixParticle(CYD, 0, cb_idx);
+  }
+
+  backbone_infos_[CYD].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(CYD, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(CYD, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(CYD, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(CYD, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(CYD, "H", promod3::loop::CYS_H_INDEX,true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(CYD, "HA", promod3::loop::CYS_HA_INDEX,true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(CYD, "CB", promod3::loop::BB_CB_INDEX, false);   
+  }
+
+
+  // MET
+  sidechain_infos_[MET].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[MET].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::MET];
+  sidechain_infos_[MET].frm_t = param.frm_t[ost::conop::MET];
+
+  AddInfo(MET, "CG", promod3::loop::MET_CG_INDEX,false);
+  AddInfo(MET, "SD", promod3::loop::MET_SD_INDEX,false);
+  AddInfo(MET, "CE", promod3::loop::MET_CE_INDEX,false);
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(MET, "HB2", promod3::loop::MET_HB2_INDEX, true);
+    AddInfo(MET, "HB3", promod3::loop::MET_HB3_INDEX, true);
+    AddInfo(MET, "HG2", promod3::loop::MET_HG2_INDEX, true);
+    AddInfo(MET, "HG3", promod3::loop::MET_HG3_INDEX, true);
+    AddInfo(MET, "HE1", promod3::loop::MET_HE1_INDEX, true);
+    AddInfo(MET, "HE2", promod3::loop::MET_HE2_INDEX, true);
+    AddInfo(MET, "HE3", promod3::loop::MET_HE3_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(MET, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(MET, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.MET_CA_CB_prefactors);
+  AddFRMRotatingParticle(MET, 0, 0); // CG
+  AddFRMRotatingParticle(MET, 0, 1); // SD
+  AddFRMRotatingParticle(MET, 0, 2); // CE
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(MET, 0, 3); // HB2
+    AddFRMRotatingParticle(MET, 0, 4); // HB3
+    AddFRMRotatingParticle(MET, 0, 5); // HG2
+    AddFRMRotatingParticle(MET, 0, 6); // HG3
+    AddFRMRotatingParticle(MET, 0, 7); // HE1
+    AddFRMRotatingParticle(MET, 0, 8); // HE2
+    AddFRMRotatingParticle(MET, 0, 9); // HE3
+  }
+
+  AddFRMRule(MET, promod3::loop::BB_CB_INDEX, promod3::loop::MET_CG_INDEX,
+             param.MET_CB_CG_prefactors);
+  AddFRMFixParticle(MET, 1, 0); // CG
+  AddFRMRotatingParticle(MET, 1, 1); // SD
+  AddFRMRotatingParticle(MET, 1, 2); // CE
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(MET, 1, 3); // HB2
+    AddFRMFixParticle(MET, 1, 4); // HB3
+    AddFRMRotatingParticle(MET, 1, 5); // HG2
+    AddFRMRotatingParticle(MET, 1, 6); // HG3
+    AddFRMRotatingParticle(MET, 1, 7); // HE1
+    AddFRMRotatingParticle(MET, 1, 8); // HE2
+    AddFRMRotatingParticle(MET, 1, 9); // HE3      
+  }
+
+  AddFRMRule(MET, promod3::loop::MET_CG_INDEX, promod3::loop::MET_SD_INDEX,
+             param.MET_CG_SD_prefactors);
+  AddFRMFixParticle(MET, 2, 0);
+  AddFRMFixParticle(MET, 2, 1);
+  AddFRMRotatingParticle(MET, 2, 2);
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(MET, 2, 3); // HB2
+    AddFRMFixParticle(MET, 2, 4); // HB3
+    AddFRMFixParticle(MET, 2, 5); // HG2
+    AddFRMFixParticle(MET, 2, 6); // HG3
+    AddFRMRotatingParticle(MET, 2, 7); // HE1
+    AddFRMRotatingParticle(MET, 2, 8); // HE2
+    AddFRMRotatingParticle(MET, 2, 9); // HE3            
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 3;
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 10;
+    }
+    AddFRMFixParticle(MET, 0, cb_idx);
+    AddFRMFixParticle(MET, 1, cb_idx);
+    AddFRMFixParticle(MET, 2, cb_idx);
+  }
+
+  backbone_infos_[MET].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(MET, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(MET, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(MET, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(MET, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(MET, "H", promod3::loop::MET_H_INDEX, true);      
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(MET, "H", promod3::loop::MET_H_INDEX, true);      
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(MET, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // TRP
+  sidechain_infos_[TRP].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[TRP].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::TRP];
+  sidechain_infos_[TRP].frm_t = param.frm_t[ost::conop::TRP];
+
+  AddInfo(TRP, "CG", promod3::loop::TRP_CG_INDEX,false);
+  AddInfo(TRP, "CD1", promod3::loop::TRP_CD1_INDEX,false);
+  AddInfo(TRP, "CD2", promod3::loop::TRP_CD2_INDEX,false);
+  AddInfo(TRP, "CE2", promod3::loop::TRP_CE2_INDEX,false);
+  AddInfo(TRP, "NE1", promod3::loop::TRP_NE1_INDEX,false);
+  AddInfo(TRP, "CE3", promod3::loop::TRP_CE3_INDEX,false);
+  AddInfo(TRP, "CZ3", promod3::loop::TRP_CZ3_INDEX,false);
+  AddInfo(TRP, "CH2", promod3::loop::TRP_CH2_INDEX,false);
+  AddInfo(TRP, "CZ2", promod3::loop::TRP_CZ2_INDEX,false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddInfo(TRP, "HE1", promod3::loop::TRP_HE1_INDEX,true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(TRP, "HB2", promod3::loop::TRP_HB2_INDEX, true);
+    AddInfo(TRP, "HB3", promod3::loop::TRP_HB3_INDEX, true);
+    AddInfo(TRP, "HD1", promod3::loop::TRP_HD1_INDEX, true);
+    AddInfo(TRP, "HE3", promod3::loop::TRP_HE3_INDEX, true);
+    AddInfo(TRP, "HZ2", promod3::loop::TRP_HZ2_INDEX, true);
+    AddInfo(TRP, "HZ3", promod3::loop::TRP_HZ3_INDEX, true);
+    AddInfo(TRP, "HH2", promod3::loop::TRP_HH2_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(TRP, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(TRP, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.TRP_CA_CB_prefactors);
+  AddFRMRotatingParticle(TRP, 0, 0); // CG
+  AddFRMRotatingParticle(TRP, 0, 1); // CD1
+  AddFRMRotatingParticle(TRP, 0, 2); // CD2
+  AddFRMRotatingParticle(TRP, 0, 3); // CE2
+  AddFRMRotatingParticle(TRP, 0, 4); // NE1
+  AddFRMRotatingParticle(TRP, 0, 5); // CE3
+  AddFRMRotatingParticle(TRP, 0, 6); // CZ3
+  AddFRMRotatingParticle(TRP, 0, 7); // CH2
+  AddFRMRotatingParticle(TRP, 0, 8); // CZ2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(TRP, 0, 9);  // HE1    
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(TRP, 0, 10); // HB2
+    AddFRMRotatingParticle(TRP, 0, 11); // HB3
+    AddFRMRotatingParticle(TRP, 0, 12); // HD1
+    AddFRMRotatingParticle(TRP, 0, 13); // HE3
+    AddFRMRotatingParticle(TRP, 0, 14); // HZ2
+    AddFRMRotatingParticle(TRP, 0, 15); // HZ3
+    AddFRMRotatingParticle(TRP, 0, 16); // HH2
+  }
+
+  AddFRMRule(TRP, promod3::loop::BB_CB_INDEX, promod3::loop::TRP_CG_INDEX,
+             param.TRP_CB_CG_prefactors);
+  AddFRMFixParticle(TRP, 1, 0); // CG
+  AddFRMRotatingParticle(TRP, 1, 1); // CD1
+  AddFRMRotatingParticle(TRP, 1, 2); // CD2
+  AddFRMRotatingParticle(TRP, 1, 3); // CE2
+  AddFRMRotatingParticle(TRP, 1, 4); // NE1
+  AddFRMRotatingParticle(TRP, 1, 5); // CE3
+  AddFRMRotatingParticle(TRP, 1, 6); // CZ3
+  AddFRMRotatingParticle(TRP, 1, 7); // CH2
+  AddFRMRotatingParticle(TRP, 1, 8); // CZ2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(TRP, 1, 9);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(TRP, 1, 10); // HB2
+    AddFRMFixParticle(TRP, 1, 11); // HB3
+    AddFRMRotatingParticle(TRP, 1, 12); // HD1
+    AddFRMRotatingParticle(TRP, 1, 13); // HE3
+    AddFRMRotatingParticle(TRP, 1, 14); // HZ2
+    AddFRMRotatingParticle(TRP, 1, 15); // HZ3
+    AddFRMRotatingParticle(TRP, 1, 16); // HH2      
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 9;
+    if(mode == POLAR_HYDROGEN_MODE) {
+      cb_idx = 10;
+    }
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 17;
+    }
+    AddFRMFixParticle(TRP, 0, cb_idx);
+    AddFRMFixParticle(TRP, 1, cb_idx);
+  }
+
+  backbone_infos_[TRP].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(TRP, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(TRP, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(TRP, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(TRP, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(TRP, "H", promod3::loop::TRP_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(TRP, "HA", promod3::loop::TRP_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(TRP, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // TYR
+  sidechain_infos_[TYR].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[TYR].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::TYR];
+  sidechain_infos_[TYR].frm_t = param.frm_t[ost::conop::TYR];
+
+  AddInfo(TYR, "CG", promod3::loop::TYR_CG_INDEX, false);
+  AddInfo(TYR, "CD1", promod3::loop::TYR_CD1_INDEX, false);
+  AddInfo(TYR, "CD2", promod3::loop::TYR_CD2_INDEX, false);
+  AddInfo(TYR, "CE1", promod3::loop::TYR_CE1_INDEX, false);
+  AddInfo(TYR, "CE2", promod3::loop::TYR_CE2_INDEX, false);
+  AddInfo(TYR, "CZ", promod3::loop::TYR_CZ_INDEX, false);
+  AddInfo(TYR, "OH", promod3::loop::TYR_OH_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddInfo(TYR, "HH", promod3::loop::TYR_HH_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(TYR, "HB2", promod3::loop::TYR_HB2_INDEX, true);
+    AddInfo(TYR, "HB3", promod3::loop::TYR_HB3_INDEX, true);
+    AddInfo(TYR, "HD1", promod3::loop::TYR_HD1_INDEX, true);
+    AddInfo(TYR, "HD2", promod3::loop::TYR_HD2_INDEX, true);
+    AddInfo(TYR, "HE1", promod3::loop::TYR_HE1_INDEX, true);
+    AddInfo(TYR, "HE2", promod3::loop::TYR_HE2_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(TYR, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+  
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddCustomHydrogenInfo(TYR, promod3::loop::TYR_HH_INDEX, 
+                          promod3::loop::TYR_CE1_INDEX, 
+                          promod3::loop::TYR_CZ_INDEX, 
+                          promod3::loop::TYR_OH_INDEX,
+                          0.96, 1.885, 2);
+  }
+
+  AddFRMRule(TYR, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.TYR_CA_CB_prefactors);
+  AddFRMRotatingParticle(TYR, 0, 0); // CG
+  AddFRMRotatingParticle(TYR, 0, 1); // CD1
+  AddFRMRotatingParticle(TYR, 0, 2); // CD2
+  AddFRMRotatingParticle(TYR, 0, 3); // CE1
+  AddFRMRotatingParticle(TYR, 0, 4); // CE2
+  AddFRMRotatingParticle(TYR, 0, 5); // CZ
+  AddFRMRotatingParticle(TYR, 0, 6); // OH
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(TYR, 0, 7); // HH    
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(TYR, 0, 8); // HB2
+    AddFRMRotatingParticle(TYR, 0, 9); // HB3
+    AddFRMRotatingParticle(TYR, 0, 10); // HD1
+    AddFRMRotatingParticle(TYR, 0, 11); // HD2
+    AddFRMRotatingParticle(TYR, 0, 12); // HE1
+    AddFRMRotatingParticle(TYR, 0, 13); // HE2
+  }
+
+  AddFRMRule(TYR, promod3::loop::BB_CB_INDEX, promod3::loop::TYR_CG_INDEX,
+             param.TYR_CB_CG_prefactors);
+  AddFRMFixParticle(TYR, 1, 0); // CG
+  AddFRMRotatingParticle(TYR, 1, 1); // CD1
+  AddFRMRotatingParticle(TYR, 1, 2); // CD2
+  AddFRMRotatingParticle(TYR, 1, 3); // CE1
+  AddFRMRotatingParticle(TYR, 1, 4); // CE2
+  AddFRMRotatingParticle(TYR, 1, 5); // CZ
+  AddFRMRotatingParticle(TYR, 1, 6); // OH
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(TYR, 1, 7); // HH
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(TYR, 1, 8); // HB2
+    AddFRMFixParticle(TYR, 1, 9); // HB3
+    AddFRMRotatingParticle(TYR, 1, 10); // HD1
+    AddFRMRotatingParticle(TYR, 1, 11); // HD2
+    AddFRMRotatingParticle(TYR, 1, 12); // HE1
+    AddFRMRotatingParticle(TYR, 1, 13); // HE2
+
+  }
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRule(TYR, promod3::loop::TYR_CZ_INDEX, promod3::loop::TYR_OH_INDEX,
+               param.TYR_CZ_OH_prefactors);
+    AddFRMFixParticle(TYR, 2, 0); // CG
+    AddFRMFixParticle(TYR, 2, 1); // CD1
+    AddFRMFixParticle(TYR, 2, 2); // CD2
+    AddFRMFixParticle(TYR, 2, 3); // CE1
+    AddFRMFixParticle(TYR, 2, 4); // CE2
+    AddFRMFixParticle(TYR, 2, 5); // CZ
+    AddFRMFixParticle(TYR, 2, 6); // OH
+
+    AddFRMRotatingParticle(TYR, 2, 7);
+
+    if(mode == FULL_ATOMIC_MODE) {
+      AddFRMFixParticle(TYR, 2, 8); // HB2
+      AddFRMFixParticle(TYR, 2, 9); // HB3
+      AddFRMFixParticle(TYR, 2, 10); // HD1
+      AddFRMFixParticle(TYR, 2, 11); // HD2
+      AddFRMFixParticle(TYR, 2, 12); // HE1
+      AddFRMFixParticle(TYR, 2, 13); // HE2      
+    }
+  }
+
+
+  if(cb_in_sidechain) {
+    int cb_idx = 7;
+    if(mode == POLAR_HYDROGEN_MODE) {
+      cb_idx = 8;
+    }
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 14;
+    }
+    AddFRMFixParticle(TYR, 0, cb_idx);
+    AddFRMFixParticle(TYR, 1, cb_idx);
+    if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+      AddFRMFixParticle(TYR, 2, cb_idx);
+    }
+  }
+
+  backbone_infos_[TYR].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(TYR, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(TYR, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(TYR, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(TYR, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(TYR, "H", promod3::loop::TYR_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(TYR, "HA", promod3::loop::TYR_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(TYR, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // THR
+  sidechain_infos_[THR].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[THR].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::THR];
+  sidechain_infos_[THR].frm_t = param.frm_t[ost::conop::THR];
+
+  AddInfo(THR, "OG1", promod3::loop::THR_OG1_INDEX, false);
+  AddInfo(THR, "CG2", promod3::loop::THR_CG2_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddInfo(THR, "HG1", promod3::loop::THR_HG1_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(THR, "HB", promod3::loop::THR_HB_INDEX, true);
+    AddInfo(THR, "HG21", promod3::loop::THR_HG22_INDEX, true);
+    AddInfo(THR, "HG22", promod3::loop::THR_HG23_INDEX, true);
+    AddInfo(THR, "HG23", promod3::loop::THR_HG23_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(THR, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddCustomHydrogenInfo(THR, promod3::loop::THR_HG1_INDEX, 
+                          promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX, 
+                          promod3::loop::THR_OG1_INDEX,
+                          0.96, 1.85, 1);
+  }
+
+  AddFRMRule(THR, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.THR_CA_CB_prefactors);
+  AddFRMRotatingParticle(THR, 0, 0); // OG1
+  AddFRMRotatingParticle(THR, 0, 1); // CG2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(THR, 0, 2); // HG1
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(THR, 0, 3); // HB  
+    AddFRMRotatingParticle(THR, 0, 4); // HG21
+    AddFRMRotatingParticle(THR, 0, 5); // HG22  
+    AddFRMRotatingParticle(THR, 0, 6); // HG23  
+  }
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRule(THR, promod3::loop::BB_CB_INDEX, promod3::loop::THR_OG1_INDEX,
+               param.THR_CB_OG1_prefactors);
+    AddFRMFixParticle(THR, 1, 0); // OG1
+    AddFRMFixParticle(THR, 1, 1); //CG2
+    AddFRMRotatingParticle(THR, 1, 2); // HG1
+
+    if(mode == FULL_ATOMIC_MODE) {
+      AddFRMFixParticle(THR, 1, 3); // HB
+      AddFRMFixParticle(THR, 1, 4); // HG21
+      AddFRMFixParticle(THR, 1, 5); // HG22
+      AddFRMFixParticle(THR, 1, 6); // HG23
+    }
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 2;
+    if(mode == POLAR_HYDROGEN_MODE) {
+      cb_idx = 3;
+    }
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 7;
+    }
+    AddFRMFixParticle(THR, 0, cb_idx);
+    if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+      AddFRMFixParticle(THR, 1, cb_idx);
+    }
+  }
+
+  backbone_infos_[THR].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(THR, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(THR, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(THR, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(THR, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(THR, "H", promod3::loop::THR_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(THR, "HA", promod3::loop::THR_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(THR, "CB", promod3::loop::BB_CB_INDEX, false); 
+  }
+
+
+  // VAL
+  sidechain_infos_[VAL].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[VAL].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::VAL];
+  sidechain_infos_[VAL].frm_t = param.frm_t[ost::conop::VAL];
+
+  AddInfo(VAL, "CG1", promod3::loop::VAL_CG1_INDEX, false);
+  AddInfo(VAL, "CG2", promod3::loop::VAL_CG2_INDEX, false);
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(VAL, "HB", promod3::loop::VAL_HB_INDEX, true);
+    AddInfo(VAL, "HG11", promod3::loop::VAL_HG11_INDEX, true);
+    AddInfo(VAL, "HG12", promod3::loop::VAL_HG12_INDEX, true);
+    AddInfo(VAL, "HG13", promod3::loop::VAL_HG13_INDEX, true);
+    AddInfo(VAL, "HG21", promod3::loop::VAL_HG21_INDEX, true);
+    AddInfo(VAL, "HG22", promod3::loop::VAL_HG22_INDEX, true);
+    AddInfo(VAL, "HG23", promod3::loop::VAL_HG23_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(VAL, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(VAL, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.VAL_CA_CB_prefactors);
+  AddFRMRotatingParticle(VAL, 0, 0); // CG1
+  AddFRMRotatingParticle(VAL, 0, 1); // CG2
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(VAL, 0, 2); // HB
+    AddFRMRotatingParticle(VAL, 0, 3); // HG11
+    AddFRMRotatingParticle(VAL, 0, 4); // HG12
+    AddFRMRotatingParticle(VAL, 0, 5); // HG13
+    AddFRMRotatingParticle(VAL, 0, 6); // HG21
+    AddFRMRotatingParticle(VAL, 0, 7); // HG22
+    AddFRMRotatingParticle(VAL, 0, 8); // HG23
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 2;
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 9;
+    }
+    AddFRMFixParticle(VAL, 0, cb_idx);
+  }
+
+  backbone_infos_[VAL].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(VAL, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(VAL, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(VAL, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(VAL, "O", promod3::loop::BB_O_INDEX, false);
+  
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(VAL, "H", promod3::loop::VAL_H_INDEX, true);      
+  }
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(VAL, "HA", promod3::loop::VAL_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(VAL, "CB", promod3::loop::BB_CB_INDEX, false); 
+  }
+
+
+  // ILE
+  sidechain_infos_[ILE].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[ILE].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::ILE];
+  sidechain_infos_[ILE].frm_t = param.frm_t[ost::conop::ILE];
+
+  AddInfo(ILE, "CG1", promod3::loop::ILE_CG1_INDEX, false);
+  AddInfo(ILE, "CG2", promod3::loop::ILE_CG2_INDEX, false);  
+  AddInfo(ILE, "CD1", promod3::loop::ILE_CD1_INDEX, false);  
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(ILE, "HB", promod3::loop::ILE_HB_INDEX, true);
+    AddInfo(ILE, "HG12", promod3::loop::ILE_HG12_INDEX, true);
+    AddInfo(ILE, "HG13", promod3::loop::ILE_HG13_INDEX, true);
+    AddInfo(ILE, "HG21", promod3::loop::ILE_HG21_INDEX, true);
+    AddInfo(ILE, "HG22", promod3::loop::ILE_HG22_INDEX, true);
+    AddInfo(ILE, "HG23", promod3::loop::ILE_HG23_INDEX, true);
+    AddInfo(ILE, "HD11", promod3::loop::ILE_HD11_INDEX, true);
+    AddInfo(ILE, "HD12", promod3::loop::ILE_HD12_INDEX, true);
+    AddInfo(ILE, "HD13", promod3::loop::ILE_HD13_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(ILE, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(ILE, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.ILE_CA_CB_prefactors);
+  AddFRMRotatingParticle(ILE, 0, 0); // CG1
+  AddFRMRotatingParticle(ILE, 0, 1); // CG2
+  AddFRMRotatingParticle(ILE, 0, 2); // CD1
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(ILE, 0, 3); // HB
+    AddFRMRotatingParticle(ILE, 0, 4); // HG12
+    AddFRMRotatingParticle(ILE, 0, 5); // HG13
+    AddFRMRotatingParticle(ILE, 0, 6); // HG21
+    AddFRMRotatingParticle(ILE, 0, 7); // HG22
+    AddFRMRotatingParticle(ILE, 0, 8); // HG23
+    AddFRMRotatingParticle(ILE, 0, 9); // HD11
+    AddFRMRotatingParticle(ILE, 0, 10); // HD12
+    AddFRMRotatingParticle(ILE, 0, 11); // HD13
+  }
+
+
+  AddFRMRule(ILE, promod3::loop::BB_CB_INDEX, promod3::loop::ILE_CG1_INDEX,
+             param.ILE_CB_CG1_prefactors);
+  AddFRMFixParticle(ILE, 1, 0); // CG1
+  AddFRMFixParticle(ILE, 1, 1); // CG2
+  AddFRMRotatingParticle(ILE, 1, 2); // CD1
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(ILE, 1, 3); // HB
+    AddFRMRotatingParticle(ILE, 1, 4); // HG12
+    AddFRMRotatingParticle(ILE, 1, 5); // HG13
+    AddFRMFixParticle(ILE, 1, 6); // HG21
+    AddFRMFixParticle(ILE, 1, 7); // HG22
+    AddFRMFixParticle(ILE, 1, 8); // HG23
+    AddFRMRotatingParticle(ILE, 1, 9); // HD11
+    AddFRMRotatingParticle(ILE, 1, 10); // HD12
+    AddFRMRotatingParticle(ILE, 1, 11); // HD13 
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 3;
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 12;
+    }
+    AddFRMFixParticle(ILE, 0, cb_idx);
+    AddFRMFixParticle(ILE, 1, cb_idx);
+  }
+
+  backbone_infos_[ILE].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(ILE, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(ILE, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(ILE, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(ILE, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(ILE, "H", promod3::loop::ILE_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(ILE, "HA", promod3::loop::ILE_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(ILE, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // LEU
+  sidechain_infos_[LEU].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[LEU].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::LEU];
+  sidechain_infos_[LEU].frm_t = param.frm_t[ost::conop::LEU];
+  
+  AddInfo(LEU, "CG", promod3::loop::LEU_CG_INDEX, false);
+  AddInfo(LEU, "CD1", promod3::loop::LEU_CD1_INDEX, false);  
+  AddInfo(LEU, "CD2", promod3::loop::LEU_CD2_INDEX, false);  
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(LEU, "HB2", promod3::loop::LEU_HB2_INDEX, true);
+    AddInfo(LEU, "HB3", promod3::loop::LEU_HB3_INDEX, true);
+    AddInfo(LEU, "HG", promod3::loop::LEU_HG_INDEX, true);
+    AddInfo(LEU, "HD11", promod3::loop::LEU_HD11_INDEX, true);
+    AddInfo(LEU, "HD12", promod3::loop::LEU_HD12_INDEX, true);
+    AddInfo(LEU, "HD13", promod3::loop::LEU_HD13_INDEX, true);
+    AddInfo(LEU, "HD21", promod3::loop::LEU_HD21_INDEX, true);
+    AddInfo(LEU, "HD22", promod3::loop::LEU_HD22_INDEX, true);
+    AddInfo(LEU, "HD23", promod3::loop::LEU_HD23_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(LEU, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  AddFRMRule(LEU, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.LEU_CA_CB_prefactors);
+  AddFRMRotatingParticle(LEU, 0, 0); // CG
+  AddFRMRotatingParticle(LEU, 0, 1); // CD1
+  AddFRMRotatingParticle(LEU, 0, 2); // CD2
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(LEU, 0, 3); // HB2
+    AddFRMRotatingParticle(LEU, 0, 4); // HB3
+    AddFRMRotatingParticle(LEU, 0, 5); // HG
+    AddFRMRotatingParticle(LEU, 0, 6); // HD11
+    AddFRMRotatingParticle(LEU, 0, 7); // HD12
+    AddFRMRotatingParticle(LEU, 0, 8); // HD13
+    AddFRMRotatingParticle(LEU, 0, 9); // HD21
+    AddFRMRotatingParticle(LEU, 0, 10); // HD22
+    AddFRMRotatingParticle(LEU, 0, 11); // HD23
+  }
+
+  AddFRMRule(LEU, promod3::loop::BB_CB_INDEX, promod3::loop::LEU_CG_INDEX,
+             param.LEU_CB_CG_prefactors);
+  AddFRMFixParticle(LEU, 1, 0); // CG
+  AddFRMRotatingParticle(LEU, 1, 1); // CG1
+  AddFRMRotatingParticle(LEU, 1, 2); // CG2
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(LEU, 1, 3); // HB2
+    AddFRMFixParticle(LEU, 1, 4); // HB3
+    AddFRMRotatingParticle(LEU, 1, 5); // HG
+    AddFRMRotatingParticle(LEU, 1, 6); // HD11
+    AddFRMRotatingParticle(LEU, 1, 7); // HD12
+    AddFRMRotatingParticle(LEU, 1, 8); // HD13
+    AddFRMRotatingParticle(LEU, 1, 9); // HD21
+    AddFRMRotatingParticle(LEU, 1, 10); // HD22
+    AddFRMRotatingParticle(LEU, 1, 11); // HD23
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 3;
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 12;
+    }
+    AddFRMFixParticle(LEU, 0, cb_idx);
+    AddFRMFixParticle(LEU, 1, cb_idx);
+  }
+
+  backbone_infos_[LEU].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(LEU, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(LEU, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(LEU, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(LEU, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(LEU, "H", promod3::loop::LEU_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(LEU, "HA", promod3::loop::LEU_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(LEU, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // PROLINES DO NOT HAVE FRM DEFINITIONS!
+  // large scale benchmarks showed, that varying around chi angles in case
+  // of prolines has a negative effect on performance => reduce to one single
+  // subrotamer...
+
+  // PRO
+  sidechain_infos_[PRO].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[PRO].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::PRO];
+  sidechain_infos_[PRO].frm_t = param.frm_t[ost::conop::PRO];
+  
+  AddInfo(PRO, "CG", promod3::loop::PRO_CG_INDEX, false);
+  AddInfo(PRO, "CD", promod3::loop::PRO_CD_INDEX, false); 
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(PRO, "HB2", promod3::loop::PRO_HB2_INDEX, true);
+    AddInfo(PRO, "HB3", promod3::loop::PRO_HB3_INDEX, true);
+    AddInfo(PRO, "HG2", promod3::loop::PRO_HG2_INDEX, true);
+    AddInfo(PRO, "HG3", promod3::loop::PRO_HG3_INDEX, true);
+    AddInfo(PRO, "HD2", promod3::loop::PRO_HD2_INDEX, true);
+    AddInfo(PRO, "HD3", promod3::loop::PRO_HD3_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(PRO, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  backbone_infos_[PRO].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  AddBBInfo(PRO, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(PRO, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(PRO, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(PRO, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(PRO, "HA", promod3::loop::PRO_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(PRO, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // CPR
+  sidechain_infos_[CPR] = sidechain_infos_[PRO]; 
+  frm_rules_[CPR] = frm_rules_[PRO];
+  backbone_infos_[CPR] = backbone_infos_[PRO];
+
+
+  // TPR
+  sidechain_infos_[TPR] = sidechain_infos_[PRO];
+  frm_rules_[TPR] = frm_rules_[PRO];
+  backbone_infos_[TPR] = backbone_infos_[PRO];
+
+
+  // HSD
+  sidechain_infos_[HSD].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[HSD].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::HIS];
+  sidechain_infos_[HSD].frm_t = param.frm_t[ost::conop::HIS];
+
+  AddInfo(HSD, "CG", promod3::loop::HIS_CG_INDEX, false);
+  AddInfo(HSD, "ND1", promod3::loop::HIS_ND1_INDEX, false);
+  AddInfo(HSD, "CD2", promod3::loop::HIS_CD2_INDEX, false);
+  AddInfo(HSD, "CE1", promod3::loop::HIS_CE1_INDEX, false);
+  AddInfo(HSD, "NE2", promod3::loop::HIS_NE2_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddInfo(HSD, "HD1", promod3::loop::HIS_HD1_INDEX,true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(HSD, "HB2", promod3::loop::HIS_HB2_INDEX, true);
+    AddInfo(HSD, "HB3", promod3::loop::HIS_HB3_INDEX, true);
+    AddInfo(HSD, "HD2", promod3::loop::HIS_HD2_INDEX, true);
+    AddInfo(HSD, "HE1", promod3::loop::HIS_HE1_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(HSD, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(HSD, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.HIS_CA_CB_prefactors);
+  AddFRMRotatingParticle(HSD, 0, 0); // CG
+  AddFRMRotatingParticle(HSD, 0, 1); // ND1
+  AddFRMRotatingParticle(HSD, 0, 2); // CD2
+  AddFRMRotatingParticle(HSD, 0, 3); // CE1
+  AddFRMRotatingParticle(HSD, 0, 4); // NE2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(HSD, 0, 5); // HD1
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(HSD, 0, 6); // HB2
+    AddFRMRotatingParticle(HSD, 0, 7); // HB3
+    AddFRMRotatingParticle(HSD, 0, 8); // HD2
+    AddFRMRotatingParticle(HSD, 0, 9); // HE1
+  }
+
+  AddFRMRule(HSD, promod3::loop::BB_CB_INDEX, promod3::loop::HIS_CG_INDEX,
+             param.HIS_CB_CG_prefactors);
+  AddFRMFixParticle(HSD, 1, 0); // CG
+  AddFRMRotatingParticle(HSD, 1, 1); // ND1
+  AddFRMRotatingParticle(HSD, 1, 2); // CD2
+  AddFRMRotatingParticle(HSD, 1, 3); // CE1
+  AddFRMRotatingParticle(HSD, 1, 4); // NE2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(HSD, 1, 5); // HD1
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(HSD, 1, 6); // HB2
+    AddFRMRotatingParticle(HSD, 1, 7); // HB3
+    AddFRMRotatingParticle(HSD, 1, 8); // HD2
+    AddFRMRotatingParticle(HSD, 1, 9); // HE1      
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 5;
+    if(mode == POLAR_HYDROGEN_MODE) {
+      cb_idx = 6;
+    }
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 10;
+    }
+    AddFRMFixParticle(HSD, 0, cb_idx);
+    AddFRMFixParticle(HSD, 1, cb_idx);
+  }
+
+  backbone_infos_[HSD].has_hydrogens = (mode == POLAR_HYDROGEN_MODE || 
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(HSD, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(HSD, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(HSD, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(HSD, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(HSD, "H", promod3::loop::HIS_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(HSD, "HA", promod3::loop::HIS_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(HSD, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // HSE
+  sidechain_infos_[HSE].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                         mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[HSE].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::HIS];
+  sidechain_infos_[HSE].frm_t = param.frm_t[ost::conop::HIS];
+
+  AddInfo(HSE, "CG", promod3::loop::HIS_CG_INDEX, false);
+  AddInfo(HSE, "ND1", promod3::loop::HIS_ND1_INDEX, false);
+  AddInfo(HSE, "CD2", promod3::loop::HIS_CD2_INDEX, false);
+  AddInfo(HSE, "CE1", promod3::loop::HIS_CE1_INDEX, false);
+  AddInfo(HSE, "NE2", promod3::loop::HIS_NE2_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddInfo(HSE, "HE2", promod3::loop::HIS_HE2_INDEX,true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(HSE, "HB2", promod3::loop::HIS_HB2_INDEX, true);
+    AddInfo(HSE, "HB3", promod3::loop::HIS_HB3_INDEX, true);
+    AddInfo(HSE, "HD2", promod3::loop::HIS_HD2_INDEX, true);
+    AddInfo(HSE, "HE1", promod3::loop::HIS_HE1_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(HSE, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(HSE, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.HIS_CA_CB_prefactors);
+  AddFRMRotatingParticle(HSE, 0, 0); // CG
+  AddFRMRotatingParticle(HSE, 0, 1); // ND1
+  AddFRMRotatingParticle(HSE, 0, 2); // CD2
+  AddFRMRotatingParticle(HSE, 0, 3); // CE1
+  AddFRMRotatingParticle(HSE, 0, 4); // NE2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(HSE, 0, 5); // HE2
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(HSE, 0, 6); // HB2
+    AddFRMRotatingParticle(HSE, 0, 7); // HB3
+    AddFRMRotatingParticle(HSE, 0, 8); // HD2
+    AddFRMRotatingParticle(HSE, 0, 9); // HE1
+  }
+
+  AddFRMRule(HSE, promod3::loop::BB_CB_INDEX, promod3::loop::HIS_CG_INDEX,
+             param.HIS_CB_CG_prefactors);
+  AddFRMFixParticle(HSE, 1, 0); // CG
+  AddFRMRotatingParticle(HSE, 1, 1); // ND1
+  AddFRMRotatingParticle(HSE, 1, 2); // CD2
+  AddFRMRotatingParticle(HSE, 1, 3); // CE1
+  AddFRMRotatingParticle(HSE, 1, 4); // NE2
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(HSE, 1, 5); // HE2
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(HSE, 1, 6); // HB2
+    AddFRMRotatingParticle(HSE, 1, 7); // HB3
+    AddFRMRotatingParticle(HSE, 1, 8); // HD2
+    AddFRMRotatingParticle(HSE, 1, 9); // HE1      
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 5;
+    if(mode == POLAR_HYDROGEN_MODE) {
+      cb_idx = 6;
+    }
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 10;
+    }
+    AddFRMFixParticle(HSE, 0, cb_idx);
+    AddFRMFixParticle(HSE, 1, cb_idx);
+  }
+
+  backbone_infos_[HSE].has_hydrogens = (mode == POLAR_HYDROGEN_MODE || 
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(HSE, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(HSE, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(HSE, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(HSE, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(HSE, "H", promod3::loop::HIS_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(HSE, "HA", promod3::loop::HIS_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(HSE, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  // HIS
+  // this is a bit hacky... we just assign HSD as determined by a fair
+  // random number generator.
+  sidechain_infos_[HIS] = sidechain_infos_[HSD];
+  frm_rules_[HIS] = frm_rules_[HSD];
+  backbone_infos_[HIS] = backbone_infos_[HSD];
+
+
+  // PHE
+  sidechain_infos_[PHE].has_hydrogens = (mode == FULL_ATOMIC_MODE);
+  sidechain_infos_[PHE].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::PHE];
+  sidechain_infos_[PHE].frm_t = param.frm_t[ost::conop::PHE];
+  
+  AddInfo(PHE, "CG", promod3::loop::PHE_CG_INDEX, false);
+  AddInfo(PHE, "CD1", promod3::loop::PHE_CD1_INDEX, false);  
+  AddInfo(PHE, "CD2", promod3::loop::PHE_CD2_INDEX, false); 
+  AddInfo(PHE, "CE1", promod3::loop::PHE_CE1_INDEX, false);  
+  AddInfo(PHE, "CE2", promod3::loop::PHE_CE2_INDEX, false); 
+  AddInfo(PHE, "CZ", promod3::loop::PHE_CZ_INDEX, false); 
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddInfo(PHE, "HB2", promod3::loop::PHE_HB2_INDEX, true);
+    AddInfo(PHE, "HB3", promod3::loop::PHE_HB3_INDEX, true);
+    AddInfo(PHE, "HD1", promod3::loop::PHE_HD1_INDEX, true);
+    AddInfo(PHE, "HD2", promod3::loop::PHE_HD2_INDEX, true);
+    AddInfo(PHE, "HE1", promod3::loop::PHE_HE1_INDEX, true);
+    AddInfo(PHE, "HE2", promod3::loop::PHE_HE2_INDEX, true);
+    AddInfo(PHE, "HZ", promod3::loop::PHE_HZ_INDEX, true);
+  }
+
+  if(cb_in_sidechain) {
+    AddInfo(PHE, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+  AddFRMRule(PHE, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX,
+             param.PHE_CA_CB_prefactors);
+  AddFRMRotatingParticle(PHE, 0, 0); // CG
+  AddFRMRotatingParticle(PHE, 0, 1); // CD1
+  AddFRMRotatingParticle(PHE, 0, 2); // CD2
+  AddFRMRotatingParticle(PHE, 0, 3); // CE1
+  AddFRMRotatingParticle(PHE, 0, 4); // CE2
+  AddFRMRotatingParticle(PHE, 0, 5); // CZ
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMRotatingParticle(PHE, 0, 6); // HB2
+    AddFRMRotatingParticle(PHE, 0, 7); // HB3
+    AddFRMRotatingParticle(PHE, 0, 8); // HD1
+    AddFRMRotatingParticle(PHE, 0, 9); // HD2
+    AddFRMRotatingParticle(PHE, 0, 10); // HE1
+    AddFRMRotatingParticle(PHE, 0, 11); // HE2
+    AddFRMRotatingParticle(PHE, 0, 12); // HZ
+  }
+
+  AddFRMRule(PHE, promod3::loop::BB_CB_INDEX, promod3::loop::PHE_CG_INDEX,
+             param.PHE_CB_CG_prefactors);
+  AddFRMFixParticle(PHE, 1, 0); // CG
+  AddFRMRotatingParticle(PHE, 1, 1); // CD1
+  AddFRMRotatingParticle(PHE, 1, 2); // CD2
+  AddFRMRotatingParticle(PHE, 1, 3); // CE1
+  AddFRMRotatingParticle(PHE, 1, 4); // CE2
+  AddFRMRotatingParticle(PHE, 1, 5); // CZ
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddFRMFixParticle(PHE, 1, 6); // HB2
+    AddFRMFixParticle(PHE, 1, 7); // HB2
+    AddFRMRotatingParticle(PHE, 1, 8); // CD1
+    AddFRMRotatingParticle(PHE, 1, 9); // CD2
+    AddFRMRotatingParticle(PHE, 1, 10); // CE1
+    AddFRMRotatingParticle(PHE, 1, 11); // CE2
+    AddFRMRotatingParticle(PHE, 1, 12); // CZ
+  }
+
+  if(cb_in_sidechain) {
+    int cb_idx = 6;
+    if(mode == FULL_ATOMIC_MODE) {
+      cb_idx = 13;
+    }
+    AddFRMFixParticle(PHE, 0, cb_idx);
+    AddFRMFixParticle(PHE, 1, cb_idx);
+  }
+
+  backbone_infos_[PHE].has_hydrogens = (mode == POLAR_HYDROGEN_MODE || 
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(PHE, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(PHE, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(PHE, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(PHE, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(PHE, "H", promod3::loop::PHE_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(PHE, "HA", promod3::loop::PHE_HA_INDEX, true);
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(PHE, "CB", promod3::loop::BB_CB_INDEX, false);
+  }
+
+
+  // ALA
+
+  // The hydrogen situation is a bit special here...
+  // If its full atomic, we only put the hydrogens in the sidechains
+  // if the CBeta is also there. Otherwise, everything goes into the
+  // backbone.
+  sidechain_infos_[ALA].has_hydrogens = (mode == FULL_ATOMIC_MODE &&
+                                         cb_in_sidechain);
+  sidechain_infos_[ALA].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::ALA];
+  sidechain_infos_[ALA].frm_t = param.frm_t[ost::conop::ALA];
+
+  if(cb_in_sidechain) {
+    AddInfo(ALA, "CB", promod3::loop::BB_CB_INDEX, false);
+    if(mode == FULL_ATOMIC_MODE) {
+      AddInfo(ALA, "HB1", promod3::loop::ALA_HB1_INDEX, true);
+      AddInfo(ALA, "HB2", promod3::loop::ALA_HB2_INDEX, true);
+      AddInfo(ALA, "HB3", promod3::loop::ALA_HB3_INDEX, true);
+    }
+  }
+
+  backbone_infos_[ALA].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(ALA, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(ALA, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(ALA, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(ALA, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(ALA, "H", promod3::loop::ALA_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(ALA, "HA", promod3::loop::ALA_HA_INDEX, true);      
+  }
+
+  if(!cb_in_sidechain) {
+    AddBBInfo(ALA, "CB", promod3::loop::BB_CB_INDEX, false); 
+    if(mode == FULL_ATOMIC_MODE) {
+      AddBBInfo(ALA, "HB1", promod3::loop::ALA_HB1_INDEX, true);
+      AddBBInfo(ALA, "HB2", promod3::loop::ALA_HB2_INDEX, true);
+      AddBBInfo(ALA, "HB3", promod3::loop::ALA_HB3_INDEX, true);        
+    }
+  }
+
+
+  // GLY
+  sidechain_infos_[GLY].has_hydrogens = false;
+  sidechain_infos_[GLY].internal_e_prefactor = 
+  param.internal_e_prefactor[ost::conop::GLY];
+  sidechain_infos_[GLY].frm_t = param.frm_t[ost::conop::GLY];
+  
+  backbone_infos_[GLY].has_hydrogens = (mode == POLAR_HYDROGEN_MODE ||
+                                        mode == FULL_ATOMIC_MODE);
+  AddBBInfo(GLY, "N", promod3::loop::BB_N_INDEX, false);
+  AddBBInfo(GLY, "CA", promod3::loop::BB_CA_INDEX, false);
+  AddBBInfo(GLY, "C", promod3::loop::BB_C_INDEX, false);
+  AddBBInfo(GLY, "O", promod3::loop::BB_O_INDEX, false);
+
+  if(mode == POLAR_HYDROGEN_MODE || mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(GLY, "H", promod3::loop::GLY_H_INDEX, true);
+  }
+
+  if(mode == FULL_ATOMIC_MODE) {
+    AddBBInfo(GLY, "HA2", promod3::loop::GLY_HA2_INDEX, true);
+    AddBBInfo(GLY, "HA3", promod3::loop::GLY_HA3_INDEX, true);
+  }
+
+  for(uint i = 0; i <= XXX; ++i){
+    num_sidechain_particles_[i] = sidechain_infos_[i].particles.size();
+    num_frm_particles_[i] = num_sidechain_particles_[i];
+    for(uint j = 0; j < frm_rules_[i].size(); ++j){
+      num_frm_particles_[i] += (frm_rules_[i][j].prefactors.size() * 
+                                frm_rules_[i][j].rotating_particles.size());
+    }
+  }
+}
+
+
+RotamerInfo RotamerLookup::GetTerminalBackboneInfo(RotamerID id, bool n_ter,
+                                                   bool c_ter) {
+  // get a copy to work on
+  RotamerInfo info = backbone_infos_[id];
+
+  if(n_ter && mode_ != HEAVY_ATOM_MODE) {
+    // find and delete particle with name "H", add particles of 
+    // name "H1", "H2", "H3", only the first two in case of Proline
+    for(std::vector<ParticleInfo>::iterator it = info.particles.begin();
+        it != info.particles.end(); ++it) {
+      if(it->name == "H") {
+        info.particles.erase(it);
+        break;
+      }
+    }
+
+    ost::conop::AminoAcid aa = RotIDToAA(id);
+
+    ParticleInfo h1("H1", promod3::loop::AminoAcidLookup::GetInstance().GetH1Index(aa), true);
+    info.particles.push_back(h1);
+
+    ParticleInfo h2("H2", promod3::loop::AminoAcidLookup::GetInstance().GetH2Index(aa), true);
+    info.particles.push_back(h2);
+
+    if(aa != ost::conop::PRO) {
+      ParticleInfo h3("H3", promod3::loop::AminoAcidLookup::GetInstance().GetH3Index(aa), true);
+      info.particles.push_back(h3);
+    }
+  }
+
+  if(c_ter) {
+    // find particle with name "O" and mark it as terminal by setting its
+    // atom_index to -1
+    for(std::vector<ParticleInfo>::iterator it = info.particles.begin();
+        it != info.particles.end(); ++it) {
+      if(it->name == "O") {
+        it->atom_idx = -1;
+        break;
+      }
+    }
+    // atom_index of -2 marks terminal oxt
+    ParticleInfo oxt("OT", -2, false);
+    info.particles.push_back(oxt);
+  }
+
+  return info;
+}
+
+}} // ns
diff --git a/sidechain/src/rotamer_lookup.hh b/sidechain/src/rotamer_lookup.hh
new file mode 100644
index 0000000000000000000000000000000000000000..50215ce8954beb932f97085d228702e26ddec380
--- /dev/null
+++ b/sidechain/src/rotamer_lookup.hh
@@ -0,0 +1,307 @@
+// Copyright (c) 2013-2018, SIB - Swiss Institute of Bioinformatics and 
+//                          Biozentrum - University of Basel
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef PROMOD3_ROTAMER_LOOKUP_HH
+#define PROMOD3_ROTAMER_LOOKUP_HH
+
+#include <vector>
+#include <ost/base.hh>
+#include <promod3/loop/amino_acid_atoms.hh>
+#include <promod3/sidechain/rotamer_id.hh>
+
+namespace promod3 { namespace sidechain {
+
+// Controls the particles that will be Constructed from the RotamerConstructor
+enum RotamerLookupMode{
+  HEAVY_ATOM_MODE,
+  POLAR_HYDROGEN_MODE,
+  FULL_ATOMIC_MODE
+};
+
+// Controls the parametrization of the rotamers
+// Must be filled by energy function specific RotamerConstructor and
+// passed to base class RotamerConstructor when calling constructor
+// of RotamerConstructor base class
+struct RotamerLookupParam {
+
+  RotamerLookupParam(bool default_parametrization = true) {
+
+    if(default_parametrization) {
+      for(int i = 0; i < ost::conop::XXX + 1; ++i) {
+        frm_t[i] = 1.0;
+        internal_e_prefactor[i] = 1.0;
+      }
+      std::vector<Real> default_prefactors;
+      default_prefactors.push_back(-1.0);
+      default_prefactors.push_back(1.0);
+      ARG_CA_CB_prefactors = default_prefactors;
+      ARG_CB_CG_prefactors = default_prefactors;
+      ARG_CG_CD_prefactors = default_prefactors;
+      ARG_CD_NE_prefactors = default_prefactors;
+      ASN_CA_CB_prefactors = default_prefactors;
+      ASN_CB_CG_prefactors = default_prefactors;
+      ASP_CA_CB_prefactors = default_prefactors;
+      ASP_CB_CG_prefactors = default_prefactors;
+      GLN_CA_CB_prefactors = default_prefactors;
+      GLN_CB_CG_prefactors = default_prefactors;
+      GLN_CG_CD_prefactors = default_prefactors;
+      GLU_CA_CB_prefactors = default_prefactors;
+      GLU_CB_CG_prefactors = default_prefactors;
+      GLU_CG_CD_prefactors = default_prefactors;
+      LYS_CA_CB_prefactors = default_prefactors;
+      LYS_CB_CG_prefactors = default_prefactors;
+      LYS_CG_CD_prefactors = default_prefactors;
+      LYS_CD_CE_prefactors = default_prefactors;
+      SER_CA_CB_prefactors = default_prefactors;
+      SER_CB_OG_prefactors = default_prefactors;                                    
+      CYS_CA_CB_prefactors = default_prefactors;  
+      MET_CA_CB_prefactors = default_prefactors;
+      MET_CB_CG_prefactors = default_prefactors;
+      MET_CG_SD_prefactors = default_prefactors;
+      TRP_CA_CB_prefactors = default_prefactors;
+      TRP_CB_CG_prefactors = default_prefactors;
+      TYR_CA_CB_prefactors = default_prefactors;
+      TYR_CB_CG_prefactors = default_prefactors;
+      TYR_CZ_OH_prefactors = default_prefactors;                                     
+      THR_CA_CB_prefactors = default_prefactors;
+      THR_CB_OG1_prefactors = default_prefactors; 
+      VAL_CA_CB_prefactors = default_prefactors;
+      ILE_CA_CB_prefactors = default_prefactors;
+      ILE_CB_CG1_prefactors = default_prefactors;
+      LEU_CA_CB_prefactors = default_prefactors;
+      LEU_CB_CG_prefactors = default_prefactors;
+      HIS_CA_CB_prefactors = default_prefactors;
+      HIS_CB_CG_prefactors = default_prefactors;
+      PHE_CA_CB_prefactors = default_prefactors;
+      PHE_CB_CG_prefactors = default_prefactors;
+    }
+  }
+
+  // the internal energy prefactor of the constructed rotamers
+  Real internal_e_prefactor[ost::conop::XXX + 1];
+
+  // frm temperature parameters
+  Real frm_t[ost::conop::XXX + 1];
+
+  // rotation bond specific frm prefactors
+  std::vector<Real> ARG_CA_CB_prefactors;
+  std::vector<Real> ARG_CB_CG_prefactors;
+  std::vector<Real> ARG_CG_CD_prefactors;
+  std::vector<Real> ARG_CD_NE_prefactors;
+
+  std::vector<Real> ASN_CA_CB_prefactors;
+  std::vector<Real> ASN_CB_CG_prefactors;
+
+  std::vector<Real> ASP_CA_CB_prefactors;
+  std::vector<Real> ASP_CB_CG_prefactors;
+
+  std::vector<Real> GLN_CA_CB_prefactors;
+  std::vector<Real> GLN_CB_CG_prefactors;
+  std::vector<Real> GLN_CG_CD_prefactors;
+
+  std::vector<Real> GLU_CA_CB_prefactors;
+  std::vector<Real> GLU_CB_CG_prefactors;
+  std::vector<Real> GLU_CG_CD_prefactors;
+
+  std::vector<Real> LYS_CA_CB_prefactors;
+  std::vector<Real> LYS_CB_CG_prefactors;
+  std::vector<Real> LYS_CG_CD_prefactors;
+  std::vector<Real> LYS_CD_CE_prefactors;
+
+  std::vector<Real> SER_CA_CB_prefactors;
+  std::vector<Real> SER_CB_OG_prefactors; // only relevant when hydrogen is 
+                                          // constructed
+
+  std::vector<Real> CYS_CA_CB_prefactors;  
+
+  std::vector<Real> MET_CA_CB_prefactors;
+  std::vector<Real> MET_CB_CG_prefactors;
+  std::vector<Real> MET_CG_SD_prefactors;
+
+  std::vector<Real> TRP_CA_CB_prefactors;
+  std::vector<Real> TRP_CB_CG_prefactors;
+
+  std::vector<Real> TYR_CA_CB_prefactors;
+  std::vector<Real> TYR_CB_CG_prefactors;
+  std::vector<Real> TYR_CZ_OH_prefactors; // only relevant when hydrogen is 
+                                          // constructed
+
+  std::vector<Real> THR_CA_CB_prefactors;
+  std::vector<Real> THR_CB_OG1_prefactors; // only relevant when hydrogen is 
+                                           // constructed
+
+  std::vector<Real> VAL_CA_CB_prefactors;
+
+  std::vector<Real> ILE_CA_CB_prefactors;
+  std::vector<Real> ILE_CB_CG1_prefactors;
+
+  std::vector<Real> LEU_CA_CB_prefactors;
+  std::vector<Real> LEU_CB_CG_prefactors;
+
+  std::vector<Real> HIS_CA_CB_prefactors;
+  std::vector<Real> HIS_CB_CG_prefactors;
+
+  std::vector<Real> PHE_CA_CB_prefactors;
+  std::vector<Real> PHE_CB_CG_prefactors;
+};
+
+
+struct ParticleInfo {
+
+  ParticleInfo() { }
+
+  ParticleInfo(const String& n, int idx, bool ih): name(n), atom_idx(idx),
+                                                   is_hydrogen(ih) { }
+
+  String name; 
+  int atom_idx;  // for AllAtomPositions 
+                 // (idx in HydrogenStorage if is_hydrogen is true)
+  bool is_hydrogen;
+};
+
+
+struct CustomHydrogenInfo {
+
+  CustomHydrogenInfo() { }
+  
+  CustomHydrogenInfo(int idx, int a_idx_one, int a_idx_two, int a_idx_three, 
+                          Real bl, Real a, int c_idx): atom_idx(idx),
+                                                       anchor_idx_one(a_idx_one), 
+                                                       anchor_idx_two(a_idx_two), 
+                                                       anchor_idx_three(a_idx_three), 
+                                                       bond_length(bl), angle(a),
+                                                       chi_idx(c_idx){ }
+  int atom_idx; //the idx in the hydrogen constructor
+  int anchor_idx_one; // idx in AllAtomPositions
+  int anchor_idx_two; 
+  int anchor_idx_three;
+  Real bond_length;
+  Real angle;
+  int chi_idx;
+};
+
+
+struct FRMRule {
+
+  FRMRule() { }
+  
+  int anchor_idx_one; // idx of heavy atom in RotamerConstructor::pos_buffer_
+  int anchor_idx_two; // idx of heavy atom in RotamerConstructor::pos_buffer_
+  std::vector<Real> prefactors;
+  // The following indices are NOT relative to any position buffer but rather
+  // to the ordering as the particles are defined in RotamerInfo
+  std::vector<int> fix_particles;
+  std::vector<int> rotating_particles;
+};
+
+
+struct RotamerInfo {
+
+  RotamerInfo() { }
+  
+  std::vector<ParticleInfo> particles;
+  std::vector<CustomHydrogenInfo> custom_hydrogens;
+  Real internal_e_prefactor;
+  Real frm_t;
+  bool has_hydrogens;
+};
+
+
+class RotamerLookup{
+
+public:
+  
+  RotamerLookup(bool cb_in_sidechain, 
+                RotamerLookupMode mode,
+                const RotamerLookupParam& param = RotamerLookupParam());
+
+  // Data access
+  const RotamerInfo& GetSidechainInfo(RotamerID id) const { 
+    return sidechain_infos_[id]; 
+  }
+
+  const RotamerInfo& GetBackboneInfo(RotamerID id) const { 
+    return backbone_infos_[id]; 
+  }
+
+  RotamerInfo GetTerminalBackboneInfo(RotamerID id, bool n_ter,
+                                      bool c_ter);
+
+  const std::vector<FRMRule>& GetFRMRules(RotamerID id) const { 
+    return frm_rules_[id]; 
+  }
+
+  int GetNumSidechainParticles(RotamerID id) const { 
+    return num_sidechain_particles_[id]; 
+  }
+
+  int GetNumFRMSidechainParticles(RotamerID id) const { 
+    return num_frm_particles_[id]; 
+  }
+
+private:
+
+  void AddInfo(RotamerID id, const String& name, int idx, bool is_h) {
+    ParticleInfo p(name, idx, is_h);
+    sidechain_infos_[id].particles.push_back(p);
+  }
+
+  void AddCustomHydrogenInfo(RotamerID id, int idx, 
+                             int a_idx_one, int a_idx_two, int a_idx_three, 
+                             Real bl, Real a, int c_idx) {
+    CustomHydrogenInfo i(idx, a_idx_one, a_idx_two, a_idx_three, bl, a, c_idx);
+    sidechain_infos_[id].custom_hydrogens.push_back(i);
+  }
+
+  void AddBBInfo(RotamerID id, const String& name, int idx, bool is_h) {
+    ParticleInfo p(name, idx, is_h);
+    backbone_infos_[id].particles.push_back(p);
+  }
+
+  void AddFRMRule(RotamerID id, int idx_one, int idx_two,
+                  const std::vector<Real>& prefactors){
+    frm_rules_[id].push_back(FRMRule());
+    frm_rules_[id].back().anchor_idx_one = idx_one;
+    frm_rules_[id].back().anchor_idx_two = idx_two;
+    frm_rules_[id].back().prefactors = prefactors;
+  }
+
+  void AddFRMFixParticle(RotamerID id, int rule_idx, int p_idx){
+    frm_rules_[id][rule_idx].fix_particles.push_back(p_idx);
+  }
+
+  void AddFRMRotatingParticle(RotamerID id, int rule_idx, int p_idx){
+    frm_rules_[id][rule_idx].rotating_particles.push_back(p_idx);
+  }
+
+  // To construct classical rotamers or as lookup for sidechain frame residues
+  RotamerInfo sidechain_infos_[XXX + 1];
+
+  // To construct backbone frame residues
+  RotamerInfo backbone_infos_[XXX + 1];
+
+  // Additional info required for generating frm rotamers
+  std::vector<FRMRule> frm_rules_[XXX + 1];
+
+  int num_sidechain_particles_[XXX + 1];
+  int num_frm_particles_[XXX + 1];
+
+  RotamerLookupMode mode_;
+};
+
+
+}} // ns
+
+#endif
diff --git a/sidechain/src/scwrl4_rotamer_constructor.cc b/sidechain/src/scwrl4_rotamer_constructor.cc
index 7619d2ec8cef748701cf4ba50b046dd8cdc53ee4..687063f6cb9b59cdd9d9b3068f348b84a5f5a3af 100644
--- a/sidechain/src/scwrl4_rotamer_constructor.cc
+++ b/sidechain/src/scwrl4_rotamer_constructor.cc
@@ -22,7 +22,36 @@
 #include <promod3/core/runtime_profiling.hh>
 #include <ost/conop/conop.hh>
 
-namespace{
+namespace promod3 { namespace sidechain {
+
+/// \brief Types of lone pair construction
+enum SCWRL4LPRule {
+  LONE_PAIR_CARBONYL, LONE_PAIR_COH, LONE_PAIR_CNC
+};
+
+/// \brief Info for lone pair construction (always involves 3 particles)
+/// -> indices are in same order as particles. The lone pair gets finally added
+/// to particle with p_idx
+/// A, B and C are indices as they are stored in AllAtomPositions, p_idx is the 
+/// index of the particle in the rotamer, where the lone pairs get added
+struct SCWRL4LPInfo {
+  SCWRL4LPInfo() { }
+  SCWRL4LPInfo(int idx_A, int idx_B, int idx_C,
+               bool a_ih, bool b_ih, bool c_ih, 
+               SCWRL4LPRule r)
+               : index_A(idx_A), index_B(idx_B),
+                 index_C(idx_C), A_is_hydrogen(a_ih),
+                 B_is_hydrogen(b_ih), C_is_hydrogen(c_ih),
+                 rule(r) { }
+  int index_A;
+  int index_B;
+  int index_C;
+  bool A_is_hydrogen;
+  bool B_is_hydrogen;
+  bool C_is_hydrogen;
+  SCWRL4LPRule rule;
+};
+
 
 // add lone pairs for carbonyl (X-C-O) to O particle p
 void _AddLonePairsCarbonyl(const geom::Vec3& x_pos, const geom::Vec3& c_pos,
@@ -37,6 +66,7 @@ void _AddLonePairsCarbonyl(const geom::Vec3& x_pos, const geom::Vec3& c_pos,
   p->AddLonePair(lone_pair_center_two - o_pos);
 }
 
+
 // add lone pairs for C-O-H combos (SER / THR / TYR) to O particle p
 void _AddLonePairsCOH(const geom::Vec3& c_pos, const geom::Vec3& o_pos,
                       const geom::Vec3& h_pos, 
@@ -67,7 +97,7 @@ void _AddLonePairsCNC(const geom::Vec3& c1_pos, const geom::Vec3& n_pos,
 }
 
 void EvalLonePairRule(promod3::sidechain::SCWRL4Param* p,
-                      promod3::sidechain::SCWRLLPRule rule,
+                      promod3::sidechain::SCWRL4LPRule rule,
                       const geom::Vec3& a,
                       const geom::Vec3& b,
                       const geom::Vec3& c) {
@@ -87,10 +117,12 @@ void EvalLonePairRule(promod3::sidechain::SCWRL4Param* p,
   }
 }
 
+
 inline bool _IsHydrogen(const String& element) {
   return element == "H" || element == "D";
 }
 
+
 // forward declaration
 struct _AtomInfo;
 
@@ -183,1425 +215,617 @@ _AtomSpecCPList _GetCarboxylAtoms(const _AtomInfo& atom_info) {
   return carbonyl_atoms;
 }
 
-}
-
-namespace promod3 { namespace sidechain {
-
-SCWRLRotamerLookup::SCWRLRotamerLookup(bool cb_in_sidechain) {
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-                                "SCWRLRotamerLookup::SCWRLRotamerLookup", 2);
-  
-  // ARG
-  sidechain_infos_[ARG].has_hydrogens = true;
-  sidechain_infos_[ARG].internal_e_prefactor = 2.27;
-  sidechain_infos_[ARG].frm_t = 1.23;
-
-  AddInfo(ARG, CH2Particle, 0.0, "CG", promod3::loop::ARG_CG_INDEX, false);
-  AddInfo(ARG, CH2Particle, 0.1, "CD", promod3::loop::ARG_CD_INDEX, false);
-  AddInfo(ARG, NParticle, -0.4, "NE", promod3::loop::ARG_NE_INDEX, false);
-  AddInfo(ARG, CParticle, 0.5, "CZ", promod3::loop::ARG_CZ_INDEX, false);
-  AddInfo(ARG, NParticle, -0.45, "NH1", promod3::loop::ARG_NH1_INDEX, false);
-  AddInfo(ARG, NParticle, -0.45, "NH2", promod3::loop::ARG_NH2_INDEX, false);
-  AddInfo(ARG, HParticle, 0.3, "HE", promod3::loop::ARG_HE_INDEX, true);
-  AddInfo(ARG, HParticle, 0.35, "HH11", promod3::loop::ARG_HH11_INDEX, true);
-  AddInfo(ARG, HParticle, 0.35, "HH12", promod3::loop::ARG_HH12_INDEX, true);
-  AddInfo(ARG, HParticle, 0.35, "HH21", promod3::loop::ARG_HH21_INDEX, true);
-  AddInfo(ARG, HParticle, 0.35, "HH22", promod3::loop::ARG_HH22_INDEX, true);
-
-  if(cb_in_sidechain) {
-    AddInfo(ARG, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddPDir(ARG, promod3::loop::ARG_HE_INDEX, promod3::loop::ARG_NE_INDEX, 6);
-  AddPDir(ARG, promod3::loop::ARG_HH11_INDEX, promod3::loop::ARG_NH1_INDEX, 7);
-  AddPDir(ARG, promod3::loop::ARG_HH12_INDEX, promod3::loop::ARG_NH1_INDEX, 8);
-  AddPDir(ARG, promod3::loop::ARG_HH21_INDEX, promod3::loop::ARG_NH2_INDEX, 9);
-  AddPDir(ARG, promod3::loop::ARG_HH22_INDEX, promod3::loop::ARG_NH2_INDEX, 10);
-
-  AddFRMRule(ARG, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(ARG, 0, -0.87);
-  AddFRMPrefactor(ARG, 0, 0.87);
-  AddFRMRotatingParticle(ARG, 0, 0);
-  AddFRMRotatingParticle(ARG, 0, 1);
-  AddFRMRotatingParticle(ARG, 0, 2);
-  AddFRMRotatingParticle(ARG, 0, 3);
-  AddFRMRotatingParticle(ARG, 0, 4);
-  AddFRMRotatingParticle(ARG, 0, 5);
-  AddFRMRotatingParticle(ARG, 0, 6);
-  AddFRMRotatingParticle(ARG, 0, 7);
-  AddFRMRotatingParticle(ARG, 0, 8);
-  AddFRMRotatingParticle(ARG, 0, 9);
-  AddFRMRotatingParticle(ARG, 0, 10);
-
-  AddFRMRule(ARG, promod3::loop::BB_CB_INDEX, promod3::loop::ARG_CG_INDEX);
-  AddFRMPrefactor(ARG, 1, -1.62);
-  AddFRMPrefactor(ARG, 1, 1.62);
-  AddFRMFixParticle(ARG, 1, 0);
-  AddFRMRotatingParticle(ARG, 1, 1);
-  AddFRMRotatingParticle(ARG, 1, 2);
-  AddFRMRotatingParticle(ARG, 1, 3);
-  AddFRMRotatingParticle(ARG, 1, 4);
-  AddFRMRotatingParticle(ARG, 1, 5);
-  AddFRMRotatingParticle(ARG, 1, 6);
-  AddFRMRotatingParticle(ARG, 1, 7);
-  AddFRMRotatingParticle(ARG, 1, 8);
-  AddFRMRotatingParticle(ARG, 1, 9);
-  AddFRMRotatingParticle(ARG, 1, 10);
-
-  AddFRMRule(ARG, promod3::loop::ARG_CG_INDEX, promod3::loop::ARG_CD_INDEX);
-  AddFRMPrefactor(ARG, 2, -1.67);
-  AddFRMPrefactor(ARG, 2, 1.67);
-  AddFRMFixParticle(ARG, 2, 0);
-  AddFRMFixParticle(ARG, 2, 1);
-  AddFRMRotatingParticle(ARG, 2, 2);
-  AddFRMRotatingParticle(ARG, 2, 3);
-  AddFRMRotatingParticle(ARG, 2, 4);
-  AddFRMRotatingParticle(ARG, 2, 5);
-  AddFRMRotatingParticle(ARG, 2, 6);
-  AddFRMRotatingParticle(ARG, 2, 7);
-  AddFRMRotatingParticle(ARG, 2, 8);
-  AddFRMRotatingParticle(ARG, 2, 9);
-  AddFRMRotatingParticle(ARG, 2, 10);
-
-  AddFRMRule(ARG, promod3::loop::ARG_CD_INDEX, promod3::loop::ARG_NE_INDEX);
-  AddFRMPrefactor(ARG, 3, -0.73);
-  AddFRMPrefactor(ARG, 3, 0.73);
-  AddFRMFixParticle(ARG, 3, 0);
-  AddFRMFixParticle(ARG, 3, 1);
-  AddFRMFixParticle(ARG, 3, 2);
-  AddFRMRotatingParticle(ARG, 3, 3);
-  AddFRMRotatingParticle(ARG, 3, 4);
-  AddFRMRotatingParticle(ARG, 3, 5);
-  AddFRMRotatingParticle(ARG, 3, 6);
-  AddFRMRotatingParticle(ARG, 3, 7);
-  AddFRMRotatingParticle(ARG, 3, 8);
-  AddFRMRotatingParticle(ARG, 3, 9);
-  AddFRMRotatingParticle(ARG, 3, 10);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(ARG, 0, 11);
-    AddFRMFixParticle(ARG, 1, 11);
-    AddFRMFixParticle(ARG, 2, 11);
-    AddFRMFixParticle(ARG, 3, 11);
-  }
-
-  backbone_infos_[ARG].has_hydrogens = true;
-  AddBBInfo(ARG, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(ARG, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(ARG, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(ARG, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(ARG, HParticle, 0.25, "H", promod3::loop::ARG_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(ARG, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(ARG, promod3::loop::ARG_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(ARG, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // ASN
-  sidechain_infos_[ASN].has_hydrogens = true;
-  sidechain_infos_[ASN].internal_e_prefactor = 1.80;
-  sidechain_infos_[ASN].frm_t = 1.41;
-
-  AddInfo(ASN, CParticle, 0.55, "CG", promod3::loop::ASN_CG_INDEX, false);
-  AddInfo(ASN, OParticle, -0.55, "OD1", promod3::loop::ASN_OD1_INDEX, false);
-  AddInfo(ASN, NParticle, -0.6, "ND2", promod3::loop::ASN_ND2_INDEX, false);
-  AddInfo(ASN, HParticle, 0.3, "HD21", promod3::loop::ASN_HD21_INDEX, true);
-  AddInfo(ASN, HParticle, 0.3, "HD22", promod3::loop::ASN_HD22_INDEX, true);
-
-  if(cb_in_sidechain) {
-    AddInfo(ASN, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddPDir(ASN, promod3::loop::ASN_HD21_INDEX, promod3::loop::ASN_ND2_INDEX, 3);
-  AddPDir(ASN, promod3::loop::ASN_HD22_INDEX, promod3::loop::ASN_ND2_INDEX, 4);
-  AddLP(ASN, promod3::loop::ASN_ND2_INDEX, promod3::loop::ASN_CG_INDEX, 
-        promod3::loop::ASN_OD1_INDEX, false, false, false, 1, LONE_PAIR_CARBONYL);
-
-  AddFRMRule(ASN, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(ASN, 0, -0.62);
-  AddFRMPrefactor(ASN, 0, 0.62);
-  AddFRMRotatingParticle(ASN, 0, 0);
-  AddFRMRotatingParticle(ASN, 0, 1);
-  AddFRMRotatingParticle(ASN, 0, 2);
-  AddFRMRotatingParticle(ASN, 0, 3);
-  AddFRMRotatingParticle(ASN, 0, 4);
-
-  AddFRMRule(ASN, promod3::loop::BB_CB_INDEX, promod3::loop::ASN_CG_INDEX);
-  AddFRMPrefactor(ASN, 1, -1.93);
-  AddFRMPrefactor(ASN, 1, 1.93);
-  AddFRMFixParticle(ASN, 1, 0);
-  AddFRMRotatingParticle(ASN, 1, 1);
-  AddFRMRotatingParticle(ASN, 1, 2);
-  AddFRMRotatingParticle(ASN, 1, 3);
-  AddFRMRotatingParticle(ASN, 1, 4);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(ASN, 0, 5);
-    AddFRMFixParticle(ASN, 1, 5);
-  }
-
-  backbone_infos_[ASN].has_hydrogens = true;
-  AddBBInfo(ASN, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(ASN, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(ASN, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(ASN, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(ASN, HParticle, 0.25, "H", promod3::loop::ASN_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(ASN, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(ASN, promod3::loop::ASN_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(ASN, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // ASP
-  sidechain_infos_[ASP].internal_e_prefactor = 2.44;
-  sidechain_infos_[ASP].frm_t = 1.48;
-  sidechain_infos_[ASP].has_hydrogens = false;
-
-  AddInfo(ASP, CParticle, 0.36, "CG", promod3::loop::ASP_CG_INDEX, false);
-  AddInfo(ASP, OParticle, -0.60, "OD1", promod3::loop::ASP_OD1_INDEX, false);
-  AddInfo(ASP, OParticle, -0.60, "OD2", promod3::loop::ASP_OD2_INDEX, false);
-
-  if(cb_in_sidechain) {
-    AddInfo(ASP, CH2Particle, -0.16, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddLP(ASP, promod3::loop::ASP_OD2_INDEX, promod3::loop::ASP_CG_INDEX, 
-        promod3::loop::ASP_OD1_INDEX, false, false, false, 1, LONE_PAIR_CARBONYL);
-  AddLP(ASP, promod3::loop::ASP_OD1_INDEX, promod3::loop::ASP_CG_INDEX, 
-        promod3::loop::ASP_OD2_INDEX, false, false, false, 2, LONE_PAIR_CARBONYL);
-
-  AddFRMRule(ASP, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(ASP, 0, -1.59);
-  AddFRMPrefactor(ASP, 0, 1.59);
-  AddFRMRotatingParticle(ASP, 0, 0);
-  AddFRMRotatingParticle(ASP, 0, 1);
-  AddFRMRotatingParticle(ASP, 0, 2);
-
-  AddFRMRule(ASP, promod3::loop::BB_CB_INDEX, promod3::loop::ASP_CG_INDEX);
-  AddFRMPrefactor(ASP, 1, -0.63);
-  AddFRMPrefactor(ASP, 1, 0.63);
-  AddFRMFixParticle(ASP, 1, 0);
-  AddFRMRotatingParticle(ASP, 1, 1);
-  AddFRMRotatingParticle(ASP, 1, 2);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(ASP, 0, 3);
-    AddFRMFixParticle(ASP, 1, 3);
-  }
-
-  backbone_infos_[ASP].has_hydrogens = true;
-  AddBBInfo(ASP, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(ASP, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(ASP, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(ASP, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(ASP, HParticle, 0.25, "H", promod3::loop::ASP_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(ASP, CH2Particle, -0.16, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(ASP, promod3::loop::ASP_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(ASP, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // GLN
-  sidechain_infos_[GLN].has_hydrogens = true;
-  sidechain_infos_[GLN].internal_e_prefactor = 1.61;
-  sidechain_infos_[GLN].frm_t = 1.32;
-
-  AddInfo(GLN, CH2Particle, 0.0, "CG", promod3::loop::GLN_CG_INDEX, false);
-  AddInfo(GLN, CParticle, 0.55, "CD", promod3::loop::GLN_CD_INDEX, false);
-  AddInfo(GLN, OParticle, -0.55, "OE1", promod3::loop::GLN_OE1_INDEX, false);
-  AddInfo(GLN, NParticle, -0.60, "NE2", promod3::loop::GLN_NE2_INDEX, false);
-  AddInfo(GLN, HParticle, 0.3, "HE21", promod3::loop::GLN_HE21_INDEX, true);
-  AddInfo(GLN, HParticle, 0.3, "HE22", promod3::loop::GLN_HE22_INDEX, true);
-
-  if(cb_in_sidechain) {
-    AddInfo(GLN, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddPDir(GLN, promod3::loop::GLN_HE21_INDEX, promod3::loop::GLN_NE2_INDEX, 4);
-  AddPDir(GLN, promod3::loop::GLN_HE22_INDEX, promod3::loop::GLN_NE2_INDEX, 5);
-  AddLP(GLN, promod3::loop::GLN_NE2_INDEX, promod3::loop::GLN_CD_INDEX, 
-        promod3::loop::GLN_OE1_INDEX, false, false, false, 2, LONE_PAIR_CARBONYL);
-
-  AddFRMRule(GLN, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(GLN, 0, -1.55);
-  AddFRMPrefactor(GLN, 0, 1.55);
-  AddFRMRotatingParticle(GLN, 0, 0);
-  AddFRMRotatingParticle(GLN, 0, 1);
-  AddFRMRotatingParticle(GLN, 0, 2);
-  AddFRMRotatingParticle(GLN, 0, 3);
-  AddFRMRotatingParticle(GLN, 0, 4);
-  AddFRMRotatingParticle(GLN, 0, 5);
-
-  AddFRMRule(GLN, promod3::loop::BB_CB_INDEX, promod3::loop::GLN_CG_INDEX);
-  AddFRMPrefactor(GLN, 1, -0.53);
-  AddFRMPrefactor(GLN, 1, 0.53);
-  AddFRMFixParticle(GLN, 1, 0);
-  AddFRMRotatingParticle(GLN, 1, 1);
-  AddFRMRotatingParticle(GLN, 1, 2);
-  AddFRMRotatingParticle(GLN, 1, 3);
-  AddFRMRotatingParticle(GLN, 1, 4);
-  AddFRMRotatingParticle(GLN, 1, 5);
-
-  AddFRMRule(GLN, promod3::loop::GLN_CG_INDEX, promod3::loop::GLN_CD_INDEX);
-  AddFRMPrefactor(GLN, 2, -1.89);
-  AddFRMPrefactor(GLN, 2, 1.89);
-  AddFRMFixParticle(GLN, 2, 0);
-  AddFRMFixParticle(GLN, 2, 1);
-  AddFRMRotatingParticle(GLN, 2, 2);
-  AddFRMRotatingParticle(GLN, 2, 3);
-  AddFRMRotatingParticle(GLN, 2, 4);
-  AddFRMRotatingParticle(GLN, 2, 5);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(GLN, 0, 6);
-    AddFRMFixParticle(GLN, 1, 6);
-    AddFRMFixParticle(GLN, 2, 6);
-  }
-
-  backbone_infos_[GLN].has_hydrogens = true;
-  AddBBInfo(GLN, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(GLN, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(GLN, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(GLN, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(GLN, HParticle, 0.25, "H", promod3::loop::GLN_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(GLN, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(GLN, promod3::loop::GLN_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(GLN, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // GLU
-  sidechain_infos_[GLU].has_hydrogens = false;
-  sidechain_infos_[GLU].internal_e_prefactor = 1.85;
-  sidechain_infos_[GLU].frm_t = 0.94;
-
-  AddInfo(GLU, CH2Particle, -0.16, "CG", promod3::loop::GLU_CG_INDEX, false);
-  AddInfo(GLU, CParticle, 0.36, "CD", promod3::loop::GLU_CD_INDEX, false);
-  AddInfo(GLU, OParticle, -0.60, "OE1", promod3::loop::GLU_OE1_INDEX, false);
-  AddInfo(GLU, OParticle, -0.60, "OE2", promod3::loop::GLU_OE2_INDEX, false);
-
-  if(cb_in_sidechain) {
-    AddInfo(GLU, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddLP(GLU, promod3::loop::GLU_OE2_INDEX, promod3::loop::GLU_CD_INDEX, 
-        promod3::loop::GLU_OE1_INDEX, false, false, false, 2, LONE_PAIR_CARBONYL);
-  AddLP(GLU, promod3::loop::GLU_OE1_INDEX, promod3::loop::GLU_CD_INDEX, 
-        promod3::loop::GLU_OE2_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  AddFRMRule(GLU, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(GLU, 0, -0.82);
-  AddFRMPrefactor(GLU, 0, 0.82);
-  AddFRMRotatingParticle(GLU, 0, 0);
-  AddFRMRotatingParticle(GLU, 0, 1);
-  AddFRMRotatingParticle(GLU, 0, 2);
-  AddFRMRotatingParticle(GLU, 0, 3);
-
-  AddFRMRule(GLU, promod3::loop::BB_CB_INDEX, promod3::loop::GLU_CG_INDEX);
-  AddFRMPrefactor(GLU, 1, -1.57);
-  AddFRMPrefactor(GLU, 1, 1.57);
-  AddFRMFixParticle(GLU, 1, 0);
-  AddFRMRotatingParticle(GLU, 1, 1);
-  AddFRMRotatingParticle(GLU, 1, 2);
-  AddFRMRotatingParticle(GLU, 1, 3);
-
-  AddFRMRule(GLU, promod3::loop::GLU_CG_INDEX, promod3::loop::GLU_CD_INDEX);
-  AddFRMPrefactor(GLU, 2, -0.76);
-  AddFRMPrefactor(GLU, 2, 0.76);
-  AddFRMFixParticle(GLU, 2, 0);
-  AddFRMFixParticle(GLU, 2, 1);
-  AddFRMRotatingParticle(GLU, 2, 2);
-  AddFRMRotatingParticle(GLU, 2, 3);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(GLU, 0, 4);
-    AddFRMFixParticle(GLU, 1, 4);
-    AddFRMFixParticle(GLU, 2, 4);
-  }
-
-  backbone_infos_[GLU].has_hydrogens = true;
-  AddBBInfo(GLU, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(GLU, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(GLU, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(GLU, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(GLU, HParticle, 0.25, "H", promod3::loop::GLU_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(GLU, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(GLU, promod3::loop::GLU_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(GLU, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // LYS
-  sidechain_infos_[LYS].has_hydrogens = true;
-  sidechain_infos_[LYS].internal_e_prefactor = 2.13;
-  sidechain_infos_[LYS].frm_t = 1.27;
-
-  AddInfo(LYS, CH2Particle, 0.0, "CG", promod3::loop::LYS_CG_INDEX,false);
-  AddInfo(LYS, CH2Particle, 0.0, "CD", promod3::loop::LYS_CD_INDEX,false);
-  AddInfo(LYS, CH2Particle, 0.25, "CE", promod3::loop::LYS_CE_INDEX,false);
-  AddInfo(LYS, NParticle, -0.3, "NZ", promod3::loop::LYS_NZ_INDEX,false);
-  AddInfo(LYS, HParticle, 0.35, "HZ1", promod3::loop::LYS_HZ1_INDEX,true);
-  AddInfo(LYS, HParticle, 0.35, "HZ2", promod3::loop::LYS_HZ2_INDEX,true);
-  AddInfo(LYS, HParticle, 0.35, "HZ3", promod3::loop::LYS_HZ3_INDEX,true);
-
-  if(cb_in_sidechain) {
-    AddInfo(LYS, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddPDir(LYS, promod3::loop::LYS_HZ1_INDEX, promod3::loop::LYS_NZ_INDEX, 4);
-  AddPDir(LYS, promod3::loop::LYS_HZ2_INDEX, promod3::loop::LYS_NZ_INDEX, 5);
-  AddPDir(LYS, promod3::loop::LYS_HZ3_INDEX, promod3::loop::LYS_NZ_INDEX, 6);
-
-  AddFRMRule(LYS, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(LYS, 0, -1.62);
-  AddFRMPrefactor(LYS, 0, 1.62);
-  AddFRMRotatingParticle(LYS, 0, 0);
-  AddFRMRotatingParticle(LYS, 0, 1);
-  AddFRMRotatingParticle(LYS, 0, 2);
-  AddFRMRotatingParticle(LYS, 0, 3);
-  AddFRMRotatingParticle(LYS, 0, 4);
-  AddFRMRotatingParticle(LYS, 0, 5);
-  AddFRMRotatingParticle(LYS, 0, 6);
-
-  AddFRMRule(LYS, promod3::loop::BB_CB_INDEX, promod3::loop::LYS_CG_INDEX);
-  AddFRMPrefactor(LYS, 1, -0.99);
-  AddFRMPrefactor(LYS, 1, 0.99);
-  AddFRMFixParticle(LYS, 1, 0);
-  AddFRMRotatingParticle(LYS, 1, 1);
-  AddFRMRotatingParticle(LYS, 1, 2);
-  AddFRMRotatingParticle(LYS, 1, 3);
-  AddFRMRotatingParticle(LYS, 1, 4);
-  AddFRMRotatingParticle(LYS, 1, 5);
-  AddFRMRotatingParticle(LYS, 1, 6);
-
-  AddFRMRule(LYS, promod3::loop::LYS_CG_INDEX, promod3::loop::LYS_CD_INDEX);
-  AddFRMPrefactor(LYS, 2, -0.96);
-  AddFRMPrefactor(LYS, 2, 0.96);
-  AddFRMFixParticle(LYS, 2, 0);
-  AddFRMFixParticle(LYS, 2, 1);
-  AddFRMRotatingParticle(LYS, 2, 2);
-  AddFRMRotatingParticle(LYS, 2, 3);
-  AddFRMRotatingParticle(LYS, 2, 4);
-  AddFRMRotatingParticle(LYS, 2, 5);
-  AddFRMRotatingParticle(LYS, 2, 6);
-
-  AddFRMRule(LYS, promod3::loop::LYS_CD_INDEX, promod3::loop::LYS_CE_INDEX);
-  AddFRMPrefactor(LYS, 3, -1.49);
-  AddFRMPrefactor(LYS, 3, 1.49);
-  AddFRMFixParticle(LYS, 3, 0);
-  AddFRMFixParticle(LYS, 3, 1);
-  AddFRMFixParticle(LYS, 3, 2);
-  AddFRMRotatingParticle(LYS, 3, 3);
-  AddFRMRotatingParticle(LYS, 3, 4);
-  AddFRMRotatingParticle(LYS, 3, 5);
-  AddFRMRotatingParticle(LYS, 3, 6);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(LYS, 0, 7);
-    AddFRMFixParticle(LYS, 1, 7);
-    AddFRMFixParticle(LYS, 2, 7);
-    AddFRMFixParticle(LYS, 3, 7);
-  }
-
-  backbone_infos_[LYS].has_hydrogens = true;
-  AddBBInfo(LYS, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(LYS, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(LYS, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(LYS, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(LYS, HParticle, 0.25, "H", promod3::loop::LYS_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(LYS, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(LYS, promod3::loop::LYS_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(LYS, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // SER
-  sidechain_infos_[SER].has_hydrogens = true;
-  sidechain_infos_[SER].internal_e_prefactor = 2.78;
-  sidechain_infos_[SER].frm_t = 3.53;
-
-  AddInfo(SER, OParticle, -0.65, "OG", promod3::loop::SER_OG_INDEX, false);
-  AddInfo(SER, HParticle, 0.40, "HG", promod3::loop::SER_HG_INDEX, true);
-
-  if(cb_in_sidechain) {
-    AddInfo(SER, CH2Particle, 0.25, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddPDir(SER, promod3::loop::SER_HG_INDEX, promod3::loop::SER_OG_INDEX, 1);
-  AddLP(SER, promod3::loop::BB_CB_INDEX, promod3::loop::SER_OG_INDEX, 
-        promod3::loop::SER_HG_INDEX, false, false, true, 0, LONE_PAIR_COH);
-  AddCustomHydrogenInfo(SER, promod3::loop::SER_HG_INDEX, 
-                        promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX, 
-                        promod3::loop::SER_OG_INDEX,
-                        0.96, 1.85, 1);
-
-  AddFRMRule(SER, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(SER, 0, -0.65);
-  AddFRMPrefactor(SER, 0, 0.65);
-  AddFRMRotatingParticle(SER, 0, 0);
-  AddFRMRotatingParticle(SER, 0, 1);
-
-  AddFRMRule(SER, promod3::loop::BB_CB_INDEX, promod3::loop::SER_OG_INDEX);
-  AddFRMPrefactor(SER, 1, -2.98);
-  AddFRMPrefactor(SER, 1, 2.98);
-  AddFRMFixParticle(SER, 1, 0);
-  AddFRMRotatingParticle(SER, 1, 1);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(SER, 0, 2);
-    AddFRMFixParticle(SER, 1, 2);
-  }
-
-  backbone_infos_[SER].has_hydrogens = true;
-  AddBBInfo(SER, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(SER, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(SER, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(SER, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(SER, HParticle, 0.25, "H", promod3::loop::SER_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(SER, CH2Particle, 0.25, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(SER, promod3::loop::SER_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(SER, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // CYS
-  sidechain_infos_[CYS].has_hydrogens = false;
-  sidechain_infos_[CYS].internal_e_prefactor = 4.07;
-  sidechain_infos_[CYS].frm_t = 1.69;
-
-  AddInfo(CYS, SParticle, -0.19, "SG", promod3::loop::CYS_SG_INDEX, false);
-
-  if(cb_in_sidechain) {
-    AddInfo(CYS, CH2Particle, 0.19, "CB", promod3::loop::BB_CB_INDEX, false);  
-  }
-
-  AddFRMRule(CYS, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(CYS, 0, -1.69);
-  AddFRMPrefactor(CYS, 0, 1.69);
-  AddFRMRotatingParticle(CYS, 0, 0);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(CYS, 0, 1);
-  }
-
-  backbone_infos_[CYS].has_hydrogens = true;
-  AddBBInfo(CYS, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(CYS, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(CYS, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(CYS, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(CYS, HParticle, 0.25, "H", promod3::loop::CYS_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(CYS, CH2Particle, 0.19, "CB", promod3::loop::BB_CB_INDEX, false);   
-  }
-
-  AddBBPDir(CYS, promod3::loop::CYS_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(CYS, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // CYH
-  sidechain_infos_[CYH] = sidechain_infos_[CYS];
-  frm_rules_[CYH] = frm_rules_[CYS];
-  backbone_infos_[CYH] = backbone_infos_[CYS];
-
-  // CYD
-  sidechain_infos_[CYD] = sidechain_infos_[CYS];
-  frm_rules_[CYD] = frm_rules_[CYS];
-  backbone_infos_[CYD] = backbone_infos_[CYS];
-
-  // MET
-  sidechain_infos_[MET].has_hydrogens = false;
-  sidechain_infos_[MET].internal_e_prefactor = 1.95;
-  sidechain_infos_[MET].frm_t = 1.77;
-
-  AddInfo(MET, CH2Particle, 0.06, "CG", promod3::loop::MET_CG_INDEX,false);
-  AddInfo(MET, SParticle, -0.12, "SD", promod3::loop::MET_SD_INDEX,false);
-  AddInfo(MET, CH3Particle, 0.06, "CE", promod3::loop::MET_CE_INDEX,false);
-
-  if(cb_in_sidechain) {
-    AddInfo(MET, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddFRMRule(MET, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(MET, 0, -0.97);
-  AddFRMPrefactor(MET, 0, 0.97);
-  AddFRMRotatingParticle(MET, 0, 0);
-  AddFRMRotatingParticle(MET, 0, 1);
-  AddFRMRotatingParticle(MET, 0, 2);
-
-  AddFRMRule(MET, promod3::loop::BB_CB_INDEX, promod3::loop::MET_CG_INDEX);
-  AddFRMPrefactor(MET, 1, -1.54);
-  AddFRMPrefactor(MET, 1, 1.54);
-  AddFRMFixParticle(MET, 1, 0);
-  AddFRMRotatingParticle(MET, 1, 1);
-  AddFRMRotatingParticle(MET, 1, 2);
-
-  AddFRMRule(MET, promod3::loop::MET_CG_INDEX, promod3::loop::MET_SD_INDEX);
-  AddFRMPrefactor(MET, 2, -1.21);
-  AddFRMPrefactor(MET, 2, 1.21);
-  AddFRMFixParticle(MET, 2, 0);
-  AddFRMFixParticle(MET, 2, 1);
-  AddFRMRotatingParticle(MET, 2, 2);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(MET, 0, 3);
-    AddFRMFixParticle(MET, 1, 3);
-    AddFRMFixParticle(MET, 2, 3);
-  }
-
-  backbone_infos_[MET].has_hydrogens = true;
-  AddBBInfo(MET, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(MET, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(MET, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(MET, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(MET, HParticle, 0.25, "H", promod3::loop::MET_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(MET, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(MET, promod3::loop::MET_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(MET, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // TRP
-  sidechain_infos_[TRP].has_hydrogens = true;
-  sidechain_infos_[TRP].internal_e_prefactor = 3.24;
-  sidechain_infos_[TRP].frm_t = 0.99;
-
-  AddInfo(TRP, CParticle,-0.03, "CG", promod3::loop::TRP_CG_INDEX,false);
-  AddInfo(TRP, CParticle, 0.06, "CD1", promod3::loop::TRP_CD1_INDEX,false);
-  AddInfo(TRP, CParticle, 0.10, "CD2", promod3::loop::TRP_CD2_INDEX,false);
-  AddInfo(TRP, CParticle, -0.04, "CE2", promod3::loop::TRP_CE2_INDEX,false);
-  AddInfo(TRP, NParticle, -0.36, "NE1", promod3::loop::TRP_NE1_INDEX,false);
-  AddInfo(TRP, CParticle, -0.03, "CE3", promod3::loop::TRP_CE3_INDEX,false);
-  AddInfo(TRP, CParticle, 0.00, "CZ3", promod3::loop::TRP_CZ3_INDEX,false);
-  AddInfo(TRP, CParticle, 0.00, "CH2", promod3::loop::TRP_CH2_INDEX,false);
-  AddInfo(TRP, CParticle, 0.00, "CZ2", promod3::loop::TRP_CZ2_INDEX,false);
-  AddInfo(TRP, HParticle, 0.30, "HE1", promod3::loop::TRP_HE1_INDEX,true);
-
-  if(cb_in_sidechain) {
-    AddInfo(TRP, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddPDir(TRP, promod3::loop::TRP_HE1_INDEX, promod3::loop::TRP_NE1_INDEX, 9);
-
-  AddFRMRule(TRP, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(TRP, 0, -1.28);
-  AddFRMPrefactor(TRP, 0, 1.28);
-  AddFRMRotatingParticle(TRP, 0, 0);
-  AddFRMRotatingParticle(TRP, 0, 1);
-  AddFRMRotatingParticle(TRP, 0, 2);
-  AddFRMRotatingParticle(TRP, 0, 3);
-  AddFRMRotatingParticle(TRP, 0, 4);
-  AddFRMRotatingParticle(TRP, 0, 5);
-  AddFRMRotatingParticle(TRP, 0, 6);
-  AddFRMRotatingParticle(TRP, 0, 7);
-  AddFRMRotatingParticle(TRP, 0, 8);
-  AddFRMRotatingParticle(TRP, 0, 9);
-
-  AddFRMRule(TRP, promod3::loop::BB_CB_INDEX, promod3::loop::TRP_CG_INDEX);
-  AddFRMPrefactor(TRP, 1, -1.48);
-  AddFRMPrefactor(TRP, 1, 1.48);
-  AddFRMFixParticle(TRP, 1, 0);
-  AddFRMRotatingParticle(TRP, 1, 1);
-  AddFRMRotatingParticle(TRP, 1, 2);
-  AddFRMRotatingParticle(TRP, 1, 3);
-  AddFRMRotatingParticle(TRP, 1, 4);
-  AddFRMRotatingParticle(TRP, 1, 5);
-  AddFRMRotatingParticle(TRP, 1, 6);
-  AddFRMRotatingParticle(TRP, 1, 7);
-  AddFRMRotatingParticle(TRP, 1, 8);
-  AddFRMRotatingParticle(TRP, 1, 9);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(TRP, 0, 10);
-    AddFRMFixParticle(TRP, 1, 10);
-  }
-
-  backbone_infos_[TRP].has_hydrogens = true;
-  AddBBInfo(TRP, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(TRP, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(TRP, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(TRP, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(TRP, HParticle, 0.25, "H", promod3::loop::TRP_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(TRP, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(TRP, promod3::loop::TRP_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(TRP, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // TYR
-  sidechain_infos_[TYR].has_hydrogens = true;
-  sidechain_infos_[TYR].internal_e_prefactor = 2.00;
-  sidechain_infos_[TYR].frm_t = 1.96;
-
-  AddInfo(TYR, CParticle, 0.0, "CG", promod3::loop::TYR_CG_INDEX,false);
-  AddInfo(TYR, CParticle, 0.0, "CD1", promod3::loop::TYR_CD1_INDEX,false);
-  AddInfo(TYR, CParticle, 0.0, "CD2", promod3::loop::TYR_CD2_INDEX,false);
-  AddInfo(TYR, CParticle, 0.0, "CE1", promod3::loop::TYR_CE1_INDEX,false);
-  AddInfo(TYR, CParticle, 0.0, "CE2", promod3::loop::TYR_CE2_INDEX,false);
-  AddInfo(TYR, CParticle, 0.25, "CZ", promod3::loop::TYR_CZ_INDEX,false);
-  AddInfo(TYR, OParticle, -0.65, "OH", promod3::loop::TYR_OH_INDEX,false);
-  AddInfo(TYR, HParticle, 0.40, "HH", promod3::loop::TYR_HH_INDEX,true);
-
-  if(cb_in_sidechain) {
-    AddInfo(TYR, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddPDir(TYR, promod3::loop::TYR_HH_INDEX, promod3::loop::TYR_OH_INDEX, 7);
-  AddLP(TYR, promod3::loop::TYR_CZ_INDEX, promod3::loop::TYR_OH_INDEX, 
-        promod3::loop::TYR_HH_INDEX, false, false, true, 6, LONE_PAIR_COH);
-  AddCustomHydrogenInfo(TYR, promod3::loop::TYR_HH_INDEX, 
-                        promod3::loop::TYR_CE1_INDEX, 
-                        promod3::loop::TYR_CZ_INDEX, 
-                        promod3::loop::TYR_OH_INDEX,
-                        0.96, 1.885, 2);
-
-  AddFRMRule(TYR, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(TYR, 0, -1.48);
-  AddFRMPrefactor(TYR, 0, 1.48);
-  AddFRMRotatingParticle(TYR, 0, 0);
-  AddFRMRotatingParticle(TYR, 0, 1);
-  AddFRMRotatingParticle(TYR, 0, 2);
-  AddFRMRotatingParticle(TYR, 0, 3);
-  AddFRMRotatingParticle(TYR, 0, 4);
-  AddFRMRotatingParticle(TYR, 0, 5);
-  AddFRMRotatingParticle(TYR, 0, 6);
-  AddFRMRotatingParticle(TYR, 0, 7);
-
-  AddFRMRule(TYR, promod3::loop::BB_CB_INDEX, promod3::loop::TYR_CG_INDEX);
-  AddFRMPrefactor(TYR, 1, -0.73);
-  AddFRMPrefactor(TYR, 1, 0.73);
-  AddFRMFixParticle(TYR, 1, 0);
-  AddFRMRotatingParticle(TYR, 1, 1);
-  AddFRMRotatingParticle(TYR, 1, 2);
-  AddFRMRotatingParticle(TYR, 1, 3);
-  AddFRMRotatingParticle(TYR, 1, 4);
-  AddFRMRotatingParticle(TYR, 1, 5);
-  AddFRMRotatingParticle(TYR, 1, 6);
-  AddFRMRotatingParticle(TYR, 1, 7);
-
-  AddFRMRule(TYR, promod3::loop::TYR_CZ_INDEX, promod3::loop::TYR_OH_INDEX);
-  AddFRMPrefactor(TYR, 2, -0.96);
-  AddFRMPrefactor(TYR, 2, 0.96);
-  AddFRMFixParticle(TYR, 2, 0);
-  AddFRMFixParticle(TYR, 2, 1);
-  AddFRMFixParticle(TYR, 2, 2);
-  AddFRMFixParticle(TYR, 2, 3);
-  AddFRMFixParticle(TYR, 2, 4);
-  AddFRMFixParticle(TYR, 2, 5);
-  AddFRMFixParticle(TYR, 2, 6);
-  AddFRMRotatingParticle(TYR, 2, 7);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(TYR, 0, 8);
-    AddFRMFixParticle(TYR, 1, 8);
-    AddFRMFixParticle(TYR, 2, 8);
-  }
-
-  backbone_infos_[TYR].has_hydrogens = true;
-  AddBBInfo(TYR, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(TYR, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(TYR, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(TYR, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(TYR, HParticle, 0.25, "H", promod3::loop::TYR_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(TYR, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(TYR, promod3::loop::TYR_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(TYR, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // THR
-  sidechain_infos_[THR].has_hydrogens = true;
-  sidechain_infos_[THR].internal_e_prefactor = 2.96;
-  sidechain_infos_[THR].frm_t = 1.11;
-
-  AddInfo(THR, OParticle, -0.65, "OG1", promod3::loop::THR_OG1_INDEX, false);
-  AddInfo(THR, CH3Particle, 0.0, "CG2", promod3::loop::THR_CG2_INDEX, false);
-  AddInfo(THR, HParticle, 0.40, "HG1", promod3::loop::THR_HG1_INDEX, true);
-
-  if(cb_in_sidechain) {
-    AddInfo(THR, CH2Particle, 0.25, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddPDir(THR, promod3::loop::THR_HG1_INDEX, promod3::loop::THR_OG1_INDEX, 2);
-  AddLP(THR, promod3::loop::BB_CB_INDEX, promod3::loop::THR_OG1_INDEX, 
-        promod3::loop::THR_HG1_INDEX, false, false, true, 0, LONE_PAIR_COH);
-  AddCustomHydrogenInfo(THR, promod3::loop::THR_HG1_INDEX, 
-                        promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX, 
-                        promod3::loop::THR_OG1_INDEX,
-                        0.96, 1.85, 1);
-
-  AddFRMRule(THR, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(THR, 0, -0.88);
-  AddFRMPrefactor(THR, 0, 0.88);
-  AddFRMRotatingParticle(THR, 0, 0);
-  AddFRMRotatingParticle(THR, 0, 1);
-  AddFRMRotatingParticle(THR, 0, 2);
-
-  AddFRMRule(THR, promod3::loop::BB_CB_INDEX, promod3::loop::THR_OG1_INDEX);
-  AddFRMPrefactor(THR, 1, -0.88);
-  AddFRMPrefactor(THR, 1, 0.88);
-  AddFRMFixParticle(THR, 1, 0);
-  AddFRMFixParticle(THR, 1, 1);
-  AddFRMRotatingParticle(THR, 1, 2);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(THR, 0, 3);
-    AddFRMFixParticle(THR, 1, 3);
-  }
-
-  backbone_infos_[THR].has_hydrogens = true;
-  AddBBInfo(THR, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(THR, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(THR, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(THR, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(THR, HParticle, 0.25, "H", promod3::loop::THR_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(THR, CH2Particle, 0.25, "CB", promod3::loop::BB_CB_INDEX, false); 
-  }
-
-  AddBBPDir(THR, promod3::loop::THR_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(THR, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // VAL
-  sidechain_infos_[VAL].has_hydrogens = false;
-  sidechain_infos_[VAL].internal_e_prefactor = 1.62;
-  sidechain_infos_[VAL].frm_t = 2.20;
-
-  AddInfo(VAL, CH3Particle, 0.0, "CG1", promod3::loop::VAL_CG1_INDEX, false);
-  AddInfo(VAL, CH3Particle, 0.0, "CG2", promod3::loop::VAL_CG2_INDEX, false);
-
-  if(cb_in_sidechain) {
-    AddInfo(VAL, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddFRMRule(VAL, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(VAL, 0, -2.09);
-  AddFRMPrefactor(VAL, 0, 2.09);
-  AddFRMRotatingParticle(VAL, 0, 0);
-  AddFRMRotatingParticle(VAL, 0, 1);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(VAL, 0, 2);
-  }
-
-  backbone_infos_[VAL].has_hydrogens = true;
-  AddBBInfo(VAL, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(VAL, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(VAL, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(VAL, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(VAL, HParticle, 0.25, "H", promod3::loop::VAL_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(VAL, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false); 
-  }
-
-  AddBBPDir(VAL, promod3::loop::VAL_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(VAL, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // ILE
-  sidechain_infos_[ILE].has_hydrogens = false;
-  sidechain_infos_[ILE].internal_e_prefactor = 2.18;
-  sidechain_infos_[ILE].frm_t = 2.03;
-
-  AddInfo(ILE, CH2Particle, 0.0, "CG1", promod3::loop::ILE_CG1_INDEX, false);
-  AddInfo(ILE, CH3Particle, 0.0, "CG2", promod3::loop::ILE_CG2_INDEX, false);  
-  AddInfo(ILE, CH3Particle, 0.0, "CD1", promod3::loop::ILE_CD1_INDEX, false);  
-
-  if(cb_in_sidechain) {
-    AddInfo(ILE, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddFRMRule(ILE, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(ILE, 0, -1.23);
-  AddFRMPrefactor(ILE, 0, 1.23);
-  AddFRMRotatingParticle(ILE, 0, 0);
-  AddFRMRotatingParticle(ILE, 0, 1);
-  AddFRMRotatingParticle(ILE, 0, 2);
-
-  AddFRMRule(ILE, promod3::loop::BB_CB_INDEX, promod3::loop::ILE_CG1_INDEX);
-  AddFRMPrefactor(ILE, 1, -0.98);
-  AddFRMPrefactor(ILE, 1, 0.98);
-  AddFRMFixParticle(ILE, 1, 0);
-  AddFRMFixParticle(ILE, 1, 1);
-  AddFRMRotatingParticle(ILE, 1, 2);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(ILE, 0, 3);
-    AddFRMFixParticle(ILE, 1, 3);
-  }
-
-  backbone_infos_[ILE].has_hydrogens = true;
-  AddBBInfo(ILE, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(ILE, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(ILE, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(ILE, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(ILE, HParticle, 0.25, "H", promod3::loop::ILE_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(ILE, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(ILE, promod3::loop::ILE_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(ILE, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // LEU
-  sidechain_infos_[LEU].has_hydrogens = false;
-  sidechain_infos_[LEU].internal_e_prefactor = 2.25;
-  sidechain_infos_[LEU].frm_t = 2.55;
-  
-  AddInfo(LEU, CH1Particle, 0.0, "CG", promod3::loop::LEU_CG_INDEX, false);
-  AddInfo(LEU, CH3Particle, 0.0, "CD1", promod3::loop::LEU_CD1_INDEX, false);  
-  AddInfo(LEU, CH3Particle, 0.0, "CD2", promod3::loop::LEU_CD2_INDEX, false);  
-
-  if(cb_in_sidechain) {
-    AddInfo(LEU, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-  
-  AddFRMRule(LEU, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(LEU, 0, -1.15);
-  AddFRMPrefactor(LEU, 0, 1.15);
-  AddFRMRotatingParticle(LEU, 0, 0);
-  AddFRMRotatingParticle(LEU, 0, 1);
-  AddFRMRotatingParticle(LEU, 0, 2);
-
-  AddFRMRule(LEU, promod3::loop::BB_CB_INDEX, promod3::loop::LEU_CG_INDEX);
-  AddFRMPrefactor(LEU, 1, -1.48);
-  AddFRMPrefactor(LEU, 1, 1.48);
-  AddFRMFixParticle(LEU, 1, 0);  
-  AddFRMRotatingParticle(LEU, 1, 1);
-  AddFRMRotatingParticle(LEU, 1, 2);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(LEU, 0, 3);
-    AddFRMFixParticle(LEU, 1, 3);
-  }
-
-  backbone_infos_[LEU].has_hydrogens = true;
-  AddBBInfo(LEU, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(LEU, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(LEU, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(LEU, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(LEU, HParticle, 0.25, "H", promod3::loop::LEU_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(LEU, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(LEU, promod3::loop::LEU_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(LEU, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // PROLINES DO NOT HAVE FRM DEFINITIONS!
-  // large scale benchmarks showed, that varying around chi angles in case
-  // of prolines has a negative effect on performance => reduce to one single
-  // subrotamer...
-
-  // PRO
-  sidechain_infos_[PRO].has_hydrogens = false;
-  sidechain_infos_[PRO].internal_e_prefactor = 0.76;
-  sidechain_infos_[PRO].frm_t = 2.62;
-  
-  AddInfo(PRO, CH2Particle, 0.0, "CG", promod3::loop::PRO_CG_INDEX, false);
-  AddInfo(PRO, CH2Particle, 0.0, "CD", promod3::loop::PRO_CD_INDEX, false); 
-
-  if(cb_in_sidechain) {
-    AddInfo(PRO, CH2Particle, 0.25, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  backbone_infos_[PRO].has_hydrogens = false;
-  AddBBInfo(PRO, NParticle, -0.20, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(PRO, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(PRO, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(PRO, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(PRO, CH2Particle, 0.25, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBLP(PRO, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // CPR
-  sidechain_infos_[CPR] = sidechain_infos_[PRO]; 
-  frm_rules_[CPR] = frm_rules_[PRO];
-  backbone_infos_[CPR] = backbone_infos_[PRO];
-
-  // TPR
-  sidechain_infos_[TPR] = sidechain_infos_[PRO];
-  frm_rules_[TPR] = frm_rules_[PRO];
-  backbone_infos_[TPR] = backbone_infos_[PRO];
-
-  // HSD
-  sidechain_infos_[HSD].has_hydrogens = true;
-  sidechain_infos_[HSD].internal_e_prefactor = 2.01;
-  sidechain_infos_[HSD].frm_t = 1.35;
-
-  AddInfo(HSD, CParticle, 0.10, "CG", promod3::loop::HIS_CG_INDEX,false);
-  AddInfo(HSD, NParticle, -0.40, "ND1", promod3::loop::HIS_ND1_INDEX,false);
-  AddInfo(HSD, CParticle, 0.10, "CD2", promod3::loop::HIS_CD2_INDEX,false);
-  AddInfo(HSD, CParticle, 0.30, "CE1", promod3::loop::HIS_CE1_INDEX,false);
-  AddInfo(HSD, NParticle, -0.40, "NE2", promod3::loop::HIS_NE2_INDEX,false);
-  AddInfo(HSD, HParticle, 0.30, "HD1", promod3::loop::HIS_HD1_INDEX,true);
-
-  if(cb_in_sidechain) {
-    AddInfo(HSD, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddPDir(HSD, promod3::loop::HIS_HD1_INDEX, promod3::loop::HIS_ND1_INDEX, 5);
-  AddLP(HSD, promod3::loop::HIS_CD2_INDEX, promod3::loop::HIS_NE2_INDEX, 
-        promod3::loop::HIS_CE1_INDEX, false, false, false, 4, LONE_PAIR_CNC);
-
-
-  AddFRMRule(HSD, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(HSD, 0, -1.84);
-  AddFRMPrefactor(HSD, 0, 1.84);
-  AddFRMRotatingParticle(HSD, 0, 0);
-  AddFRMRotatingParticle(HSD, 0, 1);
-  AddFRMRotatingParticle(HSD, 0, 2);
-  AddFRMRotatingParticle(HSD, 0, 3);
-  AddFRMRotatingParticle(HSD, 0, 4);
-  AddFRMRotatingParticle(HSD, 0, 5);
-
-  AddFRMRule(HSD, promod3::loop::BB_CB_INDEX, promod3::loop::HIS_CG_INDEX);
-  AddFRMPrefactor(HSD, 1, -0.85);
-  AddFRMPrefactor(HSD, 1, 0.85);
-  AddFRMFixParticle(HSD, 1, 0);
-  AddFRMRotatingParticle(HSD, 1, 1);
-  AddFRMRotatingParticle(HSD, 1, 2);
-  AddFRMRotatingParticle(HSD, 1, 3);
-  AddFRMRotatingParticle(HSD, 1, 4);
-  AddFRMRotatingParticle(HSD, 1, 5);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(HSD, 0, 6);
-    AddFRMFixParticle(HSD, 1, 6);
-  }
-
-  backbone_infos_[HSD].has_hydrogens = true;
-  AddBBInfo(HSD, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(HSD, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(HSD, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(HSD, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(HSD, HParticle, 0.25, "H", promod3::loop::HIS_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddInfo(HSD, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddBBPDir(HSD, promod3::loop::HIS_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(HSD, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // HSE
-  sidechain_infos_[HSE].has_hydrogens = true;
-  sidechain_infos_[HSE].internal_e_prefactor = 2.01;
-  sidechain_infos_[HSE].frm_t = 1.35;
-  
-  AddInfo(HSE, CParticle, 0.10, "CG", promod3::loop::HIS_CG_INDEX,false);
-  AddInfo(HSE, NParticle, -0.40, "ND1", promod3::loop::HIS_ND1_INDEX,false);
-  AddInfo(HSE, CParticle, 0.10, "CD2", promod3::loop::HIS_CD2_INDEX,false);
-  AddInfo(HSE, CParticle, 0.30, "CE1", promod3::loop::HIS_CE1_INDEX,false);
-  AddInfo(HSE, NParticle, -0.40, "NE2", promod3::loop::HIS_NE2_INDEX,false);
-  AddInfo(HSE, HParticle, 0.30, "HE2", promod3::loop::HIS_HE2_INDEX,true);
-  
-  if(cb_in_sidechain) {
-    AddInfo(HSE, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddPDir(HSE, promod3::loop::HIS_HE2_INDEX, promod3::loop::HIS_NE2_INDEX, 5);
-  AddLP(HSE, promod3::loop::HIS_CG_INDEX, promod3::loop::HIS_ND1_INDEX, 
-        promod3::loop::HIS_CE1_INDEX, false, false, false, 1, LONE_PAIR_CNC);
-
-  AddFRMRule(HSE, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(HSE, 0, -1.84);
-  AddFRMPrefactor(HSE, 0, 1.84);
-  AddFRMRotatingParticle(HSE, 0, 0);
-  AddFRMRotatingParticle(HSE, 0, 1);
-  AddFRMRotatingParticle(HSE, 0, 2);
-  AddFRMRotatingParticle(HSE, 0, 3);
-  AddFRMRotatingParticle(HSE, 0, 4);
-  AddFRMRotatingParticle(HSE, 0, 5);
-
-  AddFRMRule(HSE, promod3::loop::BB_CB_INDEX, promod3::loop::HIS_CG_INDEX);
-  AddFRMPrefactor(HSE, 1, -0.85);
-  AddFRMPrefactor(HSE, 1, 0.85);
-  AddFRMFixParticle(HSE, 1, 0);
-  AddFRMRotatingParticle(HSE, 1, 1);
-  AddFRMRotatingParticle(HSE, 1, 2);
-  AddFRMRotatingParticle(HSE, 1, 3);
-  AddFRMRotatingParticle(HSE, 1, 4);
-  AddFRMRotatingParticle(HSE, 1, 5);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(HSE, 0, 6);
-    AddFRMFixParticle(HSE, 1, 6);
-  }
-
-  backbone_infos_[HSE].has_hydrogens = true;
-  AddBBInfo(HSE, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(HSE, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(HSE, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(HSE, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(HSE, HParticle, 0.25, "H", promod3::loop::HIS_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(HSE, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
 
-  AddBBPDir(HSE, promod3::loop::HIS_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(HSE, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // HIS
-  // this is a bit hacky...
-  sidechain_infos_[HIS] = sidechain_infos_[HSD];
-  frm_rules_[HIS] = frm_rules_[HSD];
-  backbone_infos_[HIS] = backbone_infos_[HSD];
-
-  // PHE
-  sidechain_infos_[PHE].has_hydrogens = false;
-  sidechain_infos_[PHE].internal_e_prefactor = 1.71;
-  sidechain_infos_[PHE].frm_t = 1.07;
-  
-  AddInfo(PHE, CParticle, 0.0, "CG", promod3::loop::PHE_CG_INDEX, false);
-  AddInfo(PHE, CParticle, 0.0, "CD1", promod3::loop::PHE_CD1_INDEX, false);  
-  AddInfo(PHE, CParticle, 0.0, "CD2", promod3::loop::PHE_CD2_INDEX, false); 
-  AddInfo(PHE, CParticle, 0.0, "CE1", promod3::loop::PHE_CE1_INDEX, false);  
-  AddInfo(PHE, CParticle, 0.0, "CE2", promod3::loop::PHE_CE2_INDEX, false); 
-  AddInfo(PHE, CParticle, 0.0, "CZ", promod3::loop::PHE_CZ_INDEX, false); 
-
-  if(cb_in_sidechain) {
-    AddInfo(PHE, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  AddFRMRule(PHE, promod3::loop::BB_CA_INDEX, promod3::loop::BB_CB_INDEX);
-  AddFRMPrefactor(PHE, 0, -1.45);
-  AddFRMPrefactor(PHE, 0, 1.45);
-  AddFRMRotatingParticle(PHE, 0, 0);
-  AddFRMRotatingParticle(PHE, 0, 1);
-  AddFRMRotatingParticle(PHE, 0, 2);
-  AddFRMRotatingParticle(PHE, 0, 3);
-  AddFRMRotatingParticle(PHE, 0, 4);
-  AddFRMRotatingParticle(PHE, 0, 5);
-
-  AddFRMRule(PHE, promod3::loop::BB_CB_INDEX, promod3::loop::PHE_CG_INDEX);
-  AddFRMPrefactor(PHE, 1, -1.35);
-  AddFRMPrefactor(PHE, 1, 1.35);
-  AddFRMFixParticle(PHE, 1, 0);
-  AddFRMRotatingParticle(PHE, 1, 1);
-  AddFRMRotatingParticle(PHE, 1, 2);
-  AddFRMRotatingParticle(PHE, 1, 3);
-  AddFRMRotatingParticle(PHE, 1, 4);
-  AddFRMRotatingParticle(PHE, 1, 5);
-
-  if(cb_in_sidechain) {
-    AddFRMFixParticle(PHE, 0, 6);
-    AddFRMFixParticle(PHE, 1, 6);
-  }
-
-  backbone_infos_[PHE].has_hydrogens = true;
-  AddBBInfo(PHE, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(PHE, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(PHE, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(PHE, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(PHE, HParticle, 0.25, "H", promod3::loop::PHE_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(PHE, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false); 
-  }
-
-  AddBBPDir(PHE, promod3::loop::PHE_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(PHE, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // ALA
-  sidechain_infos_[ALA].has_hydrogens = false;
-  sidechain_infos_[ALA].internal_e_prefactor = 1.0;
-  sidechain_infos_[ALA].frm_t = 1.0;
-
-  if(cb_in_sidechain) {
-    AddInfo(ALA, CH3Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
-  }
-
-  backbone_infos_[ALA].has_hydrogens = true;
-  AddBBInfo(ALA, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(ALA, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(ALA, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(ALA, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(ALA, HParticle, 0.25, "H", promod3::loop::ALA_H_INDEX,true);
-
-  if(!cb_in_sidechain) {
-    AddBBInfo(ALA, CH3Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false); 
-  }
-
-  AddBBPDir(ALA, promod3::loop::ALA_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(ALA, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  // GLY
-  sidechain_infos_[GLY].has_hydrogens = false;
-  sidechain_infos_[GLY].internal_e_prefactor = 1.0;
-  sidechain_infos_[GLY].frm_t = 1.0;
-  
-  backbone_infos_[GLY].has_hydrogens = true;
-  AddBBInfo(GLY, NParticle, -0.35, "N", promod3::loop::BB_N_INDEX, false);
-  AddBBInfo(GLY, CH1Particle, 0.1, "CA", promod3::loop::BB_CA_INDEX, false);
-  AddBBInfo(GLY, CParticle, 0.55, "C", promod3::loop::BB_C_INDEX, false);
-  AddBBInfo(GLY, OParticle, -0.55, "O", promod3::loop::BB_O_INDEX, false);
-  AddBBInfo(GLY, HParticle, 0.25, "H", promod3::loop::GLY_H_INDEX,true);
-  AddBBPDir(GLY, promod3::loop::GLY_H_INDEX, promod3::loop::BB_N_INDEX, 4);
-  AddBBLP(GLY, promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
-          promod3::loop::BB_O_INDEX, false, false, false, 3, LONE_PAIR_CARBONYL);
-
-  for(uint i = 0; i <= XXX; ++i){
-    num_sidechain_particles_[i] = sidechain_infos_[i].particles.size();
-    num_backbone_particles_[i] = backbone_infos_[i].particles.size();
-    num_frm_particles_[i] = num_sidechain_particles_[i];
-    for(uint j = 0; j < frm_rules_[i].size(); ++j){
-      num_frm_particles_[i] += (frm_rules_[i][j].prefactors.size() * 
-                                frm_rules_[i][j].rotating_particles.size());
+struct SCWRL4RotamerParam : public RotamerLookupParam {
+
+  SCWRL4RotamerParam() {
+
+    // overwrite default FRM prefactors from base class
+    ARG_CA_CB_prefactors[0] = -0.87;
+    ARG_CB_CG_prefactors[0] = -1.62;
+    ARG_CG_CD_prefactors[0] = -1.67;
+    ARG_CD_NE_prefactors[0] = -0.73;
+    ASN_CA_CB_prefactors[0] = -0.62;
+    ASN_CB_CG_prefactors[0] = -1.93;
+    ASP_CA_CB_prefactors[0] = -1.59;
+    ASP_CB_CG_prefactors[0] = -0.63;
+    GLN_CA_CB_prefactors[0] = -1.55;
+    GLN_CB_CG_prefactors[0] = -0.53;
+    GLN_CG_CD_prefactors[0] = -1.89;
+    GLU_CA_CB_prefactors[0] = -0.82;
+    GLU_CB_CG_prefactors[0] = -1.57;
+    GLU_CG_CD_prefactors[0] = -0.76;
+    LYS_CA_CB_prefactors[0] = -1.62;
+    LYS_CB_CG_prefactors[0] = -0.99;
+    LYS_CG_CD_prefactors[0] = -0.96;
+    LYS_CD_CE_prefactors[0] = -1.49;
+    SER_CA_CB_prefactors[0] = -0.65;
+    SER_CB_OG_prefactors[0] = -2.98;
+    CYS_CA_CB_prefactors[0] = -1.69;  
+    MET_CA_CB_prefactors[0] = -0.97;
+    MET_CB_CG_prefactors[0] = -1.54;
+    MET_CG_SD_prefactors[0] = -1.21;
+    TRP_CA_CB_prefactors[0] = -1.28;
+    TRP_CB_CG_prefactors[0] = -1.48;
+    TYR_CA_CB_prefactors[0] = -1.48;
+    TYR_CB_CG_prefactors[0] = -0.73;
+    TYR_CZ_OH_prefactors[0] = -0.96;
+    THR_CA_CB_prefactors[0] = -0.88;
+    THR_CB_OG1_prefactors[0] = -0.88;
+    VAL_CA_CB_prefactors[0] = -2.09;
+    ILE_CA_CB_prefactors[0] = -1.23;
+    ILE_CB_CG1_prefactors[0] = -0.98;
+    LEU_CA_CB_prefactors[0] = -1.15;
+    LEU_CB_CG_prefactors[0] = -1.48;
+    HIS_CA_CB_prefactors[0] = -1.84;
+    HIS_CB_CG_prefactors[0] = -0.85;
+    PHE_CA_CB_prefactors[0] = -1.45;
+    PHE_CB_CG_prefactors[0] = -1.35;
+
+    ARG_CA_CB_prefactors[1] = 0.87;
+    ARG_CB_CG_prefactors[1] = 1.62;
+    ARG_CG_CD_prefactors[1] = 1.67;
+    ARG_CD_NE_prefactors[1] = 0.73;
+    ASN_CA_CB_prefactors[1] = 0.62;
+    ASN_CB_CG_prefactors[1] = 1.93;
+    ASP_CA_CB_prefactors[1] = 1.59;
+    ASP_CB_CG_prefactors[1] = 0.63;
+    GLN_CA_CB_prefactors[1] = 1.55;
+    GLN_CB_CG_prefactors[1] = 0.53;
+    GLN_CG_CD_prefactors[1] = 1.89;
+    GLU_CA_CB_prefactors[1] = 0.82;
+    GLU_CB_CG_prefactors[1] = 1.57;
+    GLU_CG_CD_prefactors[1] = 0.76;
+    LYS_CA_CB_prefactors[1] = 1.62;
+    LYS_CB_CG_prefactors[1] = 0.99;
+    LYS_CG_CD_prefactors[1] = 0.96;
+    LYS_CD_CE_prefactors[1] = 1.49;
+    SER_CA_CB_prefactors[1] = 0.65;
+    SER_CB_OG_prefactors[1] = 2.98;
+    CYS_CA_CB_prefactors[1] = 1.69;  
+    MET_CA_CB_prefactors[1] = 0.97;
+    MET_CB_CG_prefactors[1] = 1.54;
+    MET_CG_SD_prefactors[1] = 1.21;
+    TRP_CA_CB_prefactors[1] = 1.28;
+    TRP_CB_CG_prefactors[1] = 1.48;
+    TYR_CA_CB_prefactors[1] = 1.48;
+    TYR_CB_CG_prefactors[1] = 0.73;
+    TYR_CZ_OH_prefactors[1] = 0.96;
+    THR_CA_CB_prefactors[1] = 0.88;
+    THR_CB_OG1_prefactors[1] = 0.88;
+    VAL_CA_CB_prefactors[1] = 2.09;
+    ILE_CA_CB_prefactors[1] = 1.23;
+    ILE_CB_CG1_prefactors[1] = 0.98;
+    LEU_CA_CB_prefactors[1] = 1.15;
+    LEU_CB_CG_prefactors[1] = 1.48;
+    HIS_CA_CB_prefactors[1] = 1.84;
+    HIS_CB_CG_prefactors[1] = 0.85;
+    PHE_CA_CB_prefactors[1] = 1.45;
+    PHE_CB_CG_prefactors[1] = 1.35;
+
+    // overwrite default frm_t from base class
+    frm_t[ost::conop::ARG] = 1.23;
+    frm_t[ost::conop::ASN] = 1.41;
+    frm_t[ost::conop::ASP] = 1.48;
+    frm_t[ost::conop::GLN] = 1.32;
+    frm_t[ost::conop::GLU] = 0.94;
+    frm_t[ost::conop::LYS] = 1.27;
+    frm_t[ost::conop::SER] = 3.53;
+    frm_t[ost::conop::CYS] = 1.69;
+    frm_t[ost::conop::MET] = 1.77;
+    frm_t[ost::conop::TRP] = 0.99;
+    frm_t[ost::conop::TYR] = 1.96;
+    frm_t[ost::conop::THR] = 1.11;
+    frm_t[ost::conop::VAL] = 2.20;
+    frm_t[ost::conop::ILE] = 2.03;
+    frm_t[ost::conop::LEU] = 2.55;
+    frm_t[ost::conop::PRO] = 2.62;
+    frm_t[ost::conop::HIS] = 1.35;
+    frm_t[ost::conop::PHE] = 1.07;
+
+    // overwrite default internal_e_prefactor from base class
+    internal_e_prefactor[ost::conop::ARG] = 2.27;
+    internal_e_prefactor[ost::conop::ASN] = 1.80;
+    internal_e_prefactor[ost::conop::ASP] = 2.44;
+    internal_e_prefactor[ost::conop::GLN] = 1.61;
+    internal_e_prefactor[ost::conop::GLU] = 1.85;
+    internal_e_prefactor[ost::conop::LYS] = 2.13;
+    internal_e_prefactor[ost::conop::SER] = 2.78;
+    internal_e_prefactor[ost::conop::CYS] = 4.07;
+    internal_e_prefactor[ost::conop::MET] = 1.95;
+    internal_e_prefactor[ost::conop::TRP] = 3.24;
+    internal_e_prefactor[ost::conop::TYR] = 2.00;
+    internal_e_prefactor[ost::conop::THR] = 2.96;
+    internal_e_prefactor[ost::conop::VAL] = 1.62;
+    internal_e_prefactor[ost::conop::ILE] = 2.18;
+    internal_e_prefactor[ost::conop::LEU] = 2.25;
+    internal_e_prefactor[ost::conop::PRO] = 0.76;
+    internal_e_prefactor[ost::conop::HIS] = 2.01;
+    internal_e_prefactor[ost::conop::PHE] = 1.71;
+
+    // set all parameters specific to SCWRL4RotamerParam to default values
+    for(uint i = 0 ; i < promod3::loop::XXX_NUM_HYDROGENS; ++i) {
+      hydrogen_charges_[i] = 0.0;
+      polar_anchor_[i] = -1;
     }
-  }
-}
 
-SCWRL4RotamerConstructor::SCWRL4RotamerConstructor(bool cb_in_sidechain): 
-                                rotamer_lookup_(cb_in_sidechain) {
-  hydrogen_buffer_ = boost::make_shared<promod3::loop::HydrogenStorage>();
-}
-
-
-FrameResiduePtr SCWRL4RotamerConstructor::ConstructBackboneFrameResidue(
-          const ost::mol::ResidueHandle& res, RotamerID id, uint residue_index,
-          Real phi, bool n_ter, bool c_ter) {
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::ConstructBackboneFrameResidue", 2);
-
-  if(id == XXX) {
-    throw promod3::Error("Cannot construct FrameResidue for unknown "
-                         "rotamer id!");
-  }
-
-  const SCWRLRotamerInfo& info = rotamer_lookup_.GetBackboneInfo(id);
-
-  for(uint i = 0; i < info.particles.size(); ++i){
-    if(!info.particles[i].is_hydrogen){
-      ost::mol::AtomHandle a = res.FindAtom(info.particles[i].name);
-      if(!a.IsValid()){
-        throw promod3::Error("Expected atom " + info.particles[i].name + 
-                             " to be present in input residue!");
-      }
-      pos_buffer_->SetPos(id, info.particles[i].atom_idx, a.GetPos());
+    for(uint i = 0; i < promod3::loop::XXX_NUM_ATOMS; ++i) {
+      heavy_atom_charges_[i] = 0.0;
+      lone_pair_info_idx_[i] = -1;
     }
-  }
 
-  //set bb hydrogen
-  if(info.has_hydrogens){
-    promod3::loop::ConstructHydrogenN(*pos_buffer_, id, phi, *hydrogen_buffer_); 
-  }
-
-  int num_particles = info.particles.size();
-  if(n_ter) num_particles += 2;
-  if(c_ter) num_particles += 1;
-  std::vector<Particle> particles(num_particles);
-  this->ConstructBBFrameParticles(info, id, n_ter, c_ter, particles);
-
-  FrameResiduePtr p = boost::make_shared<FrameResidue>(particles, 
-                                                       residue_index);
-
-  return p;
-}
-
-FrameResiduePtr SCWRL4RotamerConstructor::ConstructBackboneFrameResidue(
-          const promod3::loop::AllAtomPositions& all_atom, uint aa_res_idx, 
-          RotamerID id, uint residue_index,
-          Real phi, bool n_ter, bool c_ter) {
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::ConstructBackboneFrameResidue", 2);
-
-  if(id == XXX) {
-    throw promod3::Error("Cannot construct FrameResidue for unknown "
-                         "rotamer id!");
-  }
-
-  const SCWRLRotamerInfo& info = rotamer_lookup_.GetBackboneInfo(id);
-
-  for(uint i = 0; i < info.particles.size(); ++i){
-    if(!info.particles[i].is_hydrogen){
-
-      if(!all_atom.IsSet(aa_res_idx, info.particles[i].atom_idx)){
-        throw promod3::Error("Expected atom " + info.particles[i].name +
-                             " to be set in all_atom");
+    // set anchor indices for all polar hydrogens
+    polar_anchor_[promod3::loop::ALA_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ALA_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ALA_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ALA_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ARG_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ARG_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ARG_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ARG_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ASN_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ASN_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ASN_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ASN_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ASP_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ASP_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ASP_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ASP_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLN_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLN_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLN_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLN_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLU_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLU_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLU_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLU_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::LYS_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::LYS_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::LYS_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::LYS_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::SER_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::SER_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::SER_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::SER_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::CYS_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::CYS_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::CYS_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::CYS_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::MET_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::MET_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::MET_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::MET_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::TRP_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::TRP_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::TRP_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::TRP_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::TYR_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::TYR_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::TYR_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::TYR_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::THR_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::THR_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::THR_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::THR_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::VAL_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::VAL_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::VAL_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::VAL_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ILE_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ILE_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ILE_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::ILE_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::LEU_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::LEU_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::LEU_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::LEU_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLY_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLY_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLY_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::GLY_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::PRO_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::PRO_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::HIS_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::HIS_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::HIS_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::HIS_H3] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::PHE_H] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::PHE_H1] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::PHE_H2] = promod3::loop::BB_N_INDEX;
+    polar_anchor_[promod3::loop::PHE_H3] = promod3::loop::BB_N_INDEX;
+    
+    polar_anchor_[promod3::loop::ARG_HE] = promod3::loop::ARG_NE_INDEX;
+    polar_anchor_[promod3::loop::ARG_HH11] = promod3::loop::ARG_NH1_INDEX; 
+    polar_anchor_[promod3::loop::ARG_HH12] = promod3::loop::ARG_NH1_INDEX; 
+    polar_anchor_[promod3::loop::ARG_HH21] = promod3::loop::ARG_NH2_INDEX; 
+    polar_anchor_[promod3::loop::ARG_HH22] = promod3::loop::ARG_NH2_INDEX; 
+    polar_anchor_[promod3::loop::ASN_HD21] = promod3::loop::ASN_ND2_INDEX;
+    polar_anchor_[promod3::loop::ASN_HD22] = promod3::loop::ASN_ND2_INDEX;
+    polar_anchor_[promod3::loop::GLN_HE21] = promod3::loop::GLN_NE2_INDEX;
+    polar_anchor_[promod3::loop::GLN_HE22] = promod3::loop::GLN_NE2_INDEX;
+    polar_anchor_[promod3::loop::LYS_HZ1] = promod3::loop::LYS_NZ_INDEX;
+    polar_anchor_[promod3::loop::LYS_HZ2] = promod3::loop::LYS_NZ_INDEX;
+    polar_anchor_[promod3::loop::LYS_HZ3] = promod3::loop::LYS_NZ_INDEX;
+    polar_anchor_[promod3::loop::SER_HG] = promod3::loop::SER_OG_INDEX;
+    polar_anchor_[promod3::loop::TRP_HE1] = promod3::loop::TRP_NE1_INDEX;
+    polar_anchor_[promod3::loop::TYR_HH] = promod3::loop::TYR_OH_INDEX;
+    polar_anchor_[promod3::loop::THR_HG1] = promod3::loop::THR_OG1_INDEX;
+    polar_anchor_[promod3::loop::HIS_HD1] = promod3::loop::HIS_ND1_INDEX;
+    polar_anchor_[promod3::loop::HIS_HE2] = promod3::loop::HIS_NE2_INDEX;
+
+    // set lone pair infos 
+    // Special care has to be taken for the terminal oxygen and
+    // histidine
+    int o_lp_idx = AddLP(promod3::loop::BB_CA_INDEX, promod3::loop::BB_C_INDEX, 
+                         promod3::loop::BB_O_INDEX, false, false, false, 
+                         LONE_PAIR_CARBONYL);
+    lone_pair_info_idx_[promod3::loop::ALA_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::ARG_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::ASN_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::ASP_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::GLN_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::GLU_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::LYS_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::SER_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::CYS_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::MET_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::TRP_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::TYR_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::THR_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::VAL_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::ILE_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::LEU_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::GLY_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::PRO_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::HIS_O] = o_lp_idx;
+    lone_pair_info_idx_[promod3::loop::PHE_O] = o_lp_idx;
+
+    AddLP(ASN, promod3::loop::ASN_OD1_INDEX,
+          promod3::loop::ASN_ND2_INDEX, promod3::loop::ASN_CG_INDEX, 
+          promod3::loop::ASN_OD1_INDEX, false, false, false, LONE_PAIR_CARBONYL);
+
+    AddLP(ASP, promod3::loop::ASP_OD1_INDEX,
+          promod3::loop::ASP_OD2_INDEX, promod3::loop::ASP_CG_INDEX, 
+          promod3::loop::ASP_OD1_INDEX, false, false, false, LONE_PAIR_CARBONYL);
+
+    AddLP(ASP, promod3::loop::ASP_OD2_INDEX,
+          promod3::loop::ASP_OD1_INDEX, promod3::loop::ASP_CG_INDEX, 
+          promod3::loop::ASP_OD2_INDEX, false, false, false, LONE_PAIR_CARBONYL);
+
+    AddLP(GLN, promod3::loop::GLN_OE1_INDEX,
+          promod3::loop::GLN_NE2_INDEX, promod3::loop::GLN_CD_INDEX, 
+          promod3::loop::GLN_OE1_INDEX, false, false, false, LONE_PAIR_CARBONYL);
+
+    AddLP(GLU, promod3::loop::GLU_OE1_INDEX,
+          promod3::loop::GLU_OE2_INDEX, promod3::loop::GLU_CD_INDEX, 
+          promod3::loop::GLU_OE1_INDEX, false, false, false, LONE_PAIR_CARBONYL);
+
+    AddLP(GLU, promod3::loop::GLU_OE2_INDEX,
+          promod3::loop::GLU_OE1_INDEX, promod3::loop::GLU_CD_INDEX, 
+          promod3::loop::GLU_OE2_INDEX, false, false, false, LONE_PAIR_CARBONYL);
+
+    AddLP(SER, promod3::loop::SER_OG_INDEX,
+          promod3::loop::BB_CB_INDEX, promod3::loop::SER_OG_INDEX, 
+          promod3::loop::SER_HG_INDEX, false, false, true, LONE_PAIR_COH);
+
+    AddLP(TYR, promod3::loop::TYR_OH_INDEX,
+          promod3::loop::TYR_CZ_INDEX, promod3::loop::TYR_OH_INDEX, 
+          promod3::loop::TYR_HH_INDEX, false, false, true, LONE_PAIR_COH);
+
+    AddLP(THR, promod3::loop::THR_OG1_INDEX,
+          promod3::loop::BB_CB_INDEX, promod3::loop::THR_OG1_INDEX, 
+          promod3::loop::THR_HG1_INDEX, false, false, true, LONE_PAIR_COH);
+
+    AddLP(HIS, promod3::loop::HIS_NE2_INDEX,
+          promod3::loop::HIS_CD2_INDEX, promod3::loop::HIS_NE2_INDEX, 
+          promod3::loop::HIS_CE1_INDEX, false, false, false, LONE_PAIR_CNC);
+
+    AddLP(HIS, promod3::loop::HIS_ND1_INDEX,
+          promod3::loop::HIS_CG_INDEX, promod3::loop::HIS_ND1_INDEX, 
+          promod3::loop::HIS_CE1_INDEX, false, false, false, LONE_PAIR_CNC);
+
+    // set charges for polar hydrogen
+    hydrogen_charges_[promod3::loop::ALA_H] = 0.25;
+    hydrogen_charges_[promod3::loop::ALA_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::ALA_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::ALA_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::ARG_H] = 0.25;
+    hydrogen_charges_[promod3::loop::ARG_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::ARG_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::ARG_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::ASN_H] = 0.25;
+    hydrogen_charges_[promod3::loop::ASN_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::ASN_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::ASN_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::ASP_H] = 0.25;
+    hydrogen_charges_[promod3::loop::ASP_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::ASP_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::ASP_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::GLN_H] = 0.25;
+    hydrogen_charges_[promod3::loop::GLN_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::GLN_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::GLN_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::GLU_H] = 0.25;
+    hydrogen_charges_[promod3::loop::GLU_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::GLU_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::GLU_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::LYS_H] = 0.25;
+    hydrogen_charges_[promod3::loop::LYS_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::LYS_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::LYS_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::SER_H] = 0.25;
+    hydrogen_charges_[promod3::loop::SER_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::SER_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::SER_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::CYS_H] = 0.25;
+    hydrogen_charges_[promod3::loop::CYS_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::CYS_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::CYS_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::MET_H] = 0.25;
+    hydrogen_charges_[promod3::loop::MET_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::MET_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::MET_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::TRP_H] = 0.25;
+    hydrogen_charges_[promod3::loop::TRP_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::TRP_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::TRP_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::TYR_H] = 0.25;
+    hydrogen_charges_[promod3::loop::TYR_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::TYR_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::TYR_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::THR_H] = 0.25;
+    hydrogen_charges_[promod3::loop::THR_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::THR_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::THR_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::VAL_H] = 0.25;
+    hydrogen_charges_[promod3::loop::VAL_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::VAL_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::VAL_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::ILE_H] = 0.25;
+    hydrogen_charges_[promod3::loop::ILE_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::ILE_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::ILE_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::LEU_H] = 0.25;
+    hydrogen_charges_[promod3::loop::LEU_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::LEU_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::LEU_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::GLY_H] = 0.25;
+    hydrogen_charges_[promod3::loop::GLY_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::GLY_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::GLY_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::PRO_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::PRO_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::HIS_H] = 0.25;
+    hydrogen_charges_[promod3::loop::HIS_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::HIS_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::HIS_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::PHE_H] = 0.25;
+    hydrogen_charges_[promod3::loop::PHE_H1] = 0.35;
+    hydrogen_charges_[promod3::loop::PHE_H2] = 0.35;
+    hydrogen_charges_[promod3::loop::PHE_H3] = 0.35;
+    hydrogen_charges_[promod3::loop::ARG_HE] = 0.3;
+    hydrogen_charges_[promod3::loop::ARG_HH11] = 0.35;
+    hydrogen_charges_[promod3::loop::ARG_HH12] = 0.35;
+    hydrogen_charges_[promod3::loop::ARG_HH21] = 0.35;
+    hydrogen_charges_[promod3::loop::ARG_HH22] = 0.35;
+    hydrogen_charges_[promod3::loop::ASN_HD21] = 0.3;
+    hydrogen_charges_[promod3::loop::ASN_HD22] = 0.3;
+    hydrogen_charges_[promod3::loop::GLN_HE21] = 0.3;
+    hydrogen_charges_[promod3::loop::GLN_HE22] = 0.3;
+    hydrogen_charges_[promod3::loop::LYS_HZ1] = 0.35;
+    hydrogen_charges_[promod3::loop::LYS_HZ2] = 0.35;
+    hydrogen_charges_[promod3::loop::LYS_HZ3] = 0.35;
+    hydrogen_charges_[promod3::loop::SER_HG] = 0.40;
+    hydrogen_charges_[promod3::loop::TRP_HE1] = 0.30;
+    hydrogen_charges_[promod3::loop::TYR_HH] = 0.40;
+    hydrogen_charges_[promod3::loop::THR_HG1] = 0.40;
+    hydrogen_charges_[promod3::loop::HIS_HD1] = 0.30;
+    hydrogen_charges_[promod3::loop::HIS_HE2] = 0.30;
+
+    // set charges for hydrogen bond acceptors
+    heavy_atom_charges_[promod3::loop::ALA_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::ARG_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::ASN_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::ASP_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::GLN_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::GLU_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::LYS_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::SER_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::CYS_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::MET_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::TRP_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::TYR_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::THR_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::VAL_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::ILE_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::LEU_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::GLY_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::PRO_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::HIS_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::PHE_O] = -0.55;
+    heavy_atom_charges_[promod3::loop::ASN_OD1] = -0.55;
+    heavy_atom_charges_[promod3::loop::ASP_OD1] = -0.60;
+    heavy_atom_charges_[promod3::loop::ASP_OD2] = -0.60;
+    heavy_atom_charges_[promod3::loop::GLN_OE1] = -0.55;
+    heavy_atom_charges_[promod3::loop::GLU_OE1] = -0.60;
+    heavy_atom_charges_[promod3::loop::GLU_OE2] = -0.60;
+    heavy_atom_charges_[promod3::loop::SER_OG] = -0.65;
+    heavy_atom_charges_[promod3::loop::TYR_OH] = -0.65;
+    heavy_atom_charges_[promod3::loop::THR_OG1] = -0.65;
+    heavy_atom_charges_[promod3::loop::HIS_NE2] = -0.40;
+    heavy_atom_charges_[promod3::loop::HIS_ND1] = -0.40;
+
+    // set most common atomtypes by element
+    for(int i = 0; i < promod3::loop::XXX_NUM_ATOMS; ++i) {
+      particle_types_[i] = CParticle;
+      promod3::loop::AminoAcidAtom aaa = promod3::loop::AminoAcidAtom(i);
+      const String& ele = 
+      promod3::loop::AminoAcidLookup::GetInstance().GetElement(aaa);
+      if(ele == "N") {
+        particle_types_[i] = NParticle;
       }
-
-      pos_buffer_->SetPos(id, info.particles[i].atom_idx, 
-                          all_atom.GetPos(aa_res_idx, info.particles[i].atom_idx));
-    }
-  }
-
-  //set hydrogens
-  if(info.has_hydrogens){
-    promod3::loop::ConstructHydrogenN(*pos_buffer_, id, phi, *hydrogen_buffer_); 
-  }
-
-  int num_particles = info.particles.size();
-  if(n_ter) num_particles += 2;
-  if(c_ter) num_particles += 1;
-  std::vector<Particle> particles(num_particles);
-  this->ConstructBBFrameParticles(info, id, n_ter, c_ter, particles);
-
-  FrameResiduePtr p = boost::make_shared<FrameResidue>(particles, 
-                                                       residue_index);
-
-  return p; 
-}
-
-FrameResiduePtr SCWRL4RotamerConstructor::ConstructSidechainFrameResidue(
-        const ost::mol::ResidueHandle& res, RotamerID id, uint residue_index) {
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::ConstructSidechainFrameResidue", 2);
-
-  if(id == XXX) {
-    throw promod3::Error("Cannot construct FrameResidue for unknown "
-                         "rotamer id!");
-  }
-
-  const SCWRLRotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id);
-
-  for(uint i = 0; i < info.particles.size(); ++i){
-    if(!info.particles[i].is_hydrogen){
-      ost::mol::AtomHandle a = res.FindAtom(info.particles[i].name);
-      if(!a.IsValid()){
-        throw promod3::Error("Expected atom " + info.particles[i].name + 
-                             " to be present in input residue!");
+      if(ele == "O") {
+        particle_types_[i] = OParticle;
+      }
+      if(ele == "S") {
+        particle_types_[i] = SParticle;
       }
-      pos_buffer_->SetPos(id, info.particles[i].atom_idx, a.GetPos());
     }
-  }
 
-  //set bb hydrogen
-  if(info.has_hydrogens){
-    // to construct hydrogens, we might also need backbone atoms in the buffer
-    const SCWRLRotamerInfo& bb_info = rotamer_lookup_.GetBackboneInfo(id);
-
-    for(uint i = 0; i < bb_info.particles.size(); ++i){
-      if(!bb_info.particles[i].is_hydrogen){
-        ost::mol::AtomHandle a = res.FindAtom(bb_info.particles[i].name);
-        if(!a.IsValid()){
-          throw promod3::Error("Expected atom " + bb_info.particles[i].name + 
-                               " to be present in input residue!");
-        }
-        pos_buffer_->SetPos(id, bb_info.particles[i].atom_idx, a.GetPos());
-      }
+    // atoms of following types must be set manually:
+    // CH1Particle, CH2Particle, CH3Particle, OCParticle
+    particle_types_[promod3::loop::ARG_CG] = CH2Particle;
+    particle_types_[promod3::loop::ARG_CD] = CH2Particle;
+    particle_types_[promod3::loop::ARG_CB] = CH2Particle;
+    particle_types_[promod3::loop::ARG_CA] = CH1Particle;
+    particle_types_[promod3::loop::ASN_CB] = CH2Particle;
+    particle_types_[promod3::loop::ASN_CA] = CH1Particle;
+    particle_types_[promod3::loop::ASP_CB] = CH2Particle;
+    particle_types_[promod3::loop::ASP_CA] = CH1Particle;
+    particle_types_[promod3::loop::GLN_CG] = CH2Particle;
+    particle_types_[promod3::loop::GLN_CB] = CH2Particle;
+    particle_types_[promod3::loop::GLN_CA] = CH1Particle;
+    particle_types_[promod3::loop::GLU_CG] = CH2Particle;
+    particle_types_[promod3::loop::GLU_CB] = CH2Particle;
+    particle_types_[promod3::loop::GLU_CA] = CH1Particle;
+    particle_types_[promod3::loop::LYS_CG] = CH2Particle;
+    particle_types_[promod3::loop::LYS_CD] = CH2Particle;
+    particle_types_[promod3::loop::LYS_CE] = CH2Particle;
+    particle_types_[promod3::loop::LYS_CB] = CH2Particle;
+    particle_types_[promod3::loop::LYS_CA] = CH1Particle;
+    particle_types_[promod3::loop::SER_CB] = CH2Particle;
+    particle_types_[promod3::loop::SER_CA] = CH1Particle;
+    particle_types_[promod3::loop::CYS_CB] = CH2Particle;
+    particle_types_[promod3::loop::CYS_CA] = CH1Particle;
+    particle_types_[promod3::loop::MET_CG] = CH2Particle;
+    particle_types_[promod3::loop::MET_CE] = CH3Particle;
+    particle_types_[promod3::loop::MET_CB] = CH2Particle;
+    particle_types_[promod3::loop::MET_CA] = CH1Particle;
+    particle_types_[promod3::loop::TRP_CB] = CH2Particle;
+    particle_types_[promod3::loop::TRP_CA] = CH1Particle;
+    particle_types_[promod3::loop::TYR_CB] = CH2Particle;
+    particle_types_[promod3::loop::TYR_CA] = CH1Particle;
+    particle_types_[promod3::loop::THR_CG2] = CH3Particle;
+    particle_types_[promod3::loop::THR_CB] = CH2Particle;
+    particle_types_[promod3::loop::THR_CA] = CH1Particle;
+    particle_types_[promod3::loop::VAL_CG1] = CH3Particle;
+    particle_types_[promod3::loop::VAL_CG2] = CH3Particle;
+    particle_types_[promod3::loop::VAL_CB] = CH2Particle;
+    particle_types_[promod3::loop::VAL_CA] = CH1Particle;
+    particle_types_[promod3::loop::ILE_CG1] = CH2Particle;
+    particle_types_[promod3::loop::ILE_CG2] = CH3Particle;
+    particle_types_[promod3::loop::ILE_CD1] = CH3Particle;
+    particle_types_[promod3::loop::ILE_CB] = CH2Particle;
+    particle_types_[promod3::loop::ILE_CA] = CH1Particle;
+    particle_types_[promod3::loop::LEU_CG] = CH1Particle;
+    particle_types_[promod3::loop::LEU_CD1] = CH3Particle;
+    particle_types_[promod3::loop::LEU_CD2] = CH3Particle;
+    particle_types_[promod3::loop::LEU_CB] = CH2Particle;
+    particle_types_[promod3::loop::LEU_CA] = CH1Particle;
+    particle_types_[promod3::loop::PRO_CG] = CH2Particle;
+    particle_types_[promod3::loop::PRO_CD] = CH2Particle;
+    particle_types_[promod3::loop::PRO_CB] = CH2Particle;
+    particle_types_[promod3::loop::PRO_CA] = CH1Particle;
+    particle_types_[promod3::loop::HIS_CB] = CH2Particle;
+    particle_types_[promod3::loop::HIS_CA] = CH1Particle;
+    particle_types_[promod3::loop::PHE_CB] = CH2Particle;
+    particle_types_[promod3::loop::PHE_CA] = CH1Particle;
+    particle_types_[promod3::loop::ALA_CB] = CH3Particle;
+    particle_types_[promod3::loop::ALA_CA] = CH1Particle;
+    particle_types_[promod3::loop::GLY_CA] = CH2Particle;
+  }  
+
+
+  static const SCWRL4RotamerParam& Instance() {
+    static SCWRL4RotamerParam scwrl4_param;
+    return scwrl4_param;
+  }
+
+
+  Real GetHydrogenCharge(RotamerID rot_id, int hydrogen_idx) const{
+    ost::conop::AminoAcid aa = RotIDToAA(rot_id);
+    promod3::loop::AminoAcidHydrogen aah = 
+    promod3::loop::AminoAcidLookup::GetInstance().GetAAH(aa, hydrogen_idx);
+    return hydrogen_charges_[aah];
+  }
+
+
+  Real GetHeavyAtomCharge(RotamerID rot_id, int atom_idx) const{
+    ost::conop::AminoAcid aa = RotIDToAA(rot_id);
+    promod3::loop::AminoAcidAtom aaa = 
+    promod3::loop::AminoAcidLookup::GetInstance().GetAAA(aa, atom_idx);
+    return heavy_atom_charges_[aaa];
+  }
+
+
+  int GetPolarAnchor(RotamerID rot_id, int hydrogen_idx) const {
+    ost::conop::AminoAcid aa = RotIDToAA(rot_id);
+    promod3::loop::AminoAcidHydrogen aah = 
+    promod3::loop::AminoAcidLookup::GetInstance().GetAAH(aa, hydrogen_idx);
+    return polar_anchor_[aah];    
+  }
+
+
+  SCWRL4ParticleType GetParticleType(RotamerID rot_id, int atom_idx) const {
+    ost::conop::AminoAcid aa = RotIDToAA(rot_id);
+    promod3::loop::AminoAcidAtom aaa = 
+    promod3::loop::AminoAcidLookup::GetInstance().GetAAA(aa, atom_idx);
+    return particle_types_[aaa];
+  }
+
+
+  int GetLPInfoIdx(RotamerID rot_id, int atom_idx) const {
+
+    // this is an ugly hack for histidine... 
+    if((rot_id == HSD && atom_idx == promod3::loop::HIS_ND1_INDEX) ||
+       (rot_id == HSE && atom_idx == promod3::loop::HIS_NE2_INDEX)) {
+      return -1;
     }
 
-    promod3::loop::ConstructHydrogens(*pos_buffer_, id, *hydrogen_buffer_, true, 
-                                      promod3::loop::PROT_STATE_HISH);
+    ost::conop::AminoAcid aa = RotIDToAA(rot_id);
+    promod3::loop::AminoAcidAtom aaa = 
+    promod3::loop::AminoAcidLookup::GetInstance().GetAAA(aa, atom_idx);
+    return lone_pair_info_idx_[aaa];
   }
 
-  int num_particles = info.particles.size();
-  std::vector<Particle> particles(num_particles);
-
-  this->ConstructBaseParticles(info, id, particles);
-
-  FrameResiduePtr p = boost::make_shared<FrameResidue>(particles, 
-                                                       residue_index);
 
-  return p;
-}
-
-FrameResiduePtr SCWRL4RotamerConstructor::ConstructSidechainFrameResidue(
-          const promod3::loop::AllAtomPositions& all_atom, uint aa_res_idx, 
-          RotamerID id, uint residue_index) {
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::ConstructSidechainFrameResidue", 2);
-
-  if(id == XXX) {
-    throw promod3::Error("Cannot construct FrameResidue for unknown "
-                         "rotamer id!");
+  const SCWRL4LPInfo& GetLP(int idx) const {
+    return lone_pair_infos_[idx];
   }
 
-  const SCWRLRotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id);
 
-  for(uint i = 0; i < info.particles.size(); ++i){
-    if(!info.particles[i].is_hydrogen){
-      if(!all_atom.IsSet(aa_res_idx, info.particles[i].atom_idx)){
-        throw promod3::Error("Expected atom " + info.particles[i].name +
-                             " to be set in all_atom");
-      }
-      pos_buffer_->SetPos(id, info.particles[i].atom_idx, 
-                          all_atom.GetPos(aa_res_idx, info.particles[i].atom_idx));
-    }
+  void AddLP(RotamerID id, int p_idx, int idx_a, int idx_b, int idx_c, 
+             bool a_ih, bool b_ih, bool c_ih, SCWRL4LPRule r) {
+    ost::conop::AminoAcid aa = RotIDToAA(id);
+    promod3::loop::AminoAcidAtom aaa = 
+    promod3::loop::AminoAcidLookup::GetInstance().GetAAA(aa, p_idx);
+    lone_pair_info_idx_[aaa] = lone_pair_infos_.size();
+    SCWRL4LPInfo lp(idx_a, idx_b, idx_c, a_ih, b_ih, c_ih, r);
+    lone_pair_infos_.push_back(lp);
   }
 
-  //set hydrogens
-  if(info.has_hydrogens){
-    // to construct hydrogens, we might also need backbone atoms in the buffer
-    const SCWRLRotamerInfo& bb_info = rotamer_lookup_.GetBackboneInfo(id);
-
-    for(uint i = 0; i < bb_info.particles.size(); ++i){
-      if(!bb_info.particles[i].is_hydrogen){
-        if(!all_atom.IsSet(aa_res_idx, bb_info.particles[i].atom_idx)){
-          throw promod3::Error("Expected atom " + bb_info.particles[i].name +
-                               " to be set in all_atom");
-        }
-        pos_buffer_->SetPos(id, bb_info.particles[i].atom_idx, 
-                            all_atom.GetPos(aa_res_idx, bb_info.particles[i].atom_idx));
-      }
-    }
 
-    promod3::loop::ConstructHydrogens(*pos_buffer_, id, *hydrogen_buffer_, true, 
-                                      promod3::loop::PROT_STATE_HISH);
+  int AddLP(int idx_a, int idx_b, int idx_c, 
+            bool a_ih, bool b_ih, bool c_ih, SCWRL4LPRule r) {
+    SCWRL4LPInfo lp(idx_a, idx_b, idx_c, a_ih, b_ih, c_ih, r);
+    lone_pair_infos_.push_back(lp);
+    return lone_pair_infos_.size() - 1;
   }
+ 
 
-  int num_particles = info.particles.size();
-  std::vector<Particle> particles(num_particles);
+  Real hydrogen_charges_[promod3::loop::XXX_NUM_HYDROGENS];
+  Real heavy_atom_charges_[promod3::loop::XXX_NUM_ATOMS];
+  int polar_anchor_[promod3::loop::XXX_NUM_HYDROGENS];
+  int lone_pair_info_idx_[promod3::loop::XXX_NUM_ATOMS];
+  std::vector<SCWRL4LPInfo> lone_pair_infos_;
+  SCWRL4ParticleType particle_types_[promod3::loop::XXX_NUM_ATOMS];
+};
 
-  this->ConstructBaseParticles(info, id, particles);
 
-  FrameResiduePtr p = boost::make_shared<FrameResidue>(particles, 
-                                                       residue_index);
+SCWRL4RotamerConstructor::SCWRL4RotamerConstructor(bool cb_in_sidechain): 
+                                RotamerConstructor(cb_in_sidechain, POLAR_HYDROGEN_MODE,
+                                                   SCWRL4RotamerParam::Instance()) { }
 
-  return p; 
-}
 
 FrameResiduePtr SCWRL4RotamerConstructor::ConstructFrameResidue(
           const ost::mol::ResidueHandle& res, uint residue_index) {
@@ -1708,8 +932,11 @@ FrameResiduePtr SCWRL4RotamerConstructor::ConstructFrameResidueHeuristic(
 }
 
 
-
-void SCWRL4RotamerConstructor::AssignInternalEnergies(RRMRotamerGroupPtr group) {
+void SCWRL4RotamerConstructor::AssignInternalEnergies(RRMRotamerGroupPtr group,
+                                                      RotamerID id, 
+                                                      uint residue_index,
+                                                      Real phi, Real psi,
+                                                      bool n_ter, bool c_ter) {
 
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
           "SCWRL4RotamerConstructor::AssignInternalEnergies", 2);
@@ -1724,7 +951,12 @@ void SCWRL4RotamerConstructor::AssignInternalEnergies(RRMRotamerGroupPtr group)
   }
 }
 
-void SCWRL4RotamerConstructor::AssignInternalEnergies(FRMRotamerGroupPtr group) {
+
+void SCWRL4RotamerConstructor::AssignInternalEnergies(FRMRotamerGroupPtr group,
+                                                      RotamerID id, 
+                                                      uint residue_index,
+                                                      Real phi, Real psi,
+                                                      bool n_ter, bool c_ter) {
 
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
           "SCWRL4RotamerConstructor::AssignInternalEnergies", 2);
@@ -1739,466 +971,70 @@ void SCWRL4RotamerConstructor::AssignInternalEnergies(FRMRotamerGroupPtr group)
   }
 }
 
-// INTERNAL FUNCTIONS
-
-RRMRotamerGroupPtr SCWRL4RotamerConstructor::ConstructRRMGroup(
-          RotamerID id, uint residue_index, 
-          std::pair<RotamerLibEntry*,uint> lib_entries, 
-          Real probability_cutoff) {
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::ConstructRRMGroup", 2);
-
-  std::vector<RRMRotamerPtr> rotamers;
-  Real summed_prob = 0.0;
-
-  // in case of his, we have to move the backbone positions in the buffer
-  // to the locations defining his in the different protonation states
-  if(id == HIS){
-    MVBBPosBuffer(HIS, HSD);
-    MVBBPosBuffer(HIS, HSE);
-  }
-
-  // in case of alanine and glycine, the rotamer libraries won't have any 
-  // entries. For consistency we nevertheless construct rotamers.
-  // We simply add a fake RotamerLibEntry in this case that has
-  // no sidechain dihedrals set.
-  std::vector<RotamerLibEntry> fake_rotamers(1);
-  if(lib_entries.second == 0 && (id == ALA || id == GLY)) {
-    // we have to make sure, that the according probability really is one!
-    fake_rotamers[0].probability = 1.0;
-    lib_entries = std::make_pair(&fake_rotamers[0], 1);
-  }
-  else if(lib_entries.second == 0) {
-    throw promod3::Error("Did not find any rotamers in Rotamer Library!");
-  }
-
-  for(uint i = 0; i < lib_entries.second; ++i){
-
-    probability_ = lib_entries.first[i].probability;
-    summed_prob += probability_;
-    chi_angles_[0] = lib_entries.first[i].chi1;
-    chi_angles_[1] = lib_entries.first[i].chi2;
-    chi_angles_[2] = lib_entries.first[i].chi3;
-    chi_angles_[3] = lib_entries.first[i].chi4;
-
-    switch(id){
-      case HIS:{
-        rotamers.push_back(ConstructRRM(HSE, residue_index));
-        rotamers.push_back(ConstructRRM(HSD, residue_index));
-        break;
-      }
-      case SER:{
-        chi_angles_[1] = Real(M_PI);
-        rotamers.push_back(ConstructRRM(id, residue_index));
-        chi_angles_[1] = Real(M_PI) / 3.0;
-        rotamers.push_back(ConstructRRM(id, residue_index));
-        chi_angles_[1] = -Real(M_PI) / 3.0;
-        rotamers.push_back(ConstructRRM(id, residue_index));
-        break;
-      }
-      case THR:{
-        chi_angles_[1] = Real(M_PI);
-        rotamers.push_back(ConstructRRM(id, residue_index));
-        chi_angles_[1] = Real(M_PI) / 3.0;
-        rotamers.push_back(ConstructRRM(id, residue_index));
-        chi_angles_[1] = -Real(M_PI) / 3.0;
-        rotamers.push_back(ConstructRRM(id, residue_index)); 
-        break;       
-      }
-      case TYR:{
-        chi_angles_[2] = Real(M_PI);
-        rotamers.push_back(ConstructRRM(id, residue_index));
-        chi_angles_[2] = Real(0.0);
-        rotamers.push_back(ConstructRRM(id, residue_index));
-        break;
-      }
-      default:{
-        rotamers.push_back(ConstructRRM(id, residue_index));
-      }
-    }
-
-    if(summed_prob >= probability_cutoff && !rotamers.empty()) break;
-  } 
-  
-  RRMRotamerGroupPtr group = boost::make_shared<RRMRotamerGroup>(rotamers,
-                                                                 residue_index);
-  this->AssignInternalEnergies(group);
-  return group;
-}
-
-FRMRotamerGroupPtr SCWRL4RotamerConstructor::ConstructFRMGroup(
-          RotamerID id, uint residue_index, 
-          std::pair<RotamerLibEntry*,uint> lib_entries, 
-          Real probability_cutoff) {
 
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::ConstructFRMGroup", 2);
+void SCWRL4RotamerConstructor::ParametrizeParticle(int at_idx, 
+                                                   bool is_hydrogen, 
+                                                   Particle& particle) {
 
-  std::vector<FRMRotamerPtr> rotamers;
-  Real summed_prob = 0.0;
-
-  // in case of his, we have to move the backbone positions in the buffer
-  // to the locations defining his in the different protonation states
-  if(id == HIS){
-    MVBBPosBuffer(HIS, HSD);
-    MVBBPosBuffer(HIS, HSE);
-  }
-
-  // in case of alanine and glycine, the rotamer libraries won't have any 
-  // entries. For consistency we nevertheless construct rotamers.
-  // We simply add a fake RotamerLibEntry in this case that has
-  // no sidechain dihedrals set.
-  std::vector<RotamerLibEntry> fake_rotamers(1);
-  if(lib_entries.second == 0 && (id == ALA || id == GLY)) {
-    // we have to make sure, that the according probability really is one!
-    fake_rotamers[0].probability = 1.0;
-    lib_entries = std::make_pair(&fake_rotamers[0], 1);
-  }
-  else if(lib_entries.second == 0) {
-    throw promod3::Error("Did not find any rotamers in Rotamer Library!");
-  }
+  if(is_hydrogen) {
 
-  for(uint i = 0; i < lib_entries.second; ++i){
-    probability_ = lib_entries.first[i].probability;
-    summed_prob += probability_;
-    chi_angles_[0] = lib_entries.first[i].chi1;
-    chi_angles_[1] = lib_entries.first[i].chi2;
-    chi_angles_[2] = lib_entries.first[i].chi3;
-    chi_angles_[3] = lib_entries.first[i].chi4;
-    chi_dev_[0] = lib_entries.first[i].sig1;
-    chi_dev_[1] = lib_entries.first[i].sig2;
-    chi_dev_[2] = lib_entries.first[i].sig3;
-    chi_dev_[3] = lib_entries.first[i].sig4;
-
-    switch(id){
-      case HIS:{
-        rotamers.push_back(ConstructFRM(HSE, residue_index));
-        rotamers.push_back(ConstructFRM(HSD, residue_index));
-        break;
-      }
-      case SER:{
-        chi_dev_[1] = Real(0.17453);
-        chi_angles_[1] = Real(M_PI);
-        rotamers.push_back(ConstructFRM(id, residue_index));
-        chi_angles_[1] = Real(M_PI) / Real(3.0);
-        rotamers.push_back(ConstructFRM(id, residue_index));
-        chi_angles_[1] = -Real(M_PI) / Real(3.0);
-        rotamers.push_back(ConstructFRM(id, residue_index));
-        break;
-      }
-      case THR:{
-        chi_dev_[1] = Real(0.17453);
-        chi_angles_[1] = Real(M_PI);
-        rotamers.push_back(ConstructFRM(id, residue_index));
-        chi_angles_[1] = Real(M_PI) / Real(3.0);
-        rotamers.push_back(ConstructFRM(id, residue_index));
-        chi_angles_[1] = -Real(M_PI) / Real(3.0);
-        rotamers.push_back(ConstructFRM(id, residue_index)); 
-        break;       
-      }
-      case TYR:{
-        chi_dev_[2] = Real(0.17453);
-        chi_angles_[2] = Real(M_PI);
-        rotamers.push_back(ConstructFRM(id, residue_index));
-        chi_angles_[2] = Real(0.0);
-        rotamers.push_back(ConstructFRM(id, residue_index));
-        break;
-      }
-      default: rotamers.push_back(ConstructFRM(id, residue_index));
-    }
-
-    if(summed_prob >= probability_cutoff && !rotamers.empty()) break;
-  } 
-  
-  FRMRotamerGroupPtr group = boost::make_shared<FRMRotamerGroup>(rotamers,
-                                                                 residue_index);
-  this->AssignInternalEnergies(group);
-  return group;
-}
-
-RRMRotamerPtr SCWRL4RotamerConstructor::ConstructRRM(RotamerID id, 
-                                                    uint residue_idx) {
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::ConstructRRM", 2);
-
-  const SCWRLRotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id);
-  int num_particles = rotamer_lookup_.GetNumSidechainParticles(id);
-  std::vector<Particle> particles(num_particles);
-
-  //set the positions
-  promod3::loop::ConstructSidechainAtoms(*pos_buffer_, id, chi_angles_[0], 
-                                         chi_angles_[1], chi_angles_[2],
-                                         chi_angles_[3]);
-
-  if(info.has_hydrogens){
-
-    promod3::loop::ConstructHydrogens(*pos_buffer_, id, *hydrogen_buffer_, true, 
-                                      promod3::loop::PROT_STATE_HISH);
-
-    // If there are any custom rules, we apply them now and overrule the
-    // default hydrogen construction
-    if(!info.custom_hydrogens.empty()){
-      for(uint i = 0; i < info.custom_hydrogens.size(); ++i){
-        const SCWRLCustomHydrogenInfo& h_info = info.custom_hydrogens[i];
-        geom::Vec3 anchor_one, anchor_two, anchor_three, new_h_pos;
-        anchor_one = pos_buffer_->GetPos(id, h_info.anchor_idx_one);
-        anchor_two = pos_buffer_->GetPos(id, h_info.anchor_idx_two);
-        anchor_three = pos_buffer_->GetPos(id, h_info.anchor_idx_three);
-        promod3::core::ConstructAtomPos(anchor_one, anchor_two, anchor_three,
-                                        h_info.bond_length, h_info.angle, 
-                                        chi_angles_[h_info.chi_idx], new_h_pos);
-        hydrogen_buffer_->SetPos(h_info.atom_idx, new_h_pos);
-      }
-    }
-  }
-
-  this->ConstructBaseParticles(info, id, particles);
-
-  RRMRotamerPtr rot = boost::make_shared<RRMRotamer>(particles, 
-                                                     probability_, 
-                                                     info.internal_e_prefactor);
-
-  return rot;  
-}
-
-FRMRotamerPtr SCWRL4RotamerConstructor::ConstructFRM(RotamerID id,
-                                                    uint residue_idx) {
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::ConstructFRM", 2);
-
-  const SCWRLRotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id);
-  int num_rrm_particles = rotamer_lookup_.GetNumSidechainParticles(id);
-  int num_particles = rotamer_lookup_.GetNumFRMSidechainParticles(id);
-  std::vector<Particle> particles(num_particles);
-
-  //set the positions
-  promod3::loop::ConstructSidechainAtoms(*pos_buffer_, id, chi_angles_[0], 
-                                         chi_angles_[1], chi_angles_[2],
-                                         chi_angles_[3]);
-  if(info.has_hydrogens){
-    promod3::loop::ConstructHydrogens(*pos_buffer_, id, *hydrogen_buffer_, true, 
-                                      promod3::loop::PROT_STATE_HISH);
-    // If there are any custom rules, we apply them now an overrule the
-    // default hydrogen construction
-    if(!info.custom_hydrogens.empty()){
-      for(uint i = 0; i < info.custom_hydrogens.size(); ++i){
-        const SCWRLCustomHydrogenInfo& h_info = info.custom_hydrogens[i];
-        geom::Vec3 anchor_one, anchor_two, anchor_three, new_h_pos;
-        anchor_one = pos_buffer_->GetPos(id, h_info.anchor_idx_one);
-        anchor_two = pos_buffer_->GetPos(id, h_info.anchor_idx_two);
-        anchor_three = pos_buffer_->GetPos(id, h_info.anchor_idx_three);
-        promod3::core::ConstructAtomPos(anchor_one, anchor_two, anchor_three,
-                                        h_info.bond_length, h_info.angle, 
-                                        chi_angles_[h_info.chi_idx], new_h_pos);
-        hydrogen_buffer_->SetPos(h_info.atom_idx, new_h_pos);
-      }
+    Real charge = SCWRL4RotamerParam::Instance().GetHydrogenCharge(id_, at_idx);
+    SCWRL4Param* p = new SCWRL4Param(HParticle, 
+                                     hydrogen_buffer_->GetPos(at_idx), 
+                                     charge);
+    int polar_anchor = SCWRL4RotamerParam::Instance().GetPolarAnchor(id_, at_idx);
+    if(polar_anchor != -1) {
+      geom::Vec3 polar_direction = hydrogen_buffer_->GetPos(at_idx) - 
+                                   pos_buffer_->GetPos(id_, polar_anchor);
+      p->SetPolarDirection(polar_direction);
     }
-  }
-
-  this->ConstructBaseParticles(info, id, particles);
-
-  // Keep track of the subrotamers
-  std::vector<std::vector<int> > subrotamer_definitions;
-  std::vector<int> actual_definition;
-  actual_definition.resize(num_rrm_particles);
-  // Directly add the first particles as first subrotamer
-  for(int i = 0; i < num_rrm_particles; ++i) actual_definition[i] = i;
-  subrotamer_definitions.push_back(actual_definition);
-
-  const std::vector<SCWRLFRMRule>& frm_rules = rotamer_lookup_.GetFRMRules(id);
-  geom::Vec3 rot_axis, rot_anchor;
-  geom::Vec3 orig_pos, rot_pos;
-  geom::Mat4 transform;
-  int base_idx = num_rrm_particles;
-
-  for(uint frm_rule_idx = 0; frm_rule_idx < frm_rules.size(); ++frm_rule_idx){
-    const SCWRLFRMRule& frm_rule = frm_rules[frm_rule_idx];
-    int num_fix_particles = frm_rule.fix_particles.size();
-    int num_rotating_particles = frm_rule.rotating_particles.size();
-
-    // Update the subrotamer definition... all particles that are fixed are 
-    // taken from the first subrotamer.
-    for(int i = 0; i < num_fix_particles; ++i) {
-      actual_definition[i] = frm_rule.fix_particles[i];
-    }
-
-    // The data required for the rotation around the specified axis
-    rot_anchor = pos_buffer_->GetPos(id, frm_rule.anchor_idx_two);
-    rot_axis = rot_anchor - pos_buffer_->GetPos(id, frm_rule.anchor_idx_one); 
-
-    // Every rotation results in a new subrotamer
-    for(uint prefac_idx = 0; prefac_idx < frm_rule.prefactors.size(); 
-        ++prefac_idx){
-
-      // Get the rotation matrix
-      Real rot_angle = frm_rule.prefactors[prefac_idx] * chi_dev_[frm_rule_idx];
-      transform = promod3::core::RotationAroundLine(rot_axis, rot_anchor,
-                                                    rot_angle);
-
-      for(int i = 0; i < num_rotating_particles; ++i){
-        int orig_particle_idx = frm_rule.rotating_particles[i];
-        int new_particle_idx = base_idx + i;
-
-        // replace the old with the new index...
-        actual_definition[orig_particle_idx] = new_particle_idx;
-
-        // construct the rotated particle
-        particles[new_particle_idx] = particles[orig_particle_idx];
-        particles[new_particle_idx].ApplyTransform(transform);
-      }
-
-      subrotamer_definitions.push_back(actual_definition);
-
-      // start of next subrotamer
-      base_idx += num_rotating_particles;
-    }
-  }
-
-  FRMRotamerPtr r = boost::make_shared<FRMRotamer>(particles,
-                                                   info.frm_t, probability_,
-                                                   info.internal_e_prefactor);
-
-  for(uint i = 0; i < subrotamer_definitions.size(); ++i) {
-    r->AddSubrotamerDefinition(subrotamer_definitions[i]);
-  }
-
-  return r;
-}
-
-void SCWRL4RotamerConstructor::MVBBPosBuffer(RotamerID from, RotamerID to) {
-  pos_buffer_->SetPos(to, promod3::loop::BB_N_INDEX, 
-                      pos_buffer_->GetPos(from, promod3::loop::BB_N_INDEX));
-  pos_buffer_->SetPos(to, promod3::loop::BB_CA_INDEX, 
-                      pos_buffer_->GetPos(from, promod3::loop::BB_CA_INDEX));
-  pos_buffer_->SetPos(to, promod3::loop::BB_C_INDEX, 
-                      pos_buffer_->GetPos(from, promod3::loop::BB_C_INDEX));
-  pos_buffer_->SetPos(to, promod3::loop::BB_O_INDEX, 
-                      pos_buffer_->GetPos(from, promod3::loop::BB_O_INDEX));
-  // Even though we officially count CB as a sidechain atom, we still move it
-  // since its completely independent of any sidechain dihedral angle and
-  // cannot be constructed anyway
-  pos_buffer_->SetPos(to, promod3::loop::BB_CB_INDEX, 
-                      pos_buffer_->GetPos(from, promod3::loop::BB_CB_INDEX));
-}
-
-void SCWRL4RotamerConstructor::ConstructBaseParticles(const SCWRLRotamerInfo& info,
-                                                     RotamerID id,
-                                                     std::vector<Particle>& particles) {
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::ConstructBaseParticles", 2);
-
-  geom::Vec3 a, b, c;
-
-  // generate the particles
-  for(uint i = 0; i < info.particles.size(); ++i){
-    const SCWRLPInfo& pinfo = info.particles[i];
-    if(pinfo.is_hydrogen){
-      a = hydrogen_buffer_->GetPos(pinfo.atom_idx);
-    }
-    else a = pos_buffer_->GetPos(id, pinfo.atom_idx);
-    particles[i] = Particle(pinfo.name, new SCWRL4Param(pinfo.type, a, 
-                                                        pinfo.charge));
-  }
-
-  // set the polar directions
-  for(uint i = 0; i < info.polar_directions.size(); ++i){
-    a = hydrogen_buffer_->GetPos(info.polar_directions[i].polar_idx);
-    b = pos_buffer_->GetPos(id, info.polar_directions[i].anchor_idx);
-    PScoringParam* p = particles[info.polar_directions[i].p_idx].GetSParam();
-    reinterpret_cast<SCWRL4Param*>(p)->SetPolarDirection(a - b);
-  }
-
-  // set the lone pairs
-  for(uint i = 0; i < info.lone_pairs.size(); ++i){
-    const SCWRLLPInfo& lp = info.lone_pairs[i];
-
-    if(lp.A_is_hydrogen) a = hydrogen_buffer_->GetPos(lp.index_A);
-    else a = pos_buffer_->GetPos(id, lp.index_A);
+    particle.SetSParam(p);
+  } else {
+
+    // deal with terminal special cases
+    if(at_idx == -1) {
+      // manual setup
+      SCWRL4Param* p = new SCWRL4Param(OParticle, terminal_o_pos_,  -0.55);
+      _AddLonePairsCarbonyl(pos_buffer_->GetPos(id_, promod3::loop::BB_CA_INDEX), 
+                            pos_buffer_->GetPos(id_, promod3::loop::BB_C_INDEX), 
+                            terminal_o_pos_, p);
+      particle.SetSParam(p);
+    } else if(at_idx == -2) {
+      // manual setup
+      SCWRL4Param* p = new SCWRL4Param(OParticle, terminal_oxt_pos_,  -0.55);
+      _AddLonePairsCarbonyl(pos_buffer_->GetPos(id_, promod3::loop::BB_CA_INDEX), 
+                            pos_buffer_->GetPos(id_, promod3::loop::BB_C_INDEX), 
+                            terminal_oxt_pos_, p);
+      particle.SetSParam(p);
+    } else {
+      SCWRL4ParticleType particle_type = 
+      SCWRL4RotamerParam::Instance().GetParticleType(id_, at_idx);
+      geom::Vec3 pos = pos_buffer_->GetPos(id_, at_idx);      
+      Real charge = 
+      SCWRL4RotamerParam::Instance().GetHeavyAtomCharge(id_, at_idx);
+      SCWRL4Param* p = new SCWRL4Param(particle_type, pos, charge);
+
+      int lpi_idx = SCWRL4RotamerParam::Instance().GetLPInfoIdx(id_, at_idx);
+
+      // check whether we have a valid lone pair idx, as well as whether we're
+      // with a n_terminal nitrogen. The latter also has no lone pair
+      //if(lpi_idx != -1 && !(n_ter_ && at_idx == promod3::loop::BB_N_INDEX)) {
+      if(lpi_idx != -1) {
+        const SCWRL4LPInfo& lp = SCWRL4RotamerParam::Instance().GetLP(lpi_idx);
+        geom::Vec3 a, b, c;
+
+        if(lp.A_is_hydrogen) a = hydrogen_buffer_->GetPos(lp.index_A);
+        else a = pos_buffer_->GetPos(id_, lp.index_A);
     
-    if(lp.B_is_hydrogen) b = hydrogen_buffer_->GetPos(lp.index_B);
-    else  b = pos_buffer_->GetPos(id, lp.index_B);
+        if(lp.B_is_hydrogen) b = hydrogen_buffer_->GetPos(lp.index_B);
+        else  b = pos_buffer_->GetPos(id_, lp.index_B);
     
-    if(lp.C_is_hydrogen) c = hydrogen_buffer_->GetPos(lp.index_C);
-    else c = pos_buffer_->GetPos(id, lp.index_C);
+        if(lp.C_is_hydrogen) c = hydrogen_buffer_->GetPos(lp.index_C);
+        else c = pos_buffer_->GetPos(id_, lp.index_C);
     
-    EvalLonePairRule(reinterpret_cast<SCWRL4Param*>(particles[lp.p_idx].GetSParam()), 
-                     lp.rule, a, b, c);
-  }
-}
-
-void SCWRL4RotamerConstructor::ConstructBBFrameParticles(
-                                 const SCWRLRotamerInfo& info, RotamerID id,
-                                 bool n_ter, bool c_ter,
-                                 std::vector<Particle>& particles) {
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRL4RotamerConstructor::ConstructBBFrameParticles", 2);
-
-  ConstructBaseParticles(info, id, particles);
-  if(!(n_ter || c_ter)) return; // we're already done
-  
-  int p_idx = info.particles.size();
-
-  if(c_ter){
-    geom::Vec3 oxt_pos;
-    geom::Vec3 c_pos = pos_buffer_->GetPos(id, promod3::loop::BB_C_INDEX);
-    geom::Vec3 ca_pos = pos_buffer_->GetPos(id, promod3::loop::BB_CA_INDEX);
-    geom::Vec3 n_pos = pos_buffer_->GetPos(id, promod3::loop::BB_N_INDEX);
-    geom::Vec3 o_pos = pos_buffer_->GetPos(id, promod3::loop::BB_O_INDEX);
-    promod3::core::ConstructCTerminalOxygens(c_pos, ca_pos, n_pos,
-                                             o_pos, oxt_pos);
-    //manually add oxygen without a rule...    
-    particles[p_idx] = Particle("OT", new SCWRL4Param(OParticle, 
-                                                      oxt_pos, -0.55));
-    _AddLonePairsCarbonyl(ca_pos, c_pos, oxt_pos, 
-      reinterpret_cast<SCWRL4Param*>(particles[p_idx].GetSParam()));
-    ++p_idx;
-  }
-
-  if(n_ter){
-    geom::Vec3 ht1_pos, ht2_pos, ht3_pos;
-    geom::Vec3 n_pos, ca_pos, c_pos;
-    n_pos = pos_buffer_->GetPos(id, promod3::loop::BB_N_INDEX);
-    ca_pos = pos_buffer_->GetPos(id, promod3::loop::BB_CA_INDEX);
-    c_pos = pos_buffer_->GetPos(id, promod3::loop::BB_C_INDEX);
-    promod3::core::ConstructAtomPos(c_pos, ca_pos, n_pos, 0.997, 2.042, 
-                                    1.0472, ht1_pos);
-    promod3::core::ConstructAtomPos(c_pos,ca_pos,n_pos,0.997, 2.042, 
-                                    -1.0472, ht2_pos);
-    particles[p_idx] = Particle("HT1", new SCWRL4Param(HParticle, 
-                                                       ht1_pos, 0.35));
-    SCWRL4Param* p = reinterpret_cast<SCWRL4Param*>(particles[p_idx].GetSParam());
-    p->SetPolarDirection(ht1_pos - n_pos);
-
-    particles[p_idx + 1] = Particle("HT2", new SCWRL4Param(HParticle, 
-                                                           ht2_pos, 0.35));
-    p = reinterpret_cast<SCWRL4Param*>(particles[p_idx + 1].GetSParam());
-    p->SetPolarDirection(ht2_pos - n_pos);
-
-    if(id == PRO || id == TPR || id == CPR) {
-      // there are only two hydrogens... please note, that they are not
-      // optimally placed in case of proline. 
-      // we would have to consider CD for that. This costs a good bottle 
-      // of wine that I implement that correctly...
-      return;
-    }
-
-    promod3::core::ConstructAtomPos(c_pos, ca_pos, n_pos, 0.997, 2.042, 
-                                    M_PI, ht3_pos);
-    // we assume, that there is currently one hydrogen apart from ht1 and ht2 
-    // and replace it with ht3
-    for(uint i = 0; i < info.particles.size(); ++i){
-      if(info.particles[i].is_hydrogen){
-        particles[i] = Particle("HT3", new SCWRL4Param(HParticle, 
-                                                       ht3_pos, 0.35));
-        SCWRL4Param* p = reinterpret_cast<SCWRL4Param*>(particles[i].GetSParam());
-        p->SetPolarDirection(ht3_pos - n_pos);
-        break;
-      }
+        EvalLonePairRule(p, lp.rule, a, b, c);
+      } 
+      particle.SetSParam(p);     
     }
   }
 }
diff --git a/sidechain/src/scwrl4_rotamer_constructor.hh b/sidechain/src/scwrl4_rotamer_constructor.hh
index 887ea3c39f71690123fd5c81f0e2def69455d225..ea2bdb33816c3731b470216bc45a6994d497ae2e 100644
--- a/sidechain/src/scwrl4_rotamer_constructor.hh
+++ b/sidechain/src/scwrl4_rotamer_constructor.hh
@@ -18,235 +18,12 @@
 #define PROMOD3_SCWRL_ROTAMER_CONSTRUCTOR_HH
 
 #include <promod3/sidechain/rotamer_constructor.hh>
-#include <promod3/sidechain/scwrl4_particle_scoring.hh>
 
 namespace promod3 { namespace sidechain {
 
 class SCWRL4RotamerConstructor;
 typedef boost::shared_ptr<SCWRL4RotamerConstructor> SCWRL4RotamerConstructorPtr;
 
-/// \brief Types of lone pair construction
-enum SCWRLLPRule {
-  LONE_PAIR_CARBONYL, LONE_PAIR_COH, LONE_PAIR_CNC
-};
-
-/// \brief Info for lone pair construction (always involves 3 particles)
-/// -> indices are in same order as particles. The lone pair gets finally added
-/// to particle with p_idx
-/// A, B and C are indices as they are stored in AllAtomPositions, p_idx is the 
-/// index of the particle in the rotamer, where the lone pairs get added
-struct SCWRLLPInfo {
-  SCWRLLPInfo() { }
-  SCWRLLPInfo(int idx_A, int idx_B, int idx_C,
-              bool a_ih, bool b_ih, bool c_ih, 
-              int p, SCWRLLPRule r)
-              : index_A(idx_A), index_B(idx_B),
-                index_C(idx_C), A_is_hydrogen(a_ih),
-                B_is_hydrogen(b_ih), C_is_hydrogen(c_ih),
-                p_idx(p), rule(r) { }
-  int index_A;
-  int index_B;
-  int index_C;
-  bool A_is_hydrogen;
-  bool B_is_hydrogen;
-  bool C_is_hydrogen;
-  int p_idx;
-  SCWRLLPRule rule;
-};
-
-/// \brief Info for polar direction construction. The polar direction is 
-///        particle_pos[polar_idx] - particle_pos[anchor_idx]
-///        The direction gets finally added to the particle with p_idx
-///        polar_idx and anchor idx are indices as they are stored in
-///        AllAtomPositions, p_idx is the index of the particle in the
-///        rotamer
-struct SCWRLPDInfo {
-  SCWRLPDInfo() { }
-  SCWRLPDInfo(int pol_idx, int a_idx, int p_idx) : polar_idx(pol_idx), 
-                                                   anchor_idx(a_idx),
-                                                   p_idx(p_idx) { }
-  int polar_idx;
-  int anchor_idx;
-  int p_idx;
-};
-
-/// \brief Info for particle construction
-struct SCWRLPInfo {
-  SCWRLPInfo() { }
-  SCWRLPInfo(SCWRL4ParticleType t, Real c, 
-             const String& n, int idx, bool ih) : type(t), charge(c), 
-                                                  name(n), atom_idx(idx), 
-                                                  is_hydrogen(ih) { }
-  SCWRL4ParticleType type;
-  Real charge;
-  String name;   // PDB naming
-  int atom_idx;  // for AllAtomPositions 
-                 // (idx in HydrogenStorage if is_hydrogen is true)
-  bool is_hydrogen;
-};
-
-/// \brief Info for custom particle construction...
-///        In the example of SER / THR and TYR we construct several hydrogens
-///        looking in different directions, they do therefore not follow the
-///        default hydrogen positioning conventions. 
-///        This rule defines how to construct them by using
-///        three indices of heavy atoms, a bond length and an angle. 
-///        The dihedral is defined as an index and is set globally in
-///        SCWRL4RotamerConstructor. The default hydrogen construction
-///        gets overriden for cases defined with such a SCWRLCustomHydrogenInfo
-struct SCWRLCustomHydrogenInfo {
-  SCWRLCustomHydrogenInfo() { }
-  SCWRLCustomHydrogenInfo(int idx, int a_idx_one, int a_idx_two, int a_idx_three, 
-                          Real bl, Real a, int c_idx): atom_idx(idx),
-                                                       anchor_idx_one(a_idx_one), 
-                                                       anchor_idx_two(a_idx_two), 
-                                                       anchor_idx_three(a_idx_three), 
-                                                       bond_length(bl), angle(a),
-                                                       chi_idx(c_idx){ }
-  int atom_idx; //the idx in the hydrogen constructor
-  int anchor_idx_one; // idx in AllAtomPositions
-  int anchor_idx_two; 
-  int anchor_idx_three;
-  Real bond_length;
-  Real angle;
-  int chi_idx;
-};
-
-/// \brief Info to generate FRM rotamers
-///        The idea is to only rotate around one bond at a time.
-///        This bond gets defined by anchor_idx_one and anchor_idx_two.
-///        All particles defined in rotating_particles get then rotated by
-///        a user defined angle times the defined prefactors.
-///        (three prefactors result in three subrotamers)
-struct SCWRLFRMRule{
-  SCWRLFRMRule() { }
-  int anchor_idx_one;
-  int anchor_idx_two;
-  std::vector<Real> prefactors;
-  std::vector<int> fix_particles;
-  std::vector<int> rotating_particles;
-};
-
-/// \brief Info to construct a full rotamer. 
-struct SCWRLRotamerInfo{
-  SCWRLRotamerInfo() { }
-  std::vector<SCWRLPInfo> particles;
-  std::vector<SCWRLCustomHydrogenInfo> custom_hydrogens;
-  std::vector<SCWRLLPInfo> lone_pairs;
-  std::vector<SCWRLPDInfo> polar_directions;
-  Real internal_e_prefactor;
-  Real frm_t;
-  bool has_hydrogens;
-};
-
-/// \brief Defines lookups to build rotamer stuff.
-class SCWRLRotamerLookup {
-public:
-
-  SCWRLRotamerLookup(bool cb_in_sidechain);
-
-  // Data access
-  const SCWRLRotamerInfo& GetSidechainInfo(RotamerID id) const { 
-    return sidechain_infos_[id]; 
-  }
-
-  const SCWRLRotamerInfo& GetBackboneInfo(RotamerID id) const { 
-    return backbone_infos_[id]; 
-  }
-
-  const std::vector<SCWRLFRMRule>& GetFRMRules(RotamerID id) const { 
-    return frm_rules_[id]; 
-  }
-
-  int GetNumSidechainParticles(RotamerID id) const { 
-    return num_sidechain_particles_[id]; 
-  }
-
-  int GetNumBackboneParticles(RotamerID id) const { 
-    return num_sidechain_particles_[id]; 
-  }
-
-  int GetNumFRMSidechainParticles(RotamerID id) const { 
-    return num_frm_particles_[id]; 
-  }
-
-private:
-
-  void AddInfo(RotamerID id, SCWRL4ParticleType p_type, Real charge, 
-               const String& name, int idx, bool is_h){
-    SCWRLPInfo p(p_type, charge, name, idx, is_h);
-    sidechain_infos_[id].particles.push_back(p);
-  }
-
-  void AddCustomHydrogenInfo(RotamerID id, int idx, 
-                             int a_idx_one, int a_idx_two, int a_idx_three, 
-                             Real bl, Real a, int c_idx){
-    SCWRLCustomHydrogenInfo i(idx, a_idx_one, a_idx_two, a_idx_three, bl, 
-                              a, c_idx);
-    sidechain_infos_[id].custom_hydrogens.push_back(i);
-  }
-
-  void AddBBInfo(RotamerID id, SCWRL4ParticleType p_type, Real charge, 
-                 const String& name, int idx, bool is_h){
-    SCWRLPInfo p(p_type, charge, name, idx, is_h);
-    backbone_infos_[id].particles.push_back(p);
-  }
-
-  void AddPDir(RotamerID id, int polar_idx, int anchor_idx, int p_idx){
-    SCWRLPDInfo p(polar_idx, anchor_idx, p_idx);
-    sidechain_infos_[id].polar_directions.push_back(p);
-  }
-
-  void AddBBPDir(RotamerID id, int polar_idx, int anchor_idx, int p_idx){
-    SCWRLPDInfo p(polar_idx, anchor_idx, p_idx);
-    backbone_infos_[id].polar_directions.push_back(p);    
-  }
-
-  void AddLP(RotamerID id, int idx_a, int idx_b, int idx_c, 
-             bool a_ih, bool b_ih, bool c_ih, int p_idx, SCWRLLPRule r){
-    SCWRLLPInfo lp(idx_a, idx_b, idx_c, a_ih, b_ih, c_ih, p_idx, r);
-    sidechain_infos_[id].lone_pairs.push_back(lp);
-  }
-
-  void AddBBLP(RotamerID id, int idx_a, int idx_b, int idx_c, 
-               bool a_ih, bool b_ih, bool c_ih, int p_idx, SCWRLLPRule r){
-    SCWRLLPInfo lp(idx_a, idx_b, idx_c, a_ih, b_ih, c_ih, p_idx, r);
-    backbone_infos_[id].lone_pairs.push_back(lp);
-  }
-
-  void AddFRMRule(RotamerID id, int idx_one, int idx_two){
-    frm_rules_[id].push_back(SCWRLFRMRule());
-    frm_rules_[id].back().anchor_idx_one = idx_one;
-    frm_rules_[id].back().anchor_idx_two = idx_two;
-  }
-
-  void AddFRMPrefactor(RotamerID id, int rule_idx, Real prefactor){
-    frm_rules_[id][rule_idx].prefactors.push_back(prefactor);
-  }
-
-  void AddFRMRotatingParticle(RotamerID id, int rule_idx, int p_idx){
-    frm_rules_[id][rule_idx].rotating_particles.push_back(p_idx);
-  }
-
-  void AddFRMFixParticle(RotamerID id, int rule_idx, int p_idx){
-    frm_rules_[id][rule_idx].fix_particles.push_back(p_idx);
-  }
-
-  // To construct classical rotamers or as lookup for sidechain frame residues
-  SCWRLRotamerInfo sidechain_infos_[XXX + 1];
-
-  // To construct backbone frame residues
-  SCWRLRotamerInfo backbone_infos_[XXX + 1];
-
-  // Additional info required for generating frm rotamers
-  std::vector<SCWRLFRMRule> frm_rules_[XXX + 1];
-
-  int num_sidechain_particles_[XXX + 1];
-  int num_backbone_particles_[XXX + 1];
-  int num_frm_particles_[XXX+1];
-};
-
-
 class SCWRL4RotamerConstructor : public RotamerConstructor{
 
 public:
@@ -255,26 +32,6 @@ public:
 
   virtual ~SCWRL4RotamerConstructor() { }
 
-  // Construct frame residues
-  virtual FrameResiduePtr ConstructBackboneFrameResidue(
-          const ost::mol::ResidueHandle& res, RotamerID id, uint residue_index,
-          Real phi, bool n_ter = false,
-          bool c_ter = false);
-
-  virtual FrameResiduePtr ConstructBackboneFrameResidue(
-          const promod3::loop::AllAtomPositions& all_atom, uint aa_res_idx, 
-          RotamerID id, uint residue_index,
-          Real phi, bool n_ter = false,
-          bool c_ter = false);
-  
-  virtual FrameResiduePtr ConstructSidechainFrameResidue(
-          const ost::mol::ResidueHandle& res, RotamerID id, 
-          uint residue_index);
-  
-  virtual FrameResiduePtr ConstructSidechainFrameResidue(
-          const promod3::loop::AllAtomPositions& all_atom, uint aa_res_idx, 
-          RotamerID id, uint residue_index);
-
   FrameResiduePtr ConstructFrameResidue(const ost::mol::ResidueHandle& res,
                                         uint residue_index);
 
@@ -283,44 +40,25 @@ public:
           ost::conop::CompoundLibPtr comp_lib);
 
   // Assign internal energies to rotamer groups
-  virtual void AssignInternalEnergies(RRMRotamerGroupPtr group);
-
-  virtual void AssignInternalEnergies(FRMRotamerGroupPtr group);
+  virtual void AssignInternalEnergies(RRMRotamerGroupPtr group,
+                                      RotamerID id,
+                                      uint residue_index,
+                                      Real phi = -1.0472, 
+                                      Real psi =  -0.7854,
+                                      bool n_ter = false,
+                                      bool c_ter = false);
+
+  virtual void AssignInternalEnergies(FRMRotamerGroupPtr group,
+                                      RotamerID id,
+                                      uint residue_index,
+                                      Real phi = -1.0472, 
+                                      Real psi =  -0.7854,
+                                      bool n_ter = false,
+                                      bool c_ter = false);
 
 private:
 
-  // Construct the rotamer groups after all backbone position information has 
-  // been set into the internal positin buffer objects
-  virtual RRMRotamerGroupPtr ConstructRRMGroup(
-          RotamerID id, uint residue_index, 
-          std::pair<RotamerLibEntry*,uint> lib_entries, 
-          Real probability_cutoff);
-
-  virtual FRMRotamerGroupPtr ConstructFRMGroup(
-          RotamerID id, uint residue_index, 
-          std::pair<RotamerLibEntry*,uint> lib_entries, 
-          Real probability_cutoff);
-
-  // assumes positions / probabilities, chi angles and chi deviations 
-  // to be set in buffer
-  RRMRotamerPtr ConstructRRM(RotamerID id, uint residue_idx);
-  FRMRotamerPtr ConstructFRM(RotamerID id, uint residue_idx);
-
-  // helpers
-  void MVBBPosBuffer(RotamerID from, RotamerID to);
-
-  void ConstructBaseParticles(const SCWRLRotamerInfo& info, RotamerID id,
-                              std::vector<Particle>& particles);
-
-  void ConstructBBFrameParticles(const SCWRLRotamerInfo& info, RotamerID id,
-                                 bool n_ter, bool c_ter,
-                                 std::vector<Particle>& particles);
-
-  Real chi_angles_[4];
-  Real chi_dev_[4];
-  Real probability_;
-  SCWRLRotamerLookup rotamer_lookup_;
-  promod3::loop::HydrogenStoragePtr hydrogen_buffer_;
+  void ParametrizeParticle(int atom_idx, bool is_hydrogen, Particle& p);
 };
 
 }} // ns