Repository: haddocking/arctic3d

Issue:
introduce chain_to_use input parameter
if the user gives a `pdb_to_use` parameter it can happen that the same pdb is associated to multiple chains. We want to let the user pick the right chain as well.

Discussion:

Patch:
diff --git a/src/arctic3d/cli.py b/src/arctic3d/cli.py
index 7c615d5..eec983a 100644
--- a/src/arctic3d/cli.py
+++ b/src/arctic3d/cli.py
@@ -57,8 +57,8 @@ argument_parser.add_argument(
 )
 
 argument_parser.add_argument(
-    "--pdb_renum_db",
-    help="path to a local version of the PDBrenum database",
+    "--chain_to_use",
+    help="the chain to be used",
 )
 
 argument_parser.add_argument(
@@ -113,8 +113,8 @@ def main(
     out_uniprot,
     out_pdb,
     pdb_to_use,
+    chain_to_use,
     run_dir,
-    pdb_renum_db,
 ):
     """Main function."""
     log.setLevel("DEBUG")
@@ -160,7 +160,7 @@ def main(
                 )
         else:
             pdb_f, filtered_interfaces = get_best_pdb(
-                uniprot_id, interface_residues, pdb_to_use, pdb_renum_db
+                uniprot_id, interface_residues, pdb_to_use, chain_to_use
             )
 
         if pdb_f is None:
diff --git a/src/arctic3d/modules/pdb.py b/src/arctic3d/modules/pdb.py
index ca7865b..a58d190 100644
--- a/src/arctic3d/modules/pdb.py
+++ b/src/arctic3d/modules/pdb.py
@@ -462,7 +462,7 @@ def get_maxint_pdb(validated_pdbs, interface_residues, uniprot_id):
     return pdb_f, hit, filtered_interfaces
 
 
-def filter_pdb_list(fetch_list, pdb_to_use):
+def filter_pdb_list(fetch_list, pdb_to_use=None, chain_to_use=None):
     """
     Filter the PDB fetch list.
 
@@ -478,19 +478,26 @@ def filter_pdb_list(fetch_list, pdb_to_use):
     reduced_list : list
         List containing only the pdb_to_use hit
     """
+
     reduced_list = []
     for hit in fetch_list:
         pdb_id = hit["pdb_id"]
-        if pdb_id == pdb_to_use:
+        chain_id = hit["chain_id"]
+        pdb_check, chain_check = True, True
+
+        if pdb_to_use and pdb_id != pdb_to_use:
+            pdb_check = False
+        if chain_to_use and chain_id != chain_to_use:
+            chain_check = False
+        if (pdb_check, chain_check) == (True, True):
             reduced_list.append(hit)
-            break
-    #
+
     if len(reduced_list) == 0:
         log.warning(f"PDB ID {pdb_to_use} not found in fetched pdb list.")
     return reduced_list
 
 
-def get_best_pdb(uniprot_id, interface_residues, pdb_to_use=None, pdb_renum_db=None):
+def get_best_pdb(uniprot_id, interface_residues, pdb_to_use=None, chain_to_use=None):
     """
     Get best PDB ID.
 
@@ -521,11 +528,13 @@ def get_best_pdb(uniprot_id, interface_residues, pdb_to_use=None, pdb_renum_db=N
         return
 
     # if pdb_to_use is not None, already filter the list
+
     if pdb_to_use:
-        pdb_code = pdb_to_use.lower()
-        pdb_list = filter_pdb_list(pdb_dict[uniprot_id], pdb_code)
-    else:
-        pdb_list = pdb_dict[uniprot_id]
+        pdb_to_use = pdb_to_use.lower()
+    if chain_to_use:
+        chain_to_use = chain_to_use.upper()
+    pdb_list = filter_pdb_list(pdb_dict[uniprot_id], pdb_to_use, chain_to_use)
+
     validated_pdbs = validate_api_hit(pdb_list)
 
     pdb_f, top_hit, filtered_interfaces = get_maxint_pdb(


Test patch:
diff --git a/tests/test_pdb.py b/tests/test_pdb.py
index 6d90f59..46f7c39 100644
--- a/tests/test_pdb.py
+++ b/tests/test_pdb.py
@@ -65,6 +65,30 @@ def good_hits():
             "experimental_method": "X-ray diffraction",
             "tax_id": 9913,
         },
+        {
+            "end": 246,
+            "chain_id": "B",
+            "pdb_id": "4gux",
+            "start": 1,
+            "unp_end": 246,
+            "coverage": 1,
+            "unp_start": 1,
+            "resolution": 1.803,
+            "experimental_method": "X-ray diffraction",
+            "tax_id": 9913,
+        },
+        {
+            "end": 246,
+            "chain_id": "C",
+            "pdb_id": "4gux",
+            "start": 1,
+            "unp_end": 246,
+            "coverage": 1,
+            "unp_start": 1,
+            "resolution": 1.803,
+            "experimental_method": "X-ray diffraction",
+            "tax_id": 9913,
+        },
     ]
     return hits_list
 
@@ -132,9 +156,13 @@ def test_get_maxint_pdb():
 
 def test_filter_pdb_list(good_hits):
     """Test filter_pdb_list."""
-    observed_red_list = filter_pdb_list(good_hits, "1abc")
+    observed_red_list = filter_pdb_list(good_hits, pdb_to_use="1abc")
     expected_red_list = []
     assert observed_red_list == expected_red_list
-    observed_red_list = filter_pdb_list(good_hits, "6sy3")
+    observed_red_list = filter_pdb_list(good_hits, pdb_to_use="6sy3")
     expected_red_list = [good_hits[1]]
     assert observed_red_list == expected_red_list
+    # testing chain information
+    observed_red_list = filter_pdb_list(good_hits, pdb_to_use="4gux", chain_to_use="C")
+    expected_red_list = [good_hits[3]]
+    assert observed_red_list == expected_red_list