diff --git a/modules/mol/alg/pymod/qsscoring.py b/modules/mol/alg/pymod/qsscoring.py
index bc1a62c2efac77e7d660326d39233ba96005f3bd..0ace94a439ffc82c840ec20914eb9501d1721d88 100644
--- a/modules/mol/alg/pymod/qsscoring.py
+++ b/modules/mol/alg/pymod/qsscoring.py
@@ -180,6 +180,10 @@ class QSscorer:
     :type: :class:`dict` with key = :class:`tuple` of chain names in
            :attr:`qs_ent_1` and value = :class:`tuple` of chain names in
            :attr:`qs_ent_2`.
+
+    :raises: :class:`QSscoreError` if we end up having less than 2 chains for
+             either entity in the mapping (can happen if chains do not have CA
+             atoms).
     """
     if self._chem_mapping is None:
       self._chem_mapping = _GetChemGroupsMapping(self.qs_ent_1, self.qs_ent_2)
@@ -709,7 +713,8 @@ class QSscoreEntity(object):
   def chem_groups(self):
     """
     Intra-complex group of chemically identical (seq. id. > 95%) polypeptide
-    chains. First chain in group is the one with the longest sequence.
+    chains as extracted from :attr:`ca_chains`. First chain in group is the one
+    with the longest sequence.
 
     :getter: Computed on first use (cached)
     :type: :class:`list` of :class:`list` of :class:`str` (chain names)
