diff --git a/modelling/doc/loop_closing.rst b/modelling/doc/loop_closing.rst
index b0947df81517f85bd52a134143c11c3f107accb9..ef8199e965ad96d7ecf20407aed41f3b9e9fb055 100644
--- a/modelling/doc/loop_closing.rst
+++ b/modelling/doc/loop_closing.rst
@@ -165,10 +165,10 @@ sequence can be relaxed by the relaxer.
   relaxed.
 
   :param bb_list:       Basis for topology creation
-  :param fix_nterm:     Whether n-terminal backbone positions should kept
-                        rigid during relaxation.
-  :param fix_cterm:     Whether c-terminal backbone positions should kept
-                        rigid during relaxation.
+  :param fix_nterm:     Whether N-terminal backbone positions (N, CA, CB) should
+                        be kept rigid during relaxation.
+  :param fix_cterm:     Whether C-terminal backbone positions (CA, CB, C, O)
+                        should be kept rigid during relaxation.
 
   :type bb_list:        :class:`~promod3.loop.BackboneList`
   :type fix_nterm:      :class:`bool`
@@ -185,10 +185,10 @@ sequence can be relaxed by the relaxer.
   :param bb_list:       Basis for topology creation
   :param density:       Density used as a target for the internal density force
   :param resolution:    Expected resolution of that density
-  :param fix_nterm:     Whether n-terminal backbone positions should kept
-                        rigid during relaxation.
-  :param fix_cterm:     Whether c-terminal backbone positions should kept
-                        rigid during relaxation.
+  :param fix_nterm:     Whether N-terminal backbone positions (N, CA, CB) should
+                        be kept rigid during relaxation.
+  :param fix_cterm:     Whether C-terminal backbone positions (CA, CB, C, O)
+                        should be kept rigid during relaxation.
 
   :type bb_list:        :class:`~promod3.loop.BackboneList`
   :type density:        :class:`ost.img.ImageHandle`
diff --git a/sidechain/pymod/export_sidechain_reconstructor.cc b/sidechain/pymod/export_sidechain_reconstructor.cc
index e6201233c532b444942ffaf72d5e9b5e82bdedd1..887fa29ff246b0d4f212a1c9d44a61d121a078a4 100644
--- a/sidechain/pymod/export_sidechain_reconstructor.cc
+++ b/sidechain/pymod/export_sidechain_reconstructor.cc
@@ -22,6 +22,20 @@ WrapGetDisulfidBridges(const SidechainReconstructionData& sc_rec_data) {
   return return_list;
 }
 
