From afbd3969552b8bb3a697f97741179b0e83da0b4f Mon Sep 17 00:00:00 2001
From: Gabriel Studer <gabriel.studer@unibas.ch>
Date: Sun, 17 Dec 2017 23:10:19 +0100
Subject: [PATCH] Control with a flag, whether the CB atom should be counted as
 sidechain or backbone atom

The reason for that is when you have a design application where you
want to include alaline and glycine as options at the same location.
Therefore you need the CB to be part of the sidechain. For classical
modeling applications this flag should be set to false, since a significant
increase of runtime has been observed when CB is in the sidechain.
---
 doc/tests/scripts/sidechain_steps.py          |   4 +-
 modelling/pymod/_reconstruct_sidechains.py    |  26 +-
 modelling/src/sidechain_env_listener.cc       |  55 +-
 modelling/src/sidechain_env_listener.hh       |  35 +-
 sidechain/doc/rotamer_constructor.rst         |  32 +-
 .../pymod/export_scwrl_rotamer_constructor.cc | 161 +---
 sidechain/src/scwrl_rotamer_constructor.cc    | 790 ++++++++++++------
 sidechain/src/scwrl_rotamer_constructor.hh    |  67 +-
 sidechain/tests/test_frame_construction.cc    |   8 +-
 sidechain/tests/test_rotamers.cc              | 101 +--
 10 files changed, 629 insertions(+), 650 deletions(-)

diff --git a/doc/tests/scripts/sidechain_steps.py b/doc/tests/scripts/sidechain_steps.py
index bf1a3866..aa903d24 100644
--- a/doc/tests/scripts/sidechain_steps.py
+++ b/doc/tests/scripts/sidechain_steps.py
@@ -6,8 +6,8 @@ prot = io.LoadPDB('data/1CRN.pdb')
 # load rotamer library
 library = sidechain.LoadDunbrackLib()
 # we need a rotamer constructor to create any rotamers or 
-# frame residues
-rot_constructor = sidechain.SCWRLRotamerConstructor()
+# frame residues 
+rot_constructor = sidechain.SCWRLRotamerConstructor(False)
 
 # create new entity from protein only containing the amino acids
 prot = mol.CreateEntityFromView(prot.Select("peptide=true"), True)
diff --git a/modelling/pymod/_reconstruct_sidechains.py b/modelling/pymod/_reconstruct_sidechains.py
index 26d31567..cc465d83 100644
--- a/modelling/pymod/_reconstruct_sidechains.py
+++ b/modelling/pymod/_reconstruct_sidechains.py
@@ -1,5 +1,6 @@
 from ost import geom, mol, conop
 from promod3 import core, sidechain
+import traceback
 
 ###############################################################################
 # helper functions
@@ -10,7 +11,6 @@ def _GetRotamerIDs(res_list):
         rot_id = sidechain.TLCToRotID(r.GetName())
         if rot_id == sidechain.XXX:
             continue # no idea what it is, so we stick with ALA 
-                     # => don't model sidechain
         rotamer_ids[i] = rot_id
     return rotamer_ids
 
