diff --git a/modules/mol/alg/pymod/ligand_scoring.py b/modules/mol/alg/pymod/ligand_scoring.py
index 25bea3916daebb66386f9e61b6e9e10253db3354..594492045052277e72df761e82e7c5f9d431196c 100644
--- a/modules/mol/alg/pymod/ligand_scoring.py
+++ b/modules/mol/alg/pymod/ligand_scoring.py
@@ -856,16 +856,18 @@ class LigandScorer:
                     if mdl_a_hash_code in bs_atom_mapping:
                         trg_bs_indices.append(bs_atom_mapping[mdl_a_hash_code])
                     elif mdl_a_hash_code not in mdl_lig_hashes:
-                        at_key = (a.GetResidue().GetNumber(), a.name)
-                        cname = a.GetChain().name
-                        cname_key = (flat_mapping[cname], cname)
-                        if at_key in self.mappable_atoms[cname_key]:
-                            # Its a contact in the model but not part of trg_bs.
-                            # It can still be mapped using the global
-                            # mdl_ch/ref_ch alignment
-                            # dist in ref > self.lddt_pli_radius + max_thresh
-                            # => guaranteed to be non-fulfilled contact
-                            n_penalty += 1
+                        if a.GetChain().GetName() in flat_mapping:
+                            # Its in a mapped chain
+                            at_key = (a.GetResidue().GetNumber(), a.name)
+                            cname = a.GetChain().name
+                            cname_key = (flat_mapping[cname], cname)
+                            if at_key in self.mappable_atoms[cname_key]:
+                                # Its a contact in the model but not part of
+                                # trg_bs. It can still be mapped using the
+                                # global mdl_ch/ref_ch alignment
+                                # d in ref > self.lddt_pli_radius + max_thresh
+                                # => guaranteed to be non-fulfilled contact
+                                n_penalty += 1
 
                 n_penalties.append(n_penalty)
 
@@ -964,20 +966,20 @@ class LigandScorer:
                 if mdl_ch not in lddt_chain_mapping:
                     # check which chain in trg is closest
                     chem_group_idx = None
-                    for i, m in self.chem_mapping:
+                    for i, m in enumerate(self.chem_mapping):
                         if mdl_ch in m:
                             chem_group_idx = i
                             break
                     if chem_group_idx is None:
                         raise RuntimeError("This should never happen... "
                                            "ask Gabriel...")
-                    mdl_ch = self.chain_mapping_mdl.FindChain(mdl_ch)
-                    mdl_center = mdl_ch.geometric_center
+                    mdl_ch_view = self.chain_mapping_mdl.FindChain(mdl_ch)
+                    mdl_center = mdl_ch_view.geometric_center
                     closest_ch = None
                     closest_dist = None
-                    for trg_ch in self.chem_groups[chem_group_idx]:
-                        if trg_ch not in lddt_mapping.values():
-                            c = self.target.FindChain(trg_ch).geometric_center
+                    for trg_ch in self.chain_mapper.chem_groups[chem_group_idx]:
+                        if trg_ch not in lddt_chain_mapping.values():
+                            c = self.chain_mapper.target.FindChain(trg_ch).geometric_center
                             d = geom.Distance(mdl_center, c)
                             if closest_dist is None or d < closest_dist:
                                 closest_dist = d
diff --git a/modules/mol/alg/tests/test_ligand_scoring.py b/modules/mol/alg/tests/test_ligand_scoring.py
index e0e87fe392f5df97be7dfc1dda1d3600a8ed1c3d..c60c7cba15d3955e28f8ace0a1fb23f5098a0f86 100644
--- a/modules/mol/alg/tests/test_ligand_scoring.py
+++ b/modules/mol/alg/tests/test_ligand_scoring.py
@@ -371,7 +371,7 @@ class TestLigandScoring(unittest.TestCase):
 
         # lddt_pli
         self.assertAlmostEqual(sc.lddt_pli["J"][mol.ResNum(1)], 0.9127105666156202, 5)
-        self.assertAlmostEqual(sc.lddt_pli["F"][mol.ResNum(1)], 0.915929203539823, 6)
+        self.assertAlmostEqual(sc.lddt_pli["F"][mol.ResNum(1)], 0.915929203539823, 5)
         # lddt_pli_details
         self.assertEqual(sc.lddt_pli_details["J"][mol.ResNum(1)]["lddt_pli_n_contacts"], 653)
         self.assertEqual(len(sc.lddt_pli_details["J"][mol.ResNum(1)]["bs_ref_res"]), 15)
@@ -382,6 +382,21 @@ class TestLigandScoring(unittest.TestCase):
         self.assertEqual(sc.lddt_pli_details["F"][mol.ResNum(1)]["target_ligand"].qualified_name, 'K.G3D1')
         self.assertEqual(sc.lddt_pli_details["F"][mol.ResNum(1)]["model_ligand"].qualified_name, 'F.G3D1')
 