+boost::python::list
+WrapGetIsNTer(const SidechainReconstructionData& sc_rec_data) {
+  boost::python::list return_list;
+  core::AppendVectorToList(sc_rec_data.is_n_ter, return_list);
+  return return_list;
+}
+
+boost::python::list
+WrapGetIsCTer(const SidechainReconstructionData& sc_rec_data) {
+  boost::python::list return_list;
+  core::AppendVectorToList(sc_rec_data.is_c_ter, return_list);
+  return return_list;
+}
+
 SidechainReconstructionDataPtr
 WrapReconstruct(SidechainReconstructor& sc_rec, uint start_resnum,
                 uint num_residues, uint chain_idx) {
@@ -52,6 +66,8 @@ void export_SidechainReconstructor() {
     .def_readonly("loop_length", &SidechainReconstructionData::loop_length)
     .add_property("rotamer_res_indices", &WrapGetRotamerResIndices)
     .add_property("disulfid_bridges", &WrapGetDisulfidBridges)
+    .add_property("is_n_ter", &WrapGetIsNTer)
+    .add_property("is_c_ter", &WrapGetIsCTer)
     .add_property("n_stem_idx", &SidechainReconstructionData::GetNStemIdx)
     .add_property("c_stem_idx", &SidechainReconstructionData::GetCStemIdx)
   ;
diff --git a/sidechain/src/sidechain_env_listener.hh b/sidechain/src/sidechain_env_listener.hh
index 32ded5d66342290dab8fd356e18cbc264ca0fb8c..9f467ce14223413b7e7a8f44b9b134f95cb90817 100644
--- a/sidechain/src/sidechain_env_listener.hh
+++ b/sidechain/src/sidechain_env_listener.hh
@@ -59,6 +59,8 @@ public:
 
   // get data
   uint GetNumResidues() const { return phi_angle_.size(); }
+  bool IsNTerminal(uint res_idx) const { return n_ter_[res_idx]; }
+  bool IsCTerminal(uint res_idx) const { return c_ter_[res_idx]; }
   RotamerID GetRotamerID(uint res_idx) const { return r_id_[res_idx]; }
   Real GetPhiAngle(uint res_idx) const { return phi_angle_[res_idx]; }
   Real GetPsiAngle(uint res_idx) const { return psi_angle_[res_idx]; }
diff --git a/sidechain/src/sidechain_reconstructor.cc b/sidechain/src/sidechain_reconstructor.cc
index 1219768ffe48fef069973d430688a10cd0118693..0c9530383363a1364044412d973ceb47e49a4e9f 100644
--- a/sidechain/src/sidechain_reconstructor.cc
+++ b/sidechain/src/sidechain_reconstructor.cc
@@ -69,6 +69,15 @@ SidechainReconstructor::Reconstruct(uint start_resnum, uint num_residues,
   // append unique surrounding residue indices (first loop part, then rest)
   res_indices.insert(res_indices.end(), nb_indices.begin(), nb_indices.end());
 
+  // add information on termini
+  res->is_n_ter.resize(res_indices.size());
+  res->is_c_ter.resize(res_indices.size());
+  for (uint i = 0; i < res_indices.size(); ++i) {
+    const uint res_idx = res_indices[i];
+    res->is_n_ter[i] = env_->IsNTerminal(res_idx);
+    res->is_c_ter[i] = env_->IsCTerminal(res_idx);
+  }
+
   // solve system
   if (env_->HasFRMRotamers()) SolveSystem_<FRMRotamerGroup>(res);
   else                        SolveSystem_<RRMRotamerGroup>(res);
diff --git a/sidechain/src/sidechain_reconstructor.hh b/sidechain/src/sidechain_reconstructor.hh
index 3fd8fd4d5271af3fe643b66233bef57d4d8d06d9..57e9cd9efb90ffe6ef6deacb03a109593ac68bf7 100644
--- a/sidechain/src/sidechain_reconstructor.hh
+++ b/sidechain/src/sidechain_reconstructor.hh
@@ -12,7 +12,7 @@ typedef boost::shared_ptr<SidechainReconstructionData>
         SidechainReconstructionDataPtr;
 typedef boost::shared_ptr<SidechainReconstructor> SidechainReconstructorPtr;
 
-/// \brief Light-weight object to pass around SidechainReconstructor results.
+/// \brief Helper object to pass around SidechainReconstructor results.
 class SidechainReconstructionData {
 public:
   // atoms and res. indices
@@ -23,6 +23,9 @@ public:
   std::vector<uint> rotamer_res_indices;
   // pairs of indices (into env_pos) of residues where we added disulfid bridge
   std::vector< std::pair<uint,uint> > disulfid_bridges;
+  // for each residue in env_pos, we define if it is a C or N terminal residue
+  std::vector<bool> is_n_ter;
+  std::vector<bool> is_c_ter;
   // for convenience
   uint GetNStemIdx() const { return env_pos->res_indices[0]; }
   uint GetCStemIdx() const { return env_pos->res_indices[loop_length-1]; }
@@ -67,11 +70,6 @@ private:
   void CheckEnvListener_(bool use_frm) const;
   void SetEnvData_(loop::AllAtomEnv& env);
 
-  // reconstruct sidechains: templatized over BackboneList / AllAtomPositions
-  template<typename PosDataType> SidechainReconstructionDataPtr
-  Reconstruct_(const PosDataType& pos_data, uint start_resnum,
-               uint chain_idx) const;
-
   // handles disulfid bridges for cys_indices
   // -> cys_indices[i] can index into has_sidechain / res->env_pos->all_pos
   // -> pairs of cys_indices[i] for bridges added to res->disulfid_bridges