@@ -105,12 +105,11 @@ def _AddLigandFrameResidues(frame_residues, ent_lig, rotamer_constructor, offset
                     fr1 = rotamer_constructor.ConstructBackboneFrameResidue(\
                               res.handle, rot_id, res_idx,
                               phi, n_ter, c_ter)
-                    if rot_id != sidechain.ALA and rot_id != sidechain.GLY:
-                        fr2 = rotamer_constructor.ConstructSidechainFrameResidue(\
-                                  res.handle, rot_id, res_idx)
-                        frame_residues.extend([fr1,fr2])
-                    else:
-                        frame_residues.append(fr1)
+
+                    fr2 = rotamer_constructor.ConstructSidechainFrameResidue(\
+                              res.handle, rot_id, res_idx)
+
+                    frame_residues.extend([fr1,fr2])
                 except:
                     pass   # ignore peptide treatment and treat below
                 else:
@@ -148,9 +147,6 @@ def _AddSidechainFrameResidues(frame_residues, incomplete_sidechains,
                 cystein_indices.append(i)
                 continue
 
-            if rotamer_ids[i] == sidechain.ALA or rotamer_ids[i] == sidechain.GLY:
-                continue # no sidechain to model
-
             try:
                 frame_residue = rotamer_constructor.ConstructSidechainFrameResidue(\
                                     r.handle, rotamer_ids[i], i)
@@ -166,9 +162,6 @@ def _AddSidechainFrameResidues(frame_residues, incomplete_sidechains,
                 cystein_indices.append(i)
                 continue
 
-            if rotamer_ids[i] == sidechain.ALA or rotamer_ids[i] == sidechain.GLY:
-                continue # no sidechain to model
-
             incomplete_sidechains.append(i)
 
 def _AddCysteinFrameResidues(frame_residues, incomplete_sidechains,
@@ -231,7 +224,7 @@ def _GetRotamerGroups(res_list, rot_ids, indices, rot_lib, rot_constructor,
                       phi_angles, psi_angles, use_frm, bbdep, frame_residues):
     '''Get list of rotamer groups from subset of res_list.
     Residues are chosen as res_list[i] for i in indices and only if a rotamer
-    group can be created (e.g. no ALA, GLY).
+    group can be created.
     Rotamer groups are filtered to keep only best ones (given frame).
     Returns list of rotamer groups and list of res. indices they belong to.
     '''
@@ -249,9 +242,6 @@ def _GetRotamerGroups(res_list, rot_ids, indices, rot_lib, rot_constructor,
         # get rotamer ID
         r = res_list[i]
         rot_id = rot_ids[i]
-        
-        if rot_id == sidechain.ALA or rot_id == sidechain.GLY:
-            continue
 
         if rot_id == sidechain.CYS:
             rot_id = sidechain.CYH
@@ -442,7 +432,7 @@ def ReconstructSidechains(ent, keep_sidechains=False, build_disulfids=True,
     if type(rotamer_library) is sidechain.BBDepRotamerLib:
         bbdep = True
 
-    rotamer_constructor = sidechain.SCWRLRotamerConstructor()
+    rotamer_constructor = sidechain.SCWRLRotamerConstructor(False)
     
     # take out ligand chain and any non-peptides
     prot = ent.Select("peptide=true and cname!='_'")
diff --git a/modelling/src/sidechain_env_listener.cc b/modelling/src/sidechain_env_listener.cc
index 18a1297e..d72e09f3 100644
--- a/modelling/src/sidechain_env_listener.cc
+++ b/modelling/src/sidechain_env_listener.cc
@@ -150,10 +150,7 @@ void SidechainEnvListener::SetResidue_(loop::ConstAllAtomPositionsPtr all_pos,
   // we only add data if BB is set
   if (bb_set) {
     // get positions
-    const geom::Vec3& n_pos  = all_pos->GetPos(idx_N);
     const geom::Vec3& ca_pos = all_pos->GetPos(idx_CA);
-    const geom::Vec3& c_pos  = all_pos->GetPos(idx_C);
-    const geom::Vec3& o_pos  = all_pos->GetPos(idx_O);
     geom::Vec3 cb_pos;
     if (r_id != sidechain::GLY)  cb_pos = all_pos->GetPos(idx_CB);
     
@@ -177,36 +174,33 @@ void SidechainEnvListener::SetResidue_(loop::ConstAllAtomPositionsPtr all_pos,
 
     // set backbone frame res.
     bb_frame_residue_[res_idx]
-      = rot_constructor_.ConstructBackboneFrameResidue(n_pos, ca_pos, c_pos, 
-                                                       o_pos, cb_pos,
+      = rot_constructor_.ConstructBackboneFrameResidue(*all_pos, res_idx, 
                                                        r_id, res_idx, 
                                                        phi_angle_[res_idx], 
                                                        n_ter_[res_idx], 
                                                        c_ter_[res_idx]);
     
-    // do we have a sidechain?
-    if (r_id != sidechain::ALA && r_id != sidechain::GLY) {
-      // set sidechain frame res. if all set
-      if (all_set) {
-        sc_frame_residue_[res_idx]
-          = rot_constructor_.ConstructSidechainFrameResidue(*all_pos, res_idx, 
-                                                            r_id, res_idx);
-      } else {
-        sc_frame_residue_[res_idx].reset();
-      }
-      // set rotamer if needed
-      if (all_rotamers_ || !all_set) {
-        SetRotamer_(all_pos, n_pos, ca_pos, cb_pos, r_id, res_idx);
-      } else {
-        if (use_frm_) frm_rotamer_group_[res_idx].reset();
-        else          rrm_rotamer_group_[res_idx].reset();
-      }
-      // set extra cystein rotamer if needed
-      if (add_cyd_rotamers_ && r_id == sidechain::CYS) {
-        CreateRotamerGroup(cyd_frm_rotamer_group_[res_idx], n_pos, ca_pos,
-                           cb_pos, sidechain::CYD, res_idx);
-      }
+    // set sidechain frame res. if all set
+    if (all_set) {
+      sc_frame_residue_[res_idx]
+        = rot_constructor_.ConstructSidechainFrameResidue(*all_pos, res_idx, 
+                                                           r_id, res_idx);
+    } else {
+      sc_frame_residue_[res_idx].reset();
+    }
+    // set rotamer if needed
+    if (all_rotamers_ || !all_set) {
+      SetRotamer_(all_pos, r_id, res_idx);
+    } else {
+      if (use_frm_) frm_rotamer_group_[res_idx].reset();
+      else          rrm_rotamer_group_[res_idx].reset();
     }
+    // set extra cystein rotamer if needed
+    if (add_cyd_rotamers_ && r_id == sidechain::CYS) {
+      CreateRotamerGroup(cyd_frm_rotamer_group_[res_idx], all_pos,
+                         sidechain::CYD, res_idx);
+    }
+    
   } else {
     // clear stuff
     if (bb_frame_residue_[res_idx]) {
@@ -224,9 +218,6 @@ void SidechainEnvListener::SetResidue_(loop::ConstAllAtomPositionsPtr all_pos,
 }
 
 void SidechainEnvListener::SetRotamer_(loop::ConstAllAtomPositionsPtr all_pos,
-                                       const geom::Vec3& n_pos,
-                                       const geom::Vec3& ca_pos,
-                                       const geom::Vec3& cb_pos,
                                        const sidechain::RotamerID r_id,
                                        const uint res_idx) {
   // add rotamer anyways -> potentially need to change ID
@@ -245,10 +236,10 @@ void SidechainEnvListener::SetRotamer_(loop::ConstAllAtomPositionsPtr all_pos,
   //    -> same with RRM:         0.30s
   //    -> RRM w/o BBdep:         0.23s
   if (use_frm_) {
-    CreateRotamerGroup(frm_rotamer_group_[res_idx], n_pos, ca_pos, cb_pos,
+    CreateRotamerGroup(frm_rotamer_group_[res_idx], all_pos,
                        rg_r_id, res_idx);
   } else {
-    CreateRotamerGroup(rrm_rotamer_group_[res_idx], n_pos, ca_pos, cb_pos,
+    CreateRotamerGroup(rrm_rotamer_group_[res_idx], all_pos,
                        rg_r_id, res_idx);
   }
 }
diff --git a/modelling/src/sidechain_env_listener.hh b/modelling/src/sidechain_env_listener.hh
index a35a0b36..2f8c14a1 100644
--- a/modelling/src/sidechain_env_listener.hh
+++ b/modelling/src/sidechain_env_listener.hh
@@ -119,40 +119,33 @@ public:
 
   // create a rotamer group based on internal settings (no use_frm_ check!)
   void CreateRotamerGroup(sidechain::FRMRotamerGroupPtr& rot_group,
-                          const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-                          const geom::Vec3& cb_pos, 
+                          loop::ConstAllAtomPositionsPtr all_pos, 
                           const sidechain::RotamerID r_id, const uint res_idx) {
     if (use_bbdep_lib_) {
-      rot_group = rot_constructor_.ConstructFRMRotamerGroup(n_pos, ca_pos, 
-                                                            cb_pos, r_id, 
-                                                            res_idx,
+      rot_group = rot_constructor_.ConstructFRMRotamerGroup(*all_pos, res_idx, 
+                                                            r_id, res_idx,
                                                             bbdep_library_,
                                                             phi_angle_[res_idx],
                                                             psi_angle_[res_idx]);
     } else {
-      rot_group = rot_constructor_.ConstructFRMRotamerGroup(n_pos, ca_pos, cb_pos, 
+      rot_group = rot_constructor_.ConstructFRMRotamerGroup(*all_pos, res_idx, 
                                                             r_id, res_idx,
                                                             library_);
     }
     rot_constructor_.AssignInternalEnergies(rot_group);
   }
   void CreateRotamerGroup(sidechain::RRMRotamerGroupPtr& rot_group,
-                          const geom::Vec3& n_pos, 
-                          const geom::Vec3& ca_pos,
-                          const geom::Vec3& cb_pos, 
-                          const sidechain::RotamerID r_id,
-                          const uint res_idx) {
+                          loop::ConstAllAtomPositionsPtr all_pos, 
+                          const sidechain::RotamerID r_id, const uint res_idx) {
     if (use_bbdep_lib_) {
-      rot_group = rot_constructor_.ConstructRRMRotamerGroup(n_pos, ca_pos, 
-                                                            cb_pos, r_id, 
-                                                            res_idx,
+      rot_group = rot_constructor_.ConstructRRMRotamerGroup(*all_pos, res_idx,
+                                                            r_id, res_idx,
                                                             bbdep_library_,
                                                             phi_angle_[res_idx],
                                                             psi_angle_[res_idx]);
     } else {
-      rot_group = rot_constructor_.ConstructRRMRotamerGroup(n_pos, ca_pos, 
-                                                            cb_pos, r_id, 
-                                                            res_idx,
+      rot_group = rot_constructor_.ConstructRRMRotamerGroup(*all_pos, res_idx,
+                                                            r_id, res_idx,
                                                             library_);
     }
     rot_constructor_.AssignInternalEnergies(rot_group);
@@ -163,9 +156,7 @@ private:
   // set stuff for one residue
   void SetResidue_(loop::ConstAllAtomPositionsPtr all_pos, const uint res_idx);
   void SetRotamer_(loop::ConstAllAtomPositionsPtr all_pos,
-                   const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-                   const geom::Vec3& cb_pos, const sidechain::RotamerID r_id,
-                   const uint res_idx);
+                   const sidechain::RotamerID r_id, const uint res_idx);
 
   // global data
   bool all_rotamers_;  // construct rotamers for all res. with BB instead of
@@ -185,8 +176,8 @@ private:
   
   // dynamic data per residue
   // -> any data only set if BB set ("if (bb_frame_residue_[res_idx]) ...")
-  // -> sc_frame_residue set if not ALA/GLY and all pos. available
-  // -> xxx_rotamer_group set if not ALA/GLY and atoms missing or all_rotamers_
+  // -> sc_frame_residue set if not GLY and all pos. available
+  // -> xxx_rotamer_group set if no atoms are missing or all_rotamers_
   //    -> if use_frm_, only xxx = frm valid, else, only xxx = rrm
   //    -> CalculateInternalEnergies done for all rotamer groups
   ScCBetaSpatialOrganizerItem* env_data_;
diff --git a/sidechain/doc/rotamer_constructor.rst b/sidechain/doc/rotamer_constructor.rst
index 316c0aba..2f9d7479 100644
--- a/sidechain/doc/rotamer_constructor.rst
+++ b/sidechain/doc/rotamer_constructor.rst
@@ -11,22 +11,33 @@ Constructing Rotamers and Frame Residues
 --------------------------------------------------------------------------------
 
 
-.. class:: SCWRLRotamerConstructor()
+.. class:: SCWRLRotamerConstructor(cb_in_sidechain)
 
   Constructing rotamers and frame residues that are parametrized according to
   the SCWRL4 method. They contain all heavy atoms, but also the
-  polar hydrogens. The rotamers start after the CB atom (typically CG). 
+  polar hydrogens. 
   In case of the :class:`FrameResidue` construction, the
   constructor distinguishes between backbone and sidechain frame residues.
 
+  :param cb_in_sidechain: If set to true, all constructed rotamers will contain 
+                          the cb atom. This flag also affects the construction 
+                          of frame residues and controls whether the cb atom 
+                          shows up in the backbone frame residues or sidechain 
+                          frame residues.
+                          This is useful when you want to represent ALA or 
+                          GLY with actual rotamers, but be aware of increased 
+                          runtime. This flag can be set to False for most
+                          modeling applications and you just don't generate
+                          any rotamers for ALA and GLY.
+
+  :type cb_in_sidechain: :class:`bool`
+
+
   .. 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(n_pos, ca_pos, cb_pos, id,\
-                                       residue_index, rot_lib,\          
-                                       [probability_cutoff = 0.98])
   .. method:: ConstructRRMRotamerGroup(res, id, residue_index, rot_lib,\
                                        [phi = -1.0472, psi = -0.7854,\
                                         probability_cutoff = 0.98])
@@ -34,18 +45,11 @@ Constructing Rotamers and Frame Residues
                                        residue_index, rot_lib,\
                                        [phi = -1.0472, psi = -0.7854,\
                                         probability_cutoff = 0.98])
-  .. method:: ConstructRRMRotamerGroup(n_pos, ca_pos, cb_pos, id,\
-                                       residue_index, rot_lib,\
-                                       [phi = -1.0472, psi = -0.7854,\
-                                        probability_cutoff = 0.98])
   .. method:: ConstructRRMRotamerGroup(res, id, residue_index, rot_lib_entries,\
                                        [probability_cutoff = 0.98])
   .. method:: ConstructRRMRotamerGroup(all_atom_pos, aa_res_idx, id,\
                                        residue_index, rot_lib_entries,\
                                        [probability_cutoff = 0.98])
-  .. method:: ConstructRRMRotamerGroup(n_pos, ca_pos, cb_pos, id,\
-                                       residue_index, rot_lib_entries,\          
-                                       [probability_cutoff = 0.98])
 
     All functions are also avaible for their flexible rotamer model counterpart.
     =>ConstructFRMRotamerGroup(...) with exactly the same parameters. 
@@ -105,10 +109,6 @@ Constructing Rotamers and Frame Residues
                                             residue_index, Real phi,\
                                             [n_ter = False, c_ter = False])
 
-  .. method:: ConstructBackboneFrameResidue(n_pos, ca_pos, c_pos, o_pos, cb_pos,\ 
-                                            id, residue_index, Real phi,\
-                                            [n_ter = False, c_ter = False])
-
     Constructs backbone frame residues for amino acid residues. It extracts
     the n, ca, c, o and cb positions and constructs a frame residue based on
     the parametrizations of SCWRL4. In case of **n_ter**, there are additional
diff --git a/sidechain/pymod/export_scwrl_rotamer_constructor.cc b/sidechain/pymod/export_scwrl_rotamer_constructor.cc
index 1d9cda25..539288e3 100644
--- a/sidechain/pymod/export_scwrl_rotamer_constructor.cc
+++ b/sidechain/pymod/export_scwrl_rotamer_constructor.cc
@@ -13,6 +13,10 @@ using namespace promod3;
 
 namespace{
 
+SCWRLRotamerConstructorPtr WrapSCWRLRotamerConstructorInit(bool cb_in_sidechain) {
+  SCWRLRotamerConstructorPtr p(new SCWRLRotamerConstructor(cb_in_sidechain));
+  return p;
+}
 
 RRMRotamerGroupPtr WrapRRMGroup_res(SCWRLRotamerConstructor& constructor,
                                     const ost::mol::ResidueHandle& res,
@@ -36,18 +40,6 @@ RRMRotamerGroupPtr WrapRRMGroup_aa(SCWRLRotamerConstructor& constructor,
                                               rot_lib, probability_cutoff);
 }
 
-RRMRotamerGroupPtr WrapRRMGroup_pos(SCWRLRotamerConstructor& constructor,
-                                    const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-                                    const geom::Vec3& cb_pos,
-                                    RotamerID rotamer_id,
-                                    uint residue_idx,
-                                    RotamerLibPtr rot_lib,
-                                    Real probability_cutoff){
-  return constructor.ConstructRRMRotamerGroup(n_pos, ca_pos, cb_pos,
-                                              rotamer_id, residue_idx,
-                                              rot_lib, probability_cutoff);
-}
-
 FRMRotamerGroupPtr WrapFRMGroup_res(SCWRLRotamerConstructor& constructor,
                                     const ost::mol::ResidueHandle& res,
                                     RotamerID id,
@@ -70,18 +62,6 @@ FRMRotamerGroupPtr WrapFRMGroup_aa(SCWRLRotamerConstructor& constructor,
                                               rot_lib, probability_cutoff);
 }
 
-FRMRotamerGroupPtr WrapFRMGroup_pos(SCWRLRotamerConstructor& constructor,
-                                    const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-                                    const geom::Vec3& cb_pos,
-                                    RotamerID rotamer_id,
-                                    uint residue_idx,
-                                    RotamerLibPtr rot_lib,
-                                    Real probability_cutoff){
-  return constructor.ConstructFRMRotamerGroup(n_pos, ca_pos, cb_pos,
-                                              rotamer_id, residue_idx,
-                                              rot_lib, probability_cutoff);
-}
-
 RRMRotamerGroupPtr WrapRRMGroup_bbdep_res(SCWRLRotamerConstructor& constructor,
                                           const ost::mol::ResidueHandle& res,
                                           RotamerID id,
@@ -108,20 +88,6 @@ RRMRotamerGroupPtr WrapRRMGroup_bbdep_aa(SCWRLRotamerConstructor& constructor,
                                               probability_cutoff);
 }
 
-RRMRotamerGroupPtr WrapRRMGroup_bbdep_pos(SCWRLRotamerConstructor& constructor,
-                                          const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-                                          const geom::Vec3& cb_pos,
-                                          RotamerID rotamer_id,
-                                          uint residue_idx,
-                                          BBDepRotamerLibPtr rot_lib,
-                                          Real phi, Real  psi,
-                                          Real probability_cutoff){
-  return constructor.ConstructRRMRotamerGroup(n_pos, ca_pos, cb_pos,
-                                              rotamer_id, residue_idx,
-                                              rot_lib, phi, psi, 
-                                              probability_cutoff);
-}
-
 FRMRotamerGroupPtr WrapFRMGroup_bbdep_res(SCWRLRotamerConstructor& constructor,
                                           const ost::mol::ResidueHandle& res,
                                           RotamerID id,
@@ -148,20 +114,6 @@ FRMRotamerGroupPtr WrapFRMGroup_bbdep_aa(SCWRLRotamerConstructor& constructor,
                                               probability_cutoff);
 }
 
-FRMRotamerGroupPtr WrapFRMGroup_bbdep_pos(SCWRLRotamerConstructor& constructor,
-                                          const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-                                          const geom::Vec3& cb_pos,
-                                          RotamerID rotamer_id,
-                                          uint residue_idx,
-                                          BBDepRotamerLibPtr rot_lib,
-                                          Real phi, Real  psi,
-                                          Real probability_cutoff){
-  return constructor.ConstructFRMRotamerGroup(n_pos, ca_pos, cb_pos,
-                                              rotamer_id, residue_idx,
-                                              rot_lib, phi, psi, 
-                                              probability_cutoff);
-}
-
 RRMRotamerGroupPtr WrapRRMGroup_entries_res(SCWRLRotamerConstructor& constructor,
                                             const ost::mol::ResidueHandle& res,
                                             RotamerID id,
@@ -190,22 +142,6 @@ RRMRotamerGroupPtr WrapRRMGroup_entries_aa(SCWRLRotamerConstructor& constructor,
                                               probability_cutoff);
 }
 
-RRMRotamerGroupPtr WrapRRMGroup_entries_pos(SCWRLRotamerConstructor& constructor,
-                                            const geom::Vec3& n_pos,
-                                            const geom::Vec3& ca_pos,
-                                            const geom::Vec3& cb_pos,
-                                            RotamerID rotamer_id,
-                                            uint residue_idx,
-                                            const boost::python::list& entries,
-                                            Real probability_cutoff){
-  std::vector<RotamerLibEntry> v_entries;
-  core::ConvertListToVector(entries, v_entries);
-  return constructor.ConstructRRMRotamerGroup(n_pos, ca_pos, cb_pos,
-                                              rotamer_id, residue_idx,
-                                              v_entries, 
-                                              probability_cutoff);
-}
-
 FRMRotamerGroupPtr WrapFRMGroup_entries_res(SCWRLRotamerConstructor& constructor,
                                             const ost::mol::ResidueHandle& res,
                                             RotamerID id,
@@ -234,23 +170,6 @@ FRMRotamerGroupPtr WrapFRMGroup_entries_aa(SCWRLRotamerConstructor& constructor,
                                               probability_cutoff);
 }
 
-FRMRotamerGroupPtr WrapFRMGroup_entries_pos(SCWRLRotamerConstructor& constructor,
-                                            const geom::Vec3& n_pos,
-                                            const geom::Vec3& ca_pos,
-                                            const geom::Vec3& cb_pos,
-                                            RotamerID rotamer_id,
-                                            uint residue_idx,
-                                            const boost::python::list& entries,
-                                            Real probability_cutoff){
-  std::vector<RotamerLibEntry> v_entries;
-  core::ConvertListToVector(entries, v_entries);
-  return constructor.ConstructFRMRotamerGroup(n_pos, ca_pos, cb_pos,
-                                              rotamer_id, residue_idx,
-                                              v_entries, 
-                                              probability_cutoff);
-}
-
-
 FrameResiduePtr WrapBBFrame_res(SCWRLRotamerConstructor& constructor,
                                 const ost::mol::ResidueHandle& residue,
                                 RotamerID id, uint residue_index,
@@ -269,19 +188,6 @@ FrameResiduePtr WrapBBFrame_aa(SCWRLRotamerConstructor& constructor,
                                                      phi, n_ter, c_ter);
 }
 
-FrameResiduePtr WrapBBFrame_pos(SCWRLRotamerConstructor& constructor,
-                               const geom::Vec3& n_pos,
-                               const geom::Vec3& ca_pos,
-                               const geom::Vec3& c_pos,
-                               const geom::Vec3& o_pos,
-                               const geom::Vec3& cb_pos,
-                               RotamerID id, uint residue_index,
-                               Real phi, bool n_ter, bool c_ter){
-    return constructor.ConstructBackboneFrameResidue(n_pos, ca_pos, c_pos, 
-                                                     o_pos, cb_pos, id, 
-                                                     residue_index,
-                                                     phi, n_ter, c_ter);
-}
 
 FrameResiduePtr WrapSCFrame_res(SCWRLRotamerConstructor& constructor,
                                 const ost::mol::ResidueHandle& residue,
@@ -313,7 +219,8 @@ void AssignInternalEnergiesFRM(const SCWRLRotamerConstructor& constructor,
 
 void export_SCWRLRotamerConstructor(){
 
-  class_<SCWRLRotamerConstructor>("SCWRLRotamerConstructor", init<>())
+  class_<SCWRLRotamerConstructor, SCWRLRotamerConstructorPtr>("SCWRLRotamerConstructor", no_init)
+    .def("__init__", boost::python::make_constructor(&WrapSCWRLRotamerConstructorInit))
     .def("ConstructRRMRotamerGroup", &WrapRRMGroup_res,(arg("residue"),
                                                         arg("rotamer_id"),
                                                         arg("residue_idx"),
@@ -325,13 +232,6 @@ void export_SCWRLRotamerConstructor(){
                                                        arg("residue_idx"),
                                                        arg("rot_lib"),
                                                        arg("probability_cutoff") = 0.98))
-    .def("ConstructRRMRotamerGroup", &WrapRRMGroup_pos,(arg("n_pos"),
-                                                        arg("ca_pos"),
-                                                        arg("cb_pos"),
-                                                        arg("rotamer_id"),
-                                                        arg("residue_idx"),
-                                                        arg("rot_lib"),
-                                                        arg("probability_cutoff") = 0.98))
     .def("ConstructFRMRotamerGroup", &WrapFRMGroup_res,(arg("residue"),
                                                         arg("rotamer_id"),
                                                         arg("residue_idx"),
@@ -343,13 +243,6 @@ void export_SCWRLRotamerConstructor(){
                                                        arg("residue_idx"),
                                                        arg("rot_lib"),
                                                        arg("probability_cutoff") = 0.98))
-    .def("ConstructFRMRotamerGroup", &WrapFRMGroup_pos,(arg("n_pos"),
-                                                        arg("ca_pos"),
-                                                        arg("cb_pos"),
-                                                        arg("rotamer_id"),
-                                                        arg("residue_idx"),
-                                                        arg("rot_lib"),
-                                                        arg("probability_cutoff") = 0.98))
     .def("ConstructRRMRotamerGroup", &WrapRRMGroup_bbdep_res,(arg("residue"),
                                                               arg("rotamer_id"),
                                                               arg("residue_idx"),
@@ -365,15 +258,6 @@ void export_SCWRLRotamerConstructor(){
                                                              arg("phi") = -1.0472,
                                                              arg("psi") = -0.7854,
                                                              arg("probability_cutoff") = 0.98))
-    .def("ConstructRRMRotamerGroup", &WrapRRMGroup_bbdep_pos,(arg("n_pos"),
-                                                              arg("ca_pos"),
-                                                              arg("cb_pos"),
-                                                              arg("rotamer_id"),
-                                                              arg("residue_idx"),
-                                                              arg("rot_lib"),
-                                                              arg("phi") = -1.0472,
-                                                              arg("psi") = -0.7854,
-                                                              arg("probability_cutoff") = 0.98))
     .def("ConstructFRMRotamerGroup", &WrapFRMGroup_bbdep_res,(arg("residue"),
                                                               arg("rotamer_id"),
                                                               arg("residue_idx"),
@@ -389,15 +273,6 @@ void export_SCWRLRotamerConstructor(){
                                                              arg("phi") = -1.0472,
                                                              arg("psi") = -0.7854,
                                                              arg("probability_cutoff") = 0.98))
-    .def("ConstructFRMRotamerGroup", &WrapFRMGroup_bbdep_pos,(arg("n_pos"),
-                                                              arg("ca_pos"),
-                                                              arg("cb_pos"),
-                                                              arg("rotamer_id"),
-                                                              arg("residue_idx"),
-                                                              arg("rot_lib"),
-                                                              arg("phi") = -1.0472,
-                                                              arg("psi") = -0.7854,
-                                                              arg("probability_cutoff") = 0.98))
     .def("ConstructRRMRotamerGroup", &WrapRRMGroup_entries_res,(arg("residue"),
                                                                 arg("rotamer_id"),
                                                                 arg("residue_idx"),
@@ -409,13 +284,6 @@ void export_SCWRLRotamerConstructor(){
                                                                arg("residue_idx"),
                                                                arg("entries"),
                                                                arg("probability_cutoff") = 0.98))
-    .def("ConstructRRMRotamerGroup", &WrapRRMGroup_entries_pos,(arg("n_pos"),
-                                                                arg("ca_pos"),
-                                                                arg("cb_pos"),
-                                                                arg("rotamer_id"),
-                                                                arg("residue_idx"),
-                                                                arg("entries"),
-                                                                arg("probability_cutoff") = 0.98))
     .def("ConstructFRMRotamerGroup", &WrapFRMGroup_entries_res,(arg("residue"),
                                                                 arg("rotamer_id"),
                                                                 arg("residue_idx"),
@@ -427,13 +295,6 @@ void export_SCWRLRotamerConstructor(){
                                                                arg("residue_idx"),
                                                                arg("entries"),
                                                                arg("probability_cutoff") = 0.98))
-    .def("ConstructFRMRotamerGroup", &WrapFRMGroup_entries_pos,(arg("n_pos"),
-                                                                arg("ca_pos"),
-                                                                arg("cb_pos"),
-                                                                arg("rotamer_id"),
-                                                                arg("residue_idx"),
-                                                                arg("entries"),
-                                                                arg("probability_cutoff") = 0.98))
     .def("ConstructBackboneFrameResidue", &WrapBBFrame_res,(arg("residue"),
                                                             arg("rotamer_id"),
                                                             arg("residue_index"),
@@ -447,16 +308,6 @@ void export_SCWRLRotamerConstructor(){
                                                            arg("phi"),
                                                            arg("n_ter")=false,
                                                            arg("c_ter")=false))
-    .def("ConstructBackboneFrameResidue", &WrapBBFrame_pos,(arg("n_pos"),
-                                                            arg("ca_pos"),
-                                                            arg("c_pos"),
-                                                            arg("o_pos"),
-                                                            arg("cb_pos"),
-                                                            arg("rotamer_id"),
-                                                            arg("residue_index"),
-                                                            arg("phi"),
-                                                            arg("n_ter")=false,
-                                                            arg("c_ter")=false))
     .def("ConstructSidechainFrameResidue", &WrapSCFrame_res,(arg("residue"),
                                                              arg("rotamer_id"),
                                                              arg("residue_index")))
diff --git a/sidechain/src/scwrl_rotamer_constructor.cc b/sidechain/src/scwrl_rotamer_constructor.cc
index 1ef28876..5ef45a29 100644
--- a/sidechain/src/scwrl_rotamer_constructor.cc
+++ b/sidechain/src/scwrl_rotamer_constructor.cc
@@ -170,7 +170,7 @@ _AtomSpecCPList _GetCarboxylAtoms(const _AtomInfo& atom_info) {
 
 namespace promod3 { namespace sidechain {
 
-SCWRLRotamerLookup::SCWRLRotamerLookup() {
+SCWRLRotamerLookup::SCWRLRotamerLookup(bool cb_in_sidechain) {
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
                                 "SCWRLRotamerLookup::SCWRLRotamerLookup", 2);
   
@@ -178,6 +178,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -189,11 +190,17 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -208,6 +215,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -222,6 +230,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -236,6 +245,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -250,14 +260,26 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(ARG, HParticle, 0.25, "H", promod3::loop::ARG_H_INDEX,true);
-  AddBBPDir(ARG, promod3::loop::ARG_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -265,15 +287,22 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -282,6 +311,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -290,47 +320,76 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(ASN, HParticle, 0.25, "H", promod3::loop::ASN_H_INDEX,true);
-  AddBBPDir(ASN, promod3::loop::ASN_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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
-  AddInfo(ASP, CParticle, 0.36, "CG", promod3::loop::ASP_CG_INDEX, false);
   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, CH2Particle, -0.16, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(ASP, HParticle, 0.25, "H", promod3::loop::ASP_H_INDEX,true);
-  AddBBPDir(ASP, promod3::loop::ASP_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -338,16 +397,23 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -357,6 +423,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -366,6 +433,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -375,14 +443,25 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(GLN, HParticle, 0.25, "H", promod3::loop::GLN_H_INDEX,true);
-  AddBBPDir(GLN, promod3::loop::GLN_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -390,14 +469,21 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -405,6 +491,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -412,6 +499,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -419,14 +507,25 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(GLU, HParticle, 0.25, "H", promod3::loop::GLU_H_INDEX,true);
-  AddBBPDir(GLU, promod3::loop::GLU_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -434,6 +533,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -441,9 +541,15 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -454,6 +560,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -464,6 +571,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -474,6 +582,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -484,14 +593,26 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
+  }
+
   sidechain_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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(LYS, HParticle, 0.25, "H", promod3::loop::LYS_H_INDEX,true);
-  AddBBPDir(LYS, promod3::loop::LYS_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -499,8 +620,14 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -508,24 +635,36 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
                         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, CH2Particle, 0.25, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(SER, HParticle, 0.25, "H", promod3::loop::SER_H_INDEX,true);
-  AddBBPDir(SER, promod3::loop::SER_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -533,19 +672,34 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.19, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(CYS, HParticle, 0.25, "H", promod3::loop::CYS_H_INDEX,true);
-  AddBBPDir(CYS, promod3::loop::CYS_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -563,35 +717,54 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(MET, HParticle, 0.25, "H", promod3::loop::MET_H_INDEX,true);
-  AddBBPDir(MET, promod3::loop::MET_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -599,6 +772,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -609,7 +783,13 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -623,6 +803,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -636,14 +817,24 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(TRP, HParticle, 0.25, "H", promod3::loop::TRP_H_INDEX,true);
-  AddBBPDir(TRP, promod3::loop::TRP_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -651,6 +842,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -659,6 +851,11 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -667,6 +864,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
                         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);
@@ -678,6 +876,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -689,6 +888,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -700,14 +900,25 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(TYR, HParticle, 0.25, "H", promod3::loop::TYR_H_INDEX,true);
-  AddBBPDir(TYR, promod3::loop::TYR_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -715,36 +926,54 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
-  AddPDir(THR, promod3::loop::THR_HG1_INDEX, promod3::loop::THR_OG1_INDEX, 0);
+
+  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, CH2Particle, 0.25, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(THR, HParticle, 0.25, "H", promod3::loop::THR_H_INDEX,true);
-  AddBBPDir(THR, promod3::loop::THR_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -752,21 +981,36 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(VAL, HParticle, 0.25, "H", promod3::loop::VAL_H_INDEX,true);
-  AddBBPDir(VAL, promod3::loop::VAL_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -774,29 +1018,46 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(ILE, HParticle, 0.25, "H", promod3::loop::ILE_H_INDEX,true);
-  AddBBPDir(ILE, promod3::loop::ILE_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -804,49 +1065,76 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
+  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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(LEU, HParticle, 0.25, "H", promod3::loop::LEU_H_INDEX,true);
-  AddBBPDir(LEU, promod3::loop::LEU_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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 onoe single
+  // 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);
-  AddBBInfo(PRO, CH2Particle, 0.25, "CB", promod3::loop::BB_CB_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);
 
@@ -864,15 +1152,23 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -882,6 +1178,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -891,14 +1188,24 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(HSD, HParticle, 0.25, "H", promod3::loop::HIS_H_INDEX,true);
-  AddBBPDir(HSD, promod3::loop::HIS_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -906,15 +1213,22 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -924,6 +1238,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -933,14 +1248,24 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(HSE, HParticle, 0.25, "H", promod3::loop::HIS_H_INDEX,true);
-  AddBBPDir(HSE, promod3::loop::HIS_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
 
@@ -954,12 +1279,18 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -969,6 +1300,7 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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);
@@ -978,32 +1310,56 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   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, CH2Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(PHE, HParticle, 0.25, "H", promod3::loop::PHE_H_INDEX,true);
-  AddBBPDir(PHE, promod3::loop::PHE_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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, CH3Particle, 0.0, "CB", promod3::loop::BB_CB_INDEX, false);
   AddBBInfo(ALA, HParticle, 0.25, "H", promod3::loop::ALA_H_INDEX,true);
-  AddBBPDir(ALA, promod3::loop::ALA_H_INDEX, promod3::loop::BB_N_INDEX, 5);
+
+  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);
@@ -1025,7 +1381,8 @@ SCWRLRotamerLookup::SCWRLRotamerLookup() {
   }
 }
 
-SCWRLRotamerConstructor::SCWRLRotamerConstructor(){
+SCWRLRotamerConstructor::SCWRLRotamerConstructor(bool cb_in_sidechain): 
+                                rotamer_lookup_(cb_in_sidechain) {
   String s(XXX,'X');
   for(uint i = 0; i < XXX; ++i){
     s[i] = RotIDToOLC(RotamerID(i));
@@ -1055,16 +1412,6 @@ RRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructRRMRotamerGroup(
                                         probability_cutoff);
 }
 
-RRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructRRMRotamerGroup(
-        const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-        const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-        RotamerLibPtr rot_lib, Real probability_cutoff){
-  std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id);
-  this->SetPosBuffer(n_pos, ca_pos, cb_pos, id);
-  return this->ConstructRRMRotamerGroup(id, residue_index, lib_entries, 
-                                        probability_cutoff);
-}
-
 FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
         uint residue_index, RotamerLibPtr rot_lib, 
@@ -1085,16 +1432,6 @@ FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
                                         probability_cutoff);
 }
 
-FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
-        const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-        const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-        RotamerLibPtr rot_lib, Real probability_cutoff){
-  std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id);
-  this->SetPosBuffer(n_pos, ca_pos, cb_pos, id);
-  return this->ConstructFRMRotamerGroup(id, residue_index, lib_entries, 
-                                        probability_cutoff);
-}
-
 RRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructRRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
         uint residue_index, BBDepRotamerLibPtr rot_lib, 
@@ -1116,17 +1453,6 @@ RRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructRRMRotamerGroup(
                                         probability_cutoff);
 }
 
-RRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructRRMRotamerGroup(
-        const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-        const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-        BBDepRotamerLibPtr rot_lib, 
-        Real phi, Real psi, Real probability_cutoff){
-  std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id, phi, psi);
-  this->SetPosBuffer(n_pos, ca_pos, cb_pos, id);
-  return this->ConstructRRMRotamerGroup(id, residue_index, lib_entries, 
-                                        probability_cutoff);
-}
-
 FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
         uint residue_index, BBDepRotamerLibPtr rot_lib, 
@@ -1148,26 +1474,11 @@ FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
                                         probability_cutoff);
 }
 
-FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
-        const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-        const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-        BBDepRotamerLibPtr rot_lib, 
-        Real phi, Real psi, Real probability_cutoff){
-  std::pair<RotamerLibEntry*,uint> lib_entries = rot_lib->QueryLib(id, phi, psi);
-  this->SetPosBuffer(n_pos, ca_pos, cb_pos, id);
-  return this->ConstructFRMRotamerGroup(id, residue_index, lib_entries, 
-                                        probability_cutoff);
-}
-
 RRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructRRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
         uint residue_index, 
         std::vector<RotamerLibEntry>& lib_entries, 
         Real probability_cutoff){
-  if(lib_entries.empty()){
-    throw promod3::Error("How do you want me to construct rotamers with an " 
-                         "empty input?");
-  }
   std::pair<RotamerLibEntry*,uint> I_LIKE_CHEESE = 
   std::make_pair(&lib_entries[0], lib_entries.size());
   this->SetPosBuffer(res, id);
@@ -1180,10 +1491,6 @@ RRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructRRMRotamerGroup(
         uint aa_res_idx, RotamerID id, uint residue_index,
         std::vector<RotamerLibEntry>& lib_entries, 
         Real probability_cutoff){
-   if(lib_entries.empty()){
-    throw promod3::Error("How do you want me to construct rotamers with an " 
-                         "empty input?");
-  }
   std::pair<RotamerLibEntry*,uint> I_LIKE_CHEESE = 
   std::make_pair(&lib_entries[0], lib_entries.size());
   this->SetPosBuffer(all_atom, aa_res_idx, id);
@@ -1191,30 +1498,10 @@ RRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructRRMRotamerGroup(
                                         probability_cutoff);
 }
 
-RRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructRRMRotamerGroup(
-        const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-        const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-        std::vector<RotamerLibEntry>& lib_entries, 
-        Real probability_cutoff){
-  if(lib_entries.empty()){
-    throw promod3::Error("How do you want me to construct rotamers with an " 
-                         "empty input?");
-  }
-  std::pair<RotamerLibEntry*,uint> I_LIKE_CHEESE = 
-  std::make_pair(&lib_entries[0], lib_entries.size());
-  this->SetPosBuffer(n_pos, ca_pos, cb_pos, id);
-  return this->ConstructRRMRotamerGroup(id, residue_index, I_LIKE_CHEESE, 
-                                        probability_cutoff);
-}
-
 FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
         const ost::mol::ResidueHandle& res, RotamerID id,
         uint residue_index, std::vector<RotamerLibEntry>& lib_entries, 
         Real probability_cutoff){
-  if(lib_entries.empty()){
-    throw promod3::Error("How do you want me to construct rotamers with an " 
-                         "empty input?");
-  }
   std::pair<RotamerLibEntry*,uint> I_LIKE_CHEESE = 
   std::make_pair(&lib_entries[0], lib_entries.size());
   this->SetPosBuffer(res, id);
@@ -1227,10 +1514,6 @@ FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
         uint aa_res_idx, RotamerID id, uint residue_index,
         std::vector<RotamerLibEntry>& lib_entries, 
         Real probability_cutoff){
-  if(lib_entries.empty()){
-    throw promod3::Error("How do you want me to construct rotamers with an " 
-                         "empty input?");
-  }
   std::pair<RotamerLibEntry*,uint> I_LIKE_CHEESE = 
   std::make_pair(&lib_entries[0], lib_entries.size());
   this->SetPosBuffer(all_atom, aa_res_idx, id);
@@ -1238,22 +1521,6 @@ FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
                                         probability_cutoff);
 }
 
-FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
-        const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-        const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-        std::vector<RotamerLibEntry>& lib_entries, 
-        Real probability_cutoff){
-  if(lib_entries.empty()){
-    throw promod3::Error("How do you want me to construct rotamers with an " 
-                         "empty input?");
-  }
-  std::pair<RotamerLibEntry*,uint> I_LIKE_CHEESE = 
-  std::make_pair(&lib_entries[0], lib_entries.size());
-  this->SetPosBuffer(n_pos, ca_pos, cb_pos, id);
-  return this->ConstructFRMRotamerGroup(id, residue_index, I_LIKE_CHEESE, 
-                                        probability_cutoff);
-}
-
 
 FrameResiduePtr SCWRLRotamerConstructor::ConstructBackboneFrameResidue(
           const ost::mol::ResidueHandle& res, RotamerID id, uint residue_index,
@@ -1262,8 +1529,7 @@ FrameResiduePtr SCWRLRotamerConstructor::ConstructBackboneFrameResidue(
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
           "SCWRLRotamerConstructor::ConstructBackboneFrameResidue", 2);
 
-  const SCWRLRotamerInfo& info = 
-  SCWRLRotamerLookup::GetInstance().GetBackboneInfo(id);
+  const SCWRLRotamerInfo& info = rotamer_lookup_.GetBackboneInfo(id);
 
   for(uint i = 0; i < info.particles.size(); ++i){
     if(!info.particles[i].is_hydrogen){
@@ -1301,8 +1567,7 @@ FrameResiduePtr SCWRLRotamerConstructor::ConstructBackboneFrameResidue(
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
           "SCWRLRotamerConstructor::ConstructBackboneFrameResidue", 2);
 
-  const SCWRLRotamerInfo& info = 
-  SCWRLRotamerLookup::GetInstance().GetBackboneInfo(id);
+  const SCWRLRotamerInfo& info = rotamer_lookup_.GetBackboneInfo(id);
 
   for(uint i = 0; i < info.particles.size(); ++i){
     if(!info.particles[i].is_hydrogen){
@@ -1334,49 +1599,13 @@ FrameResiduePtr SCWRLRotamerConstructor::ConstructBackboneFrameResidue(
   return p; 
 }
 
-FrameResiduePtr SCWRLRotamerConstructor::ConstructBackboneFrameResidue(
-          const geom::Vec3& n_pos, const geom::Vec3& ca_pos, 
-          const geom::Vec3& c_pos, const geom::Vec3& o_pos,
-          const geom::Vec3& cb_pos, 
-          RotamerID id, uint residue_index,
-          Real phi, bool n_ter, bool c_ter){
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRLRotamerConstructor::ConstructBackboneFrameResidue", 2);
-
-  const SCWRLRotamerInfo& info = 
-  SCWRLRotamerLookup::GetInstance().GetBackboneInfo(id);
-
-  pos_buffer_->SetPos(id, promod3::loop::BB_N_INDEX, n_pos);
-  pos_buffer_->SetPos(id, promod3::loop::BB_CA_INDEX, ca_pos);
-  pos_buffer_->SetPos(id, promod3::loop::BB_C_INDEX, c_pos);
-  pos_buffer_->SetPos(id, promod3::loop::BB_O_INDEX, o_pos);
-  if(id != GLY) pos_buffer_->SetPos(id, promod3::loop::BB_CB_INDEX, cb_pos);
-
-  //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 SCWRLRotamerConstructor::ConstructSidechainFrameResidue(
           const ost::mol::ResidueHandle& res, RotamerID id, uint residue_index){
 
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
           "SCWRLRotamerConstructor::ConstructSidechainFrameResidue", 2);
 
-  const SCWRLRotamerInfo& info = 
-  SCWRLRotamerLookup::GetInstance().GetSidechainInfo(id);
+  const SCWRLRotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id);
 
   for(uint i = 0; i < info.particles.size(); ++i){
     if(!info.particles[i].is_hydrogen){
@@ -1413,8 +1642,7 @@ FrameResiduePtr SCWRLRotamerConstructor::ConstructSidechainFrameResidue(
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
           "SCWRLRotamerConstructor::ConstructSidechainFrameResidue", 2);
 
-  const SCWRLRotamerInfo& info = 
-  SCWRLRotamerLookup::GetInstance().GetSidechainInfo(id);
+  const SCWRLRotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id);
 
   for(uint i = 0; i < info.particles.size(); ++i){
     if(!info.particles[i].is_hydrogen){
@@ -1597,6 +1825,20 @@ RRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructRRMRotamerGroup(
     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;
@@ -1669,6 +1911,20 @@ FRMRotamerGroupPtr SCWRLRotamerConstructor::ConstructFRMRotamerGroup(
     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_;
@@ -1733,10 +1989,8 @@ RRMRotamerPtr SCWRLRotamerConstructor::ConstructRRMRotamer(RotamerID id,
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
           "SCWRLRotamerConstructor::ConstructRRMRotamer", 2);
 
-  const SCWRLRotamerInfo& info = 
-  SCWRLRotamerLookup::GetInstance().GetSidechainInfo(id);
-  int num_particles = 
-  SCWRLRotamerLookup::GetInstance().GetNumSidechainParticles(id);
+  const SCWRLRotamerInfo& info = rotamer_lookup_.GetSidechainInfo(id);
+  int num_particles = rotamer_lookup_.GetNumSidechainParticles(id);
   std::vector<Particle> particles(num_particles);
 
   //set the positions
@@ -1749,7 +2003,7 @@ RRMRotamerPtr SCWRLRotamerConstructor::ConstructRRMRotamer(RotamerID id,
     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
+    // 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){
@@ -1781,12 +2035,9 @@ FRMRotamerPtr SCWRLRotamerConstructor::ConstructFRMRotamer(RotamerID id,
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
           "SCWRLRotamerConstructor::ConstructFRMRotamer", 2);
 
-  const SCWRLRotamerInfo& info = 
-  SCWRLRotamerLookup::GetInstance().GetSidechainInfo(id);
-  int num_rrm_particles = 
-  SCWRLRotamerLookup::GetInstance().GetNumSidechainParticles(id);
-  int num_particles = 
-  SCWRLRotamerLookup::GetInstance().GetNumFRMSidechainParticles(id);
+  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
@@ -1823,8 +2074,7 @@ FRMRotamerPtr SCWRLRotamerConstructor::ConstructFRMRotamer(RotamerID id,
   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 = 
-  SCWRLRotamerLookup::GetInstance().GetFRMRules(id);
+  const std::vector<SCWRLFRMRule>& frm_rules = rotamer_lookup_.GetFRMRules(id);
   geom::Vec3 rotation_axis, rotation_anchor;
   geom::Vec3 orig_pos, rot_pos;
   geom::Mat4 rot;
@@ -1836,8 +2086,10 @@ FRMRotamerPtr SCWRLRotamerConstructor::ConstructFRMRotamer(RotamerID id,
     int num_rotating_particles = frm_rule.rotating_particles.size();
 
     // Update the subrotamer definition... all particles that are fixed are taken
-    // from the first subrotamer, the indices therefore start from 0
-    for(int i = 0; i < num_fix_particles; ++i) actual_definition[i] = i;
+    // 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
     rotation_anchor = pos_buffer_->GetPos(id, frm_rule.anchor_idx_two);
@@ -1853,9 +2105,10 @@ FRMRotamerPtr SCWRLRotamerConstructor::ConstructFRMRotamer(RotamerID id,
                                               rotation_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;
-        int orig_particle_idx = num_fix_particles + i;
 
+        // replace the old with the new index...
         actual_definition[orig_particle_idx] = new_particle_idx;
 
         // get the new position
@@ -1877,10 +2130,10 @@ FRMRotamerPtr SCWRLRotamerConstructor::ConstructFRMRotamer(RotamerID id,
       // instead of building them from scratch, they get extracted from the
       // initial particles and transformed
       for(int i = 0; i < num_rotating_particles; ++i){
-        int orig_particle_idx = num_fix_particles + i;
+        int orig_particle_idx = frm_rule.rotating_particles[i];
+        int new_particle_idx = base_idx + i;
 
         if(particles[orig_particle_idx].IsHBondDonor()){
-          int new_particle_idx = base_idx + i;
           orig_pos = particles[orig_particle_idx].GetPos() +
                      particles[orig_particle_idx].GetPolarDirection();
           rot_pos[0] = rot(0,0) * orig_pos[0] + rot(0,1) * orig_pos[1] + 
@@ -1895,7 +2148,6 @@ FRMRotamerPtr SCWRLRotamerConstructor::ConstructFRMRotamer(RotamerID id,
         }
 
         if(particles[orig_particle_idx].IsHBondAcceptor()){
-          int new_particle_idx = base_idx + i;
           const std::vector<geom::Vec3>& lp = 
           particles[orig_particle_idx].GetLonePairs();
           for(uint j = 0; j < lp.size(); ++j){
@@ -1939,14 +2191,26 @@ void SCWRLRotamerConstructor::SetPosBuffer(const ost::mol::ResidueHandle& res,
   ost::mol::AtomHandle n = res.FindAtom("N");
   ost::mol::AtomHandle ca = res.FindAtom("CA");
   ost::mol::AtomHandle cb = res.FindAtom("CB");
+  ost::mol::AtomHandle c = res.FindAtom("C");
+  ost::mol::AtomHandle o = res.FindAtom("O");
 
-  if(!(n.IsValid() && ca.IsValid() && cb.IsValid())){
-    throw promod3::Error("N, CA and CB must be valid to construct rotamer!");
+  if(!(n.IsValid() && ca.IsValid() && c.IsValid() && o.IsValid())) {
+    throw promod3::Error("All backbone atoms must be valid to construct "
+                         "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_CB_INDEX, cb.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(!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());
+  }
 }
 
 void SCWRLRotamerConstructor::SetPosBuffer(const promod3::loop::AllAtomPositions& all_atom_pos,
@@ -1955,31 +2219,38 @@ void SCWRLRotamerConstructor::SetPosBuffer(const promod3::loop::AllAtomPositions
   core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
           "SCWRLRotamerConstructor::SetPosBuffer_all_atom_pos", 2);
 
+
   if(!(all_atom_pos.IsSet(all_atom_idx, promod3::loop::BB_N_INDEX) &&
        all_atom_pos.IsSet(all_atom_idx, promod3::loop::BB_CA_INDEX) &&
-       all_atom_pos.IsSet(all_atom_idx, promod3::loop::BB_CB_INDEX))){
-    throw promod3::Error("N, CA and CB must be set to construct rotamer!");
+       all_atom_pos.IsSet(all_atom_idx, promod3::loop::BB_C_INDEX) &&
+       all_atom_pos.IsSet(all_atom_idx, promod3::loop::BB_O_INDEX))){
+    throw promod3::Error("All backbone atoms must be set to construct "
+                         "rotamer!");
   }
 
   pos_buffer_->SetPos(id, promod3::loop::BB_N_INDEX, 
-                      all_atom_pos.GetPos(all_atom_idx, 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, 
-                      all_atom_pos.GetPos(all_atom_idx, promod3::loop::BB_CA_INDEX));
-  pos_buffer_->SetPos(id, promod3::loop::BB_CB_INDEX, 
-                      all_atom_pos.GetPos(all_atom_idx, promod3::loop::BB_CB_INDEX));  
-}
-
-void SCWRLRotamerConstructor::SetPosBuffer(const geom::Vec3& n_pos, 
-                                           const geom::Vec3& ca_pos, 
-                                           const geom::Vec3& cb_pos,
-                                           RotamerID id){
-
-  core::ScopedTimerPtr prof = core::StaticRuntimeProfiler::StartScoped(
-          "SCWRLRotamerConstructor::SetPosBuffer_vec3", 2);
+                      all_atom_pos.GetPos(all_atom_idx, 
+                                          promod3::loop::BB_CA_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, 
+                      all_atom_pos.GetPos(all_atom_idx, 
+                                          promod3::loop::BB_O_INDEX));  
+
+  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, 
+                        all_atom_pos.GetPos(all_atom_idx, 
+                                            promod3::loop::BB_CB_INDEX));
 
-  pos_buffer_->SetPos(id, promod3::loop::BB_N_INDEX, n_pos);
-  pos_buffer_->SetPos(id, promod3::loop::BB_CA_INDEX, ca_pos);
-  pos_buffer_->SetPos(id, promod3::loop::BB_CB_INDEX, cb_pos);  
+  }
 }
 
 void SCWRLRotamerConstructor::MVBBPosBuffer(RotamerID from, RotamerID to){
@@ -1987,6 +2258,13 @@ void SCWRLRotamerConstructor::MVBBPosBuffer(RotamerID from, RotamerID to){
                       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));
 }
@@ -2062,54 +2340,38 @@ void SCWRLRotamerConstructor::ConstructBBFrameParticles(
   }
 
   if(n_ter){
-    if(id == PRO || id == TPR || id == CPR){
-      // there are two hydrogens
-      geom::Vec3 ht1_pos, ht2_pos;
-      geom::Vec3 cb_pos, ca_pos, n_pos;
-      // Actually we would have to reconstruct the hydrogens using the prolines
-      // CD atom... since we only have bb info, we use the CB atom.
-      // rather crude, I know...
-      cb_pos = pos_buffer_->GetPos(id, promod3::loop::BB_CB_INDEX);
-      ca_pos = pos_buffer_->GetPos(id, promod3::loop::BB_CA_INDEX);
-      n_pos = pos_buffer_->GetPos(id, promod3::loop::BB_N_INDEX);
-      promod3::core::ConstructAtomPos(cb_pos, ca_pos, n_pos, 0.997, 2.042, 
-                                      2.0944, ht1_pos);
-      promod3::core::ConstructAtomPos(cb_pos,ca_pos,n_pos,0.997, 2.042, 
-                                     -2.0944, ht2_pos);
-      particles[p_idx] = Particle(HParticle, ht1_pos, 0.35, "HT1");
-      particles[p_idx].SetPolarDirection(ht1_pos - n_pos);
-      particles[p_idx + 1] = Particle(HParticle, ht2_pos, 0.35, "HT2");
-      particles[p_idx + 1].SetPolarDirection(ht2_pos - n_pos);
+    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(HParticle, ht1_pos, 0.35, "HT1");
+    particles[p_idx].SetPolarDirection(ht1_pos - n_pos);
+    particles[p_idx + 1] = Particle(HParticle, ht2_pos, 0.35, "HT2");
+    particles[p_idx + 1].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;
     }
-    else{
-      // there are three hydrogens
-      geom::Vec3 ht1_pos, ht2_pos, ht3_pos;
-      geom::Vec3 cb_pos, ca_pos, n_pos; 
-      if(id == GLY) cb_pos = pos_buffer_->GetPos(id, promod3::loop::BB_C_INDEX);
-      else cb_pos = pos_buffer_->GetPos(id, promod3::loop::BB_CB_INDEX);
-      ca_pos = pos_buffer_->GetPos(id, promod3::loop::BB_CA_INDEX);
-      n_pos = pos_buffer_->GetPos(id, promod3::loop::BB_N_INDEX);
-      promod3::core::ConstructAtomPos(cb_pos, ca_pos, n_pos, 0.997, 2.042, 
-                                      M_PI, ht1_pos);
-      promod3::core::ConstructAtomPos(cb_pos, ca_pos, n_pos, 0.997, 2.042,
-                                      1.0472, ht2_pos);
-      promod3::core::ConstructAtomPos(cb_pos, ca_pos, n_pos, 0.997, 2.042, 
-                                      -1.0472, ht3_pos);
-
-      // we assume, that there is currently one hydrogen and replace it with ht1
-      for(uint i = 0; i < info.particles.size(); ++i){
-        if(info.particles[i].is_hydrogen){
-          particles[i] = Particle(HParticle, ht1_pos, 0.35, "HT1");
-          particles[i].SetPolarDirection(ht1_pos - n_pos);
-          break;
-        }
-      }
 
-      // set ht2 and ht3
-      particles[p_idx] = Particle(HParticle, ht2_pos, 0.35, "HT2");
-      particles[p_idx].SetPolarDirection(ht2_pos - n_pos);
-      particles[p_idx + 1] = Particle(HParticle, ht3_pos, 0.35, "HT3");
-      particles[p_idx + 1].SetPolarDirection(ht3_pos - n_pos);
+    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(HParticle, ht3_pos, 0.35, "HT3");
+        particles[i].SetPolarDirection(ht3_pos - n_pos);
+        break;
+      }
     }
   }
 }
diff --git a/sidechain/src/scwrl_rotamer_constructor.hh b/sidechain/src/scwrl_rotamer_constructor.hh
index cc0b38b3..8beea081 100644
--- a/sidechain/src/scwrl_rotamer_constructor.hh
+++ b/sidechain/src/scwrl_rotamer_constructor.hh
@@ -18,6 +18,9 @@
 
 namespace promod3 { namespace sidechain {
 
+class SCWRLRotamerConstructor;
+typedef boost::shared_ptr<SCWRLRotamerConstructor> SCWRLRotamerConstructorPtr;
+
 /// \brief Types of lone pair construction
 enum SCWRLLPRule {
   LONE_PAIR_CARBONYL, LONE_PAIR_COH, LONE_PAIR_CNC
@@ -135,11 +138,9 @@ struct SCWRLRotamerInfo{
 /// \brief Defines lookups to build rotamer stuff.
 class SCWRLRotamerLookup {
 public:
-  // Singleton access to one constant instance (see AminoAcidLookup for details)
-  static const SCWRLRotamerLookup& GetInstance() {
-    static SCWRLRotamerLookup instance;
-    return instance;
-  }
+
+  SCWRLRotamerLookup(bool cb_in_sidechain);
+
   // Data access
   const SCWRLRotamerInfo& GetSidechainInfo(RotamerID id) const { 
     return sidechain_infos_[id]; 
@@ -227,8 +228,6 @@ private:
     frm_rules_[id][rule_idx].fix_particles.push_back(p_idx);
   }
 
-  SCWRLRotamerLookup();
-
   // To construct classical rotamers or as lookup for sidechain frame residues
   SCWRLRotamerInfo sidechain_infos_[XXX + 1];
 
@@ -248,7 +247,7 @@ class SCWRLRotamerConstructor{
 
 public:
 
-  SCWRLRotamerConstructor();
+  SCWRLRotamerConstructor(bool cb_in_sidechain = false);
 
   // Construct rotamer groups from non backbone dependent library
   RRMRotamerGroupPtr ConstructRRMRotamerGroup(
@@ -261,12 +260,6 @@ public:
           uint aa_res_idx, RotamerID id, uint residue_index,
           RotamerLibPtr rot_lib, 
           Real probability_cutoff = 0.98);
-
-  RRMRotamerGroupPtr ConstructRRMRotamerGroup(
-          const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-          const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-          RotamerLibPtr rot_lib, 
-          Real probability_cutoff = 0.98);
   
   FRMRotamerGroupPtr ConstructFRMRotamerGroup(
           const ost::mol::ResidueHandle& res, RotamerID id,
@@ -279,12 +272,6 @@ public:
           RotamerLibPtr rot_lib, 
           Real probability_cutoff = 0.98);
 
-  FRMRotamerGroupPtr ConstructFRMRotamerGroup(
-          const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-          const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-          RotamerLibPtr rot_lib, 
-          Real probability_cutoff = 0.98);
-
   // Construct rotamer groups from backbone dependent library
   RRMRotamerGroupPtr ConstructRRMRotamerGroup(
           const ost::mol::ResidueHandle& res, RotamerID id,
@@ -300,14 +287,6 @@ public:
           Real phi = -1.0472, 
           Real psi =  -0.7854,
           Real probability_cutoff = 0.98);
-
-  RRMRotamerGroupPtr ConstructRRMRotamerGroup(
-          const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-          const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-          BBDepRotamerLibPtr rot_lib, 
-          Real phi = -1.0472, 
-          Real psi =  -0.7854,
-          Real probability_cutoff = 0.98);
   
   FRMRotamerGroupPtr ConstructFRMRotamerGroup(
           const ost::mol::ResidueHandle& res, RotamerID id,
@@ -324,14 +303,6 @@ public:
           Real psi =  -0.7854,
           Real probability_cutoff = 0.98);
 
-  FRMRotamerGroupPtr ConstructFRMRotamerGroup(
-          const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-          const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-          BBDepRotamerLibPtr rot_lib, 
-          Real phi = -1.0472, 
-          Real psi =  -0.7854,
-          Real probability_cutoff = 0.98);
-
   // Construct rotamer groups directly from rotamerlib entries
   RRMRotamerGroupPtr ConstructRRMRotamerGroup(
           const ost::mol::ResidueHandle& res, RotamerID id,
@@ -344,12 +315,6 @@ public:
           uint aa_res_idx, RotamerID id, uint residue_index,
           std::vector<RotamerLibEntry>& lib_entries, 
           Real probability_cutoff = 0.98);
-
-  RRMRotamerGroupPtr ConstructRRMRotamerGroup(
-          const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-          const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-          std::vector<RotamerLibEntry>& lib_entries, 
-          Real probability_cutoff = 0.98);
   
   FRMRotamerGroupPtr ConstructFRMRotamerGroup(
           const ost::mol::ResidueHandle& res, RotamerID id,
@@ -363,26 +328,12 @@ public:
           std::vector<RotamerLibEntry>& lib_entries, 
           Real probability_cutoff = 0.98);
 
-  FRMRotamerGroupPtr ConstructFRMRotamerGroup(
-          const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-          const geom::Vec3& cb_pos, RotamerID id, uint residue_index,
-          std::vector<RotamerLibEntry>& lib_entries, 
-          Real probability_cutoff = 0.98);
-
   // Construct frame residues
   FrameResiduePtr ConstructBackboneFrameResidue(
           const ost::mol::ResidueHandle& res, RotamerID id, uint residue_index,
           Real phi, bool n_ter = false,
           bool c_ter = false);
 
-  FrameResiduePtr ConstructBackboneFrameResidue(
-          const geom::Vec3& n_pos, const geom::Vec3& ca_pos, 
-          const geom::Vec3& c_pos, const geom::Vec3& o_pos,
-          const geom::Vec3& cb_pos, 
-          RotamerID id, uint residue_index,
-          Real phi, bool n_ter = false,
-          bool c_ter = false);
-
   FrameResiduePtr ConstructBackboneFrameResidue(
           const promod3::loop::AllAtomPositions& all_atom, uint aa_res_idx, 
           RotamerID id, uint residue_index,
@@ -434,9 +385,6 @@ private:
   void SetPosBuffer(const promod3::loop::AllAtomPositions&,
                     uint aa_res_index, RotamerID id);
 
-  void SetPosBuffer(const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
-                    const geom::Vec3& cb_pos, RotamerID id);
-
   void MVBBPosBuffer(RotamerID from, RotamerID to);
 
   void ConstructBaseParticles(const SCWRLRotamerInfo& info, RotamerID id,
@@ -449,6 +397,7 @@ private:
   Real chi_angles_[4];
   Real chi_dev_[4];
   Real probability_;
+  SCWRLRotamerLookup rotamer_lookup_;
   promod3::loop::AllAtomPositionsPtr pos_buffer_;
   promod3::loop::HydrogenStoragePtr hydrogen_buffer_;
 };
diff --git a/sidechain/tests/test_frame_construction.cc b/sidechain/tests/test_frame_construction.cc
index edae739c..5c680116 100644
--- a/sidechain/tests/test_frame_construction.cc
+++ b/sidechain/tests/test_frame_construction.cc
@@ -59,13 +59,7 @@ void CheckBackboneFrameConstruction(ost::mol::ResidueHandleList& res_list,
     // frame residues
     fr1 = rc.ConstructBackboneFrameResidue(res_list[i], r_id, i,
                                            phi, n_ter, c_ter);
-    const geom::Vec3 n_pos  = all_atoms.GetPos(i, loop::BB_N_INDEX);
-    const geom::Vec3 ca_pos = all_atoms.GetPos(i, loop::BB_CA_INDEX);
-    const geom::Vec3 c_pos  = all_atoms.GetPos(i, loop::BB_C_INDEX);
-    const geom::Vec3 o_pos  = all_atoms.GetPos(i, loop::BB_O_INDEX);
-    if (r_id != GLY) cb_pos = all_atoms.GetPos(i, loop::BB_CB_INDEX);
-    fr2 = rc.ConstructBackboneFrameResidue(n_pos, ca_pos, c_pos, o_pos, cb_pos,
-                                           r_id, i, phi, n_ter, c_ter);
+    fr2 = rc.ConstructBackboneFrameResidue(all_atoms, i, r_id, i, phi, n_ter, c_ter);
     CompareFrameResidues(*fr1, *fr2);
   }
 }
diff --git a/sidechain/tests/test_rotamers.cc b/sidechain/tests/test_rotamers.cc
index 702bfd1d..0b49ec0b 100644
--- a/sidechain/tests/test_rotamers.cc
+++ b/sidechain/tests/test_rotamers.cc
@@ -96,7 +96,6 @@ void CheckRotamerGroupConstruction(ost::mol::ResidueHandleList& res_list,
                                    RotamerLibPtr rot_lib) {
   // check all frames
   BOOST_CHECK_EQUAL(res_list.size(), all_atoms.GetNumResidues());
-  geom::Vec3 cb_pos;
   RRMRotamerGroupPtr rrm1, rrm2;
   FRMRotamerGroupPtr frm1, frm2;
   SCWRLRotamerConstructor rot_constructor;
@@ -108,81 +107,33 @@ void CheckRotamerGroupConstruction(ost::mol::ResidueHandleList& res_list,
     // angles
     const Real phi = (n_ter) ? -1.0472 : all_atoms.GetPhiTorsion(i);
     const Real psi = (c_ter) ? -0.7854 : all_atoms.GetPsiTorsion(i);
-    // pos
-    const geom::Vec3 n_pos  = all_atoms.GetPos(i, loop::BB_N_INDEX);
-    const geom::Vec3 ca_pos = all_atoms.GetPos(i, loop::BB_CA_INDEX);
-    if (r_id != GLY) cb_pos = all_atoms.GetPos(i, loop::BB_CB_INDEX);
     // do it
-    if (r_id == ALA || r_id == GLY) {
-      // should all throw exceptions
-      BOOST_CHECK_THROW(
-             rot_constructor.ConstructRRMRotamerGroup(res_list[i], r_id, i, 
-                                                      bbd_rot_lib,
-                                                      phi, psi),
-             promod3::Error);
-      BOOST_CHECK_THROW(
-             rot_constructor.ConstructRRMRotamerGroup(n_pos, ca_pos, cb_pos, 
-                                                      r_id, i, bbd_rot_lib, 
-                                                      phi, psi),
-             promod3::Error);
-      BOOST_CHECK_THROW(
-             rot_constructor.ConstructRRMRotamerGroup(res_list[i], r_id, i, 
-                                                      rot_lib),
-             promod3::Error);
-      BOOST_CHECK_THROW(
-             rot_constructor.ConstructRRMRotamerGroup(n_pos, ca_pos, cb_pos, 
-                                                      r_id, i, rot_lib),
-             promod3::Error);
-      BOOST_CHECK_THROW(
-             rot_constructor.ConstructFRMRotamerGroup(res_list[i], r_id, i, 
-                                                      bbd_rot_lib,
-                                                      phi, psi),
-             promod3::Error);
-      BOOST_CHECK_THROW(
-             rot_constructor.ConstructFRMRotamerGroup(n_pos, ca_pos, cb_pos, 
-                                                      r_id, i,
-                                                      bbd_rot_lib, 
-                                                      phi, psi),
-             promod3::Error);
-      BOOST_CHECK_THROW(
-             rot_constructor.ConstructFRMRotamerGroup(res_list[i], r_id, i, 
-                                                      rot_lib),
-             promod3::Error);
-      BOOST_CHECK_THROW(
-             rot_constructor.ConstructFRMRotamerGroup(n_pos, ca_pos, cb_pos, 
-                                                      r_id, i, rot_lib),
-             promod3::Error);
-    } else {
-      // RRM ROTAMER (bbdep)
-      rrm1 = rot_constructor.ConstructRRMRotamerGroup(res_list[i], r_id, i, 
-                                                      bbd_rot_lib,
-                                                      phi, psi);
-
-      rrm2 = rot_constructor.ConstructRRMRotamerGroup(n_pos, ca_pos, cb_pos, 
-                                                      r_id, i, bbd_rot_lib, 
-                                                      phi, psi);
-      CompareRotamerGroups(*rrm1, *rrm2);
-      // RRM ROTAMER (non-bbdep)
-      rrm1 = rot_constructor.ConstructRRMRotamerGroup(res_list[i], r_id, i, 
-                                                      rot_lib);
-      rrm2 = rot_constructor.ConstructRRMRotamerGroup(n_pos, ca_pos, cb_pos, 
-                                                      r_id, i, rot_lib);
-      CompareRotamerGroups(*rrm1, *rrm2);
-      // FRM ROTAMER (bbdep)
-      frm1 = rot_constructor.ConstructFRMRotamerGroup(res_list[i], r_id, i, 
-                                                      bbd_rot_lib,
-                                                      phi, psi);
-      frm2 = rot_constructor.ConstructFRMRotamerGroup(n_pos, ca_pos, cb_pos, 
-                                                      r_id, i, bbd_rot_lib, 
-                                                      phi, psi);
-      CompareRotamerGroups(*frm1, *frm2);
-      // RRM ROTAMER (non-bbdep)
-      frm1 = rot_constructor.ConstructFRMRotamerGroup(res_list[i], r_id, i, 
-                                                      rot_lib);
-      frm2 = rot_constructor.ConstructFRMRotamerGroup(n_pos, ca_pos, cb_pos, 
-                                                      r_id, i, rot_lib);
-      CompareRotamerGroups(*frm1, *frm2);
-    }
+    // RRM ROTAMER (bbdep)
+    rrm1 = rot_constructor.ConstructRRMRotamerGroup(res_list[i], r_id, i, 
+                                                    bbd_rot_lib,
+                                                    phi, psi);
+
+    rrm2 = rot_constructor.ConstructRRMRotamerGroup(all_atoms, i, r_id, i, 
+                                                    bbd_rot_lib, phi, psi);
+    CompareRotamerGroups(*rrm1, *rrm2);
+    // RRM ROTAMER (non-bbdep)
+    rrm1 = rot_constructor.ConstructRRMRotamerGroup(res_list[i], r_id, i, 
+                                                    rot_lib);
+    rrm2 = rot_constructor.ConstructRRMRotamerGroup(all_atoms, i, r_id, i, 
+                                                    rot_lib);
+    CompareRotamerGroups(*rrm1, *rrm2);
+    // FRM ROTAMER (bbdep)
+    frm1 = rot_constructor.ConstructFRMRotamerGroup(res_list[i], r_id, i, 
+                                                    bbd_rot_lib, phi, psi);
+    frm2 = rot_constructor.ConstructFRMRotamerGroup(all_atoms, i, r_id, i, 
+                                                    bbd_rot_lib, phi, psi);
+    CompareRotamerGroups(*frm1, *frm2);
+    // RRM ROTAMER (non-bbdep)
+    frm1 = rot_constructor.ConstructFRMRotamerGroup(res_list[i], r_id, i, 
+                                                    rot_lib);
+    frm2 = rot_constructor.ConstructFRMRotamerGroup(all_atoms, i, r_id, i, 
+                                                    rot_lib);
+    CompareRotamerGroups(*frm1, *frm2);
   }
 }
 
-- 
GitLab