+        # lddt_pli with added mdl contacts
+        sc = LigandScorer(trg, trg_4c0a, None, None, check_resnames=False,
+                          add_mdl_contacts=True)
+        self.assertAlmostEqual(sc.lddt_pli["J"][mol.ResNum(1)], 0.8988340192043895, 5)
+        self.assertAlmostEqual(sc.lddt_pli["F"][mol.ResNum(1)], 0.9039735099337749, 5)
+        # lddt_pli_details
+        self.assertEqual(sc.lddt_pli_details["J"][mol.ResNum(1)]["lddt_pli_n_contacts"], 729)
+        self.assertEqual(len(sc.lddt_pli_details["J"][mol.ResNum(1)]["bs_ref_res"]), 63)
+        self.assertEqual(sc.lddt_pli_details["J"][mol.ResNum(1)]["target_ligand"].qualified_name, 'I.G3D1')
+        self.assertEqual(sc.lddt_pli_details["J"][mol.ResNum(1)]["model_ligand"].qualified_name, 'J.G3D1')
+        self.assertEqual(sc.lddt_pli_details["F"][mol.ResNum(1)]["lddt_pli_n_contacts"], 755)
+        self.assertEqual(len(sc.lddt_pli_details["F"][mol.ResNum(1)]["bs_ref_res"]), 62)
+        self.assertEqual(sc.lddt_pli_details["F"][mol.ResNum(1)]["target_ligand"].qualified_name, 'K.G3D1')
+        self.assertEqual(sc.lddt_pli_details["F"][mol.ResNum(1)]["model_ligand"].qualified_name, 'F.G3D1')
+
 
     def test_rmsd_assignment(self):
         """Test that the RMSD-based assignment works.
@@ -775,6 +790,86 @@ class TestLigandScoring(unittest.TestCase):
         self.assertAlmostEqual(sc2.rmsd['00001_FE'][1], 2.1703, 4)
         self.assertAlmostEqual(sc2.rmsd['00001_FE_2'][1], 2.1703, 4)
 
+    def test_added_mdl_contacts(self):
+
+        # binding site for ligand in chain G consists of chains A and B
+        prot = _LoadMMCIF("1r8q.cif.gz")
+
+        # model has the full binding site
+        mdl = mol.CreateEntityFromView(prot.Select("cname=A,B,G"), True)
+
+        # chain C has same sequence as chain A but is not in contact
+        # with ligand in chain G
+        # target has thus incomplete binding site only from chain B
+        trg = mol.CreateEntityFromView(prot.Select("cname=B,C,G"), True)
+
+        # if added model contacts are not considered, the incomplete binding
+        # site only from chain B is perfectly reproduced by model which also has
+        # chain B
+        sc = LigandScorer(mdl, trg, add_mdl_contacts=False)
+        self.assertAlmostEqual(sc.lddt_pli_matrix[0,0], 1.0, 5)
+
+        # if added model contacts are considered, contributions from chain B are
+        # perfectly reproduced but all contacts of ligand towards chain A are
+        # added as penalty
+        sc = LigandScorer(mdl, trg, add_mdl_contacts=True)
+
+        lig = prot.Select("cname=G")
+        A_count = 0
+        B_count = 0
+        for a in lig.atoms:
+            close_atoms = mdl.FindWithin(a.GetPos(), sc.lddt_pli_radius)
+            for ca in close_atoms:
+                cname = ca.GetChain().GetName()
+                if cname == "G":
+                    pass # its a ligand atom...
+                elif cname == "A":
+                    A_count += 1
+                elif cname == "B":
+                    B_count += 1
+                
+        self.assertAlmostEqual(sc.lddt_pli_matrix[0,0],
+                               B_count/(A_count + B_count), 5)
+
+        # Same as before but additionally we remove residue TRP.66 
+        # from chain C in the target to test mapping magic...
+        # Chain C is NOT in contact with the ligand but we only
+        # add contacts from chain A as penalty that are mappable
+        # to the closest chain with same sequence. That would be
+        # chain C
+        query = "cname=B,G or (cname=C and rnum!=66)"
+        trg = mol.CreateEntityFromView(prot.Select(query), True)
+        sc = LigandScorer(mdl, trg, add_mdl_contacts=True)
+
+        TRP66_count = 0
+        for a in lig.atoms:
+            close_atoms = mdl.FindWithin(a.GetPos(), sc.lddt_pli_radius)
+            for ca in close_atoms:
+                cname = ca.GetChain().GetName()
+                if cname == "A" and ca.GetResidue().GetNumber().GetNum() == 66:
+                    TRP66_count += 1
+
+        self.assertEqual(TRP66_count, 134)
+
+        # remove TRP66_count from original penalty
+        self.assertAlmostEqual(sc.lddt_pli_matrix[0,0],
+                               B_count/(A_count + B_count - TRP66_count), 5)        
+
+        # Move a random atom in the model from chain B towards the ligand center
+        # chain B is also present in the target and interacts with the ligand,
+        # but that atom would be far away and thus adds to the penalty. Since
+        # the ligand is small enough, the number of added contacts should be
+        # exactly the number of ligand atoms.
+        mdl_ed = mdl.EditXCS()
+        at = mdl.FindResidue("B", mol.ResNum(8)).FindAtom("NZ")
+        mdl_ed.SetAtomPos(at, lig.geometric_center)
+        sc = LigandScorer(mdl, trg, add_mdl_contacts=True)
+
+        # compared to the last assertAlmostEqual, we add the number of ligand
+        # atoms as additional penalties
+        self.assertAlmostEqual(sc.lddt_pli_matrix[0,0],
+                               B_count/(A_count + B_count - TRP66_count + \
+                               lig.GetAtomCount()), 5)
 
 if __name__ == "__main__":
     from ost import testutils