@@ -994,8 +999,8 @@ def _GetChemGroups(qs_ent, seqid_thr=95.):
   :type seqid_thr:  :class:`float`
   """
   # get data from qs_ent
-  chain_names = [ch.name for ch in qs_ent.ent.chains]
   ca_chains = qs_ent.ca_chains
+  chain_names = sorted(ca_chains.keys())
   # get pairs of identical chains
   # NOTE: this scales quadratically with number of chains and may be optimized
   #       -> one could merge it with "merge transitive pairs" below...
@@ -1119,7 +1124,10 @@ def _GetChemGroupsMapping(qs_ent_1, qs_ent_2):
     LogWarning('Unmapped Chains in %s: %s'
                % (qs_ent_2.GetName(), ','.join(list(chains_2 - mapped_2))))
   
+  # check if we have any chains left
   LogInfo('Chemical chain-groups mapping: ' + str(chem_mapping))
+  if len(mapped_1) < 2 or len(mapped_2) < 2:
+    raise QSscoreError('Less than 2 chains left in chem_mapping.')
   return chem_mapping
 
 def _SelectFew(l, max_elements):
diff --git a/modules/mol/alg/tests/test_qsscoring.py b/modules/mol/alg/tests/test_qsscoring.py
index a860a05287ee60935a962b90ee961204a699cf28..ddc3a465a231c32219bf33e1b4eea375cdc0b4ca 100644
--- a/modules/mol/alg/tests/test_qsscoring.py
+++ b/modules/mol/alg/tests/test_qsscoring.py
@@ -71,8 +71,8 @@ class TestQSscore(unittest.TestCase):
     # use QSscoreEntity to go faster
     qs_scorer_symm = QSscorer(qs_scorer.qs_ent_1, qs_scorer.qs_ent_2)
     qs_scorer_symm.SetSymmetries(symm_1, symm_2)
-    self.assertAlmostEqual(qs_scorer_symm.global_score, 0.359, 2)
-    self.assertAlmostEqual(qs_scorer_symm.best_score, 0.958, 2)
+    self.assertAlmostEqual(qs_scorer_symm.global_score, qs_scorer.global_score)
+    self.assertAlmostEqual(qs_scorer_symm.best_score, qs_scorer.best_score)
 
   def test_HeteroCase4(self):
     # inverted chains
@@ -82,6 +82,22 @@ class TestQSscore(unittest.TestCase):
     self.assertAlmostEqual(qs_scorer.global_score, 0.980, 2)
     self.assertAlmostEqual(qs_scorer.best_score, 0.980, 2)
 
+    # check if CA-only scoring is close to this
+    ent_2_ca = ent_2.Select('aname=CA')
+    # use QSscoreEntity to go faster
+    qs_scorer_ca = QSscorer(qs_scorer.qs_ent_1, ent_2_ca)
+    self.assertAlmostEqual(qs_scorer_ca.global_score, qs_scorer.global_score, 2)
+    self.assertAlmostEqual(qs_scorer_ca.best_score, qs_scorer.best_score, 2)
+    # throw exception for messed up chains without CA atoms
+    ent_2_no_ca = ent_2.Select('aname!=CA')
+    with self.assertRaises(QSscoreError):
+      qs_scorer_tst = QSscorer(qs_scorer.qs_ent_1, ent_2_no_ca)
+      qs_scorer_tst.global_score
+    ent_2_almost_no_ca = ent_2.Select('aname!=CA or cname=A')
+    with self.assertRaises(QSscoreError):
+      qs_scorer_tst = QSscorer(qs_scorer.qs_ent_1, ent_2_almost_no_ca)
+      qs_scorer_tst.global_score
+
   def test_HeteroModel(self):
     # uncomplete model missing 2 third of the contacts
     ent_1 = _LoadFile('1eud_ref.pdb')               # AB, no symmetry
@@ -101,20 +117,6 @@ class TestQSscore(unittest.TestCase):
     self.assertAlmostEqual(qs_scorer.global_score, 0.147, 2)
     self.assertAlmostEqual(qs_scorer.best_score, 0.866, 2)
 
-  def test_lDDT(self):
-    # lDDT is not symmetrical and does not account for overprediction!
-    ref = _LoadFile('4br6.1.pdb').Select('cname=A,B')
-    mdl = _LoadFile('4br6.1.pdb')
-    qs_scorer = QSscorer(ref, mdl)
-    self.assertAlmostEqual(qs_scorer.global_score, 0.171, 2)
-    self.assertAlmostEqual(qs_scorer.best_score, 1.00, 2)
-    self.assertAlmostEqual(qs_scorer.lddt_score, 1.00, 2)
-    # flip them (use QSscoreEntity to go faster)
-    qs_scorer2 = QSscorer(qs_scorer.qs_ent_2, qs_scorer.qs_ent_1)
-    self.assertAlmostEqual(qs_scorer2.global_score, 0.171, 2)
-    self.assertAlmostEqual(qs_scorer2.best_score, 1.00, 2)
-    self.assertAlmostEqual(qs_scorer2.lddt_score, 0.483, 2)
-
   def test_HomoCase2(self):
     # broken cyclic symmetry
     ent_1 = _LoadFile('4r7y.1.pdb')   # A6, symmetry: C6
@@ -134,6 +136,23 @@ class TestQSscore(unittest.TestCase):
     self.assertEqual(qs_scorer_symm.best_score, qs_scorer.best_score)
 
 
+  # TEST EXTRA SCORES
+  
+  def test_lDDT(self):
+    # lDDT is not symmetrical and does not account for overprediction!
+    ref = _LoadFile('4br6.1.pdb').Select('cname=A,B')
+    mdl = _LoadFile('4br6.1.pdb')
+    qs_scorer = QSscorer(ref, mdl)
+    self.assertAlmostEqual(qs_scorer.global_score, 0.171, 2)
+    self.assertAlmostEqual(qs_scorer.best_score, 1.00, 2)
+    self.assertAlmostEqual(qs_scorer.lddt_score, 1.00, 2)
+    # flip them (use QSscoreEntity to go faster)
+    qs_scorer2 = QSscorer(qs_scorer.qs_ent_2, qs_scorer.qs_ent_1)
+    self.assertAlmostEqual(qs_scorer2.global_score, 0.171, 2)
+    self.assertAlmostEqual(qs_scorer2.best_score, 1.00, 2)
+    self.assertAlmostEqual(qs_scorer2.lddt_score, 0.483, 2)
+    
+
   # TEST BIG STUFF and FANCY SYMMETRIES
 
   def test_HeteroBig(self):