JAL-2694 StructureSelectionManager.getMapping takes a list of Chain IDs per sequence... patch/JAL-2694_maptoallchainsworkaround
authorJim Procter <jprocter@issues.jalview.org>
Fri, 1 Sep 2017 16:22:42 +0000 (17:22 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Fri, 1 Sep 2017 16:22:42 +0000 (17:22 +0100)
one failing test in this commit

12 files changed:
src/MCview/AppletPDBCanvas.java
src/MCview/PDBCanvas.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AppletJmol.java
src/jalview/gui/AppJmol.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/StructureViewerBase.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/structures/models/AAStructureBindingModel.java
test/jalview/structure/Mapping.java
test/jalview/structure/StructureSelectionManagerTest.java
test/jalview/structures/models/AAStructureBindingModelTest.java

index f94faba..7b03d7c 100644 (file)
@@ -159,7 +159,9 @@ public class AppletPDBCanvas extends Panel
 
     try
     {
-      pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
+      pdb = ssm.setMapping(seq,
+              StructureSelectionManager.perChainList(chains),
+              pdbentry.getFile(), protocol);
 
       if (protocol == DataSourceType.PASTE)
       {
index b2f2503..1914b4a 100644 (file)
@@ -153,7 +153,9 @@ public class PDBCanvas extends JPanel
 
     try
     {
-      pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
+      pdb = ssm.setMapping(seq,
+              StructureSelectionManager.perChainList(chains),
+              pdbentry.getFile(), protocol);
 
       if (protocol.equals(jalview.io.DataSourceType.PASTE))
       {
index b48dec9..38e0b42 100644 (file)
@@ -4133,7 +4133,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     {
       // register the association(s) and quit, don't create any windows.
       if (StructureSelectionManager.getStructureSelectionManager(applet)
-              .setMapping(seqs, chains, pdb.getFile(), protocol) == null)
+              .setMapping(seqs,
+                      StructureSelectionManager.perChainList(chains),
+                      pdb.getFile(), protocol) == null)
       {
         System.err.println("Failed to map " + pdb.getFile() + " ("
                 + protocol + ") to any sequences");
index 49219b9..3456310 100644 (file)
@@ -213,7 +213,9 @@ public class AppletJmol extends EmbmenuFrame implements
     {
       reader = StructureSelectionManager
               .getStructureSelectionManager(ap.av.applet)
-              .setMapping(seq, chains, pdbentry.getFile(), protocol);
+              .setMapping(seq,
+                      StructureSelectionManager.perChainList(chains),
+                      pdbentry.getFile(), protocol);
       // PROMPT USER HERE TO ADD TO NEW OR EXISTING VIEW?
       // FOR NOW, LETS JUST OPEN A NEW WINDOW
     }
index a4597d3..dd67b03 100644 (file)
@@ -175,7 +175,7 @@ public class AppJmol extends StructureViewerBase
      * If the PDB file is already loaded, the user may just choose to add to an
      * existing viewer (or cancel)
      */
-    if (addAlreadyLoadedFile(seq, chains, ap, pdbId))
+    if (addAlreadyLoadedFile(seq, ap, pdbId))
     {
       return;
     }
index ba360af..305df8a 100644 (file)
@@ -219,7 +219,7 @@ public class ChimeraViewFrame extends StructureViewerBase
      * If the PDB file is already loaded, the user may just choose to add to an
      * existing viewer (or cancel)
      */
-    if (addAlreadyLoadedFile(seq, chains, ap, pdbId))
+    if (addAlreadyLoadedFile(seq, ap, pdbId))
     {
       return;
     }
index 3ba9947..8c8b81d 100644 (file)
@@ -448,18 +448,17 @@ public abstract class StructureViewerBase extends GStructureViewer
    * and updates any viewers that have the PDB file
    * 
    * @param seq
-   * @param chains
    * @param apanel
    * @param pdbFilename
    */
   protected void addSequenceMappingsToStructure(SequenceI[] seq,
-          String[] chains, final AlignmentPanel apanel, String pdbFilename)
+          final AlignmentPanel apanel, String pdbFilename)
   {
     // TODO : Fix multiple seq to one chain issue here.
     /*
      * create the mappings
      */
-    apanel.getStructureSelectionManager().setMapping(seq, chains,
+    apanel.getStructureSelectionManager().setMapping(seq, null,
             pdbFilename, DataSourceType.FILE);
 
     /*
@@ -509,7 +508,7 @@ public abstract class StructureViewerBase extends GStructureViewer
    * @param pdbId
    * @return true if the user chooses to add to a viewer, or to cancel entirely
    */
-  protected boolean addAlreadyLoadedFile(SequenceI[] seq, String[] chains,
+  protected boolean addAlreadyLoadedFile(SequenceI[] seq,
           final AlignmentPanel apanel, String pdbId)
   {
     boolean finished = false;
@@ -535,7 +534,7 @@ public abstract class StructureViewerBase extends GStructureViewer
       }
       else if (option == JvOptionPane.YES_OPTION)
       {
-        addSequenceMappingsToStructure(seq, chains, apanel, alreadyMapped);
+        addSequenceMappingsToStructure(seq, apanel, alreadyMapped);
         finished = true;
       }
     }
index a98738f..a8c6ecf 100644 (file)
@@ -324,7 +324,8 @@ public class StructureSelectionManager
    * @return null or the structure data parsed as a pdb file
    */
   synchronized public StructureFile setMapping(SequenceI[] sequence,
-          String[] targetChains, String pdbFile, DataSourceType protocol)
+          List<String>[] targetChains, String pdbFile,
+          DataSourceType protocol)
   {
     return setMapping(true, sequence, targetChains, pdbFile, protocol);
   }
@@ -350,7 +351,7 @@ public class StructureSelectionManager
    * @return null or the structure data parsed as a pdb file
    */
   synchronized public StructureFile setMapping(boolean forStructureView,
-          SequenceI[] sequenceArray, String[] targetChainIds,
+          SequenceI[] sequenceArray, List<String>[] targetChainIds,
           String pdbFile, DataSourceType sourceType)
   {
     /*
@@ -416,7 +417,8 @@ public class StructureSelectionManager
       e.printStackTrace();
     }
 
-    String targetChainId;
+    List<String> targetChainId = new ArrayList();
+    String _targetChainId;
     for (int s = 0; s < sequenceArray.length; s++)
     {
       boolean infChain = true;
@@ -434,25 +436,28 @@ public class StructureSelectionManager
       }
       else if (seq.getName().indexOf("|") > -1)
       {
-        targetChainId = seq.getName()
+        targetChainId = new ArrayList();
+        _targetChainId=seq.getName()
                 .substring(seq.getName().lastIndexOf("|") + 1);
-        if (targetChainId.length() > 1)
+        if (_targetChainId.length() > 1)
         {
-          if (targetChainId.trim().length() == 0)
+          if (_targetChainId.trim().length() == 0)
           {
-            targetChainId = " ";
+            _targetChainId = " ";
           }
           else
           {
             // not a valid chain identifier
-            targetChainId = "";
+            _targetChainId = "";
           }
         }
+        targetChainId.add(_targetChainId);
       }
       else
       {
-        targetChainId = "";
+        _targetChainId = "";
       }
+      
 
       /*
        * Attempt pairwise alignment of the sequence with each chain in the PDB,
@@ -468,7 +473,7 @@ public class StructureSelectionManager
       List<String> maximalChainIds = new ArrayList<>();
       for (PDBChain chain : pdb.getChains())
       {
-        if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
+        if (targetChainId.size() > 0 && !targetChainId.contains(chain.id)
                 && !infChain)
         {
           continue; // don't try to map chains don't match.
@@ -483,7 +488,7 @@ public class StructureSelectionManager
         // as.calcScoreMatrix();
         // as.traceAlignment();
 
-        if (targetChainId.length() > 0 && chain.id.equals(targetChainId))
+        if (targetChainId.size() > 0 && targetChainId.contains(chain.id))
         {
           // Don't care - just pick this chain as the mapping
           maxChain = chain;
@@ -536,19 +541,22 @@ public class StructureSelectionManager
                 .getString("status.obtaining_mapping_with_sifts"));
         jalview.datamodel.Mapping sqmpping = maxAlignseq
                 .getMappingFromS1(false);
-        if (targetChainId != null && !targetChainId.trim().isEmpty())
+        if (targetChainId != null && !targetChainId.isEmpty())
         {
-          StructureMapping siftsMapping;
+          List<StructureMapping> siftsMappings;
           try
           {
-            siftsMapping = getStructureMapping(seq, pdbFile, targetChainId,
+            siftsMappings = getStructureMapping(seq, pdbFile, targetChainId,
                     pdb, maxChain, sqmpping, maxAlignseq);
-            seqToStrucMapping.add(siftsMapping);
+            for (StructureMapping siftsMapping : siftsMappings)
+            {
+              seqToStrucMapping.add(siftsMapping);
             maxChain.makeExactMapping(maxAlignseq, seq);
             maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
                                                        // "IEA:SIFTS" ?
             maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
             ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
+            }
 
           } catch (SiftsException e)
           {
@@ -572,9 +580,9 @@ public class StructureSelectionManager
           {
             try
             {
-              StructureMapping siftsMapping = getStructureMapping(seq,
-                      pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq);
-              foundSiftsMappings.add(siftsMapping);
+              foundSiftsMappings.addAll(getStructureMapping(seq, pdbFile,
+                      Arrays.asList(new String[]
+                      { chain.id }), pdb, chain, sqmpping, maxAlignseq));
             } catch (SiftsException e)
             {
               System.err.println(e.getMessage());
@@ -646,12 +654,20 @@ public class StructureSelectionManager
    * @return
    * @throws SiftsException
    */
-  private StructureMapping getStructureMapping(SequenceI seq,
-          String pdbFile, String targetChainId, StructureFile pdb,
+  private List<StructureMapping> getStructureMapping(SequenceI seq,
+          String pdbFile, List<String> targetChainIdList, StructureFile pdb,
           PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
           AlignSeq maxAlignseq) throws SiftsException
   {
-    StructureMapping curChainMapping = siftsClient
+    List<StructureMapping> currChainMappingList = new ArrayList();
+    int p = 0;
+    do
+    {
+      String targetChainId = (targetChainIdList == null
+              || p >= targetChainIdList.size()) ? null
+                      : targetChainIdList.get(p);
+      StructureMapping curChainMapping = siftsClient
+
             .getSiftsStructureMapping(seq, pdbFile, targetChainId);
     try
     {
@@ -659,12 +675,14 @@ public class StructureSelectionManager
       if (chain != null)
       {
         chain.transferResidueAnnotation(curChainMapping, sqmpping);
+          currChainMappingList.add(curChainMapping);
       }
     } catch (Exception e)
     {
       e.printStackTrace();
     }
-    return curChainMapping;
+    } while (targetChainIdList != null && ++p < targetChainIdList.size());
+    return currChainMappingList;
   }
 
   private List<StructureMapping> getNWMappings(SequenceI seq,
index 2528286..b9dc58d 100644 (file)
@@ -72,9 +72,9 @@ public abstract class AAStructureBindingModel
   private SequenceI[][] sequence;
 
   /*
-   * array of target chains for sequences - tied to pdbentry and sequence[]
+   * array of list of target chains for sequences - tied to pdbentry and sequence[]
    */
-  private String[][] chains;
+  private List<String>[][] chains;
 
   /*
    * datasource protocol for access to PDBEntrylatest
@@ -164,20 +164,26 @@ public abstract class AAStructureBindingModel
     int chainmaps = 0;
     // JBPNote: JAL-2693 - this should be a list of chain mappings per
     // [pdbentry][sequence]
-    String[][] newchains = new String[pdbEntry.length][];
+    List<String>[][] newchains = new List[pdbEntry.length][];
     int pe = 0;
     for (PDBEntry pdb : pdbEntry)
     {
       SequenceI[] seqsForPdb = sequence[pe];
       if (seqsForPdb != null)
       {
-        newchains[pe] = new String[seqsForPdb.length];
+        newchains[pe] = new List[seqsForPdb.length];
         int se = 0;
         for (SequenceI asq : seqsForPdb)
         {
-          String chain = (chains != null && chains[pe] != null)
+          List<String> chain = (chains != null && chains[pe] != null)
                   ? chains[pe][se]
                   : null;
+          if (chain == null)
+          {
+            chain = new ArrayList<>();
+          }
+          newchains[pe][se] = chain;
+
           SequenceI sq = (asq.getDatasetSequence() == null) ? asq
                   : asq.getDatasetSequence();
           if (sq.getAllPDBEntries() != null)
@@ -190,14 +196,12 @@ public abstract class AAStructureBindingModel
                 String chaincode = pdbentry.getChainCode();
                 if (chaincode != null && chaincode.length() > 0)
                 {
-                  chain = chaincode;
+                  newchains[pe][se].add(chaincode);
                   chainmaps++;
-                  break;
                 }
               }
             }
           }
-          newchains[pe][se] = chain;
           se++;
         }
         pe++;
@@ -259,7 +263,7 @@ public abstract class AAStructureBindingModel
     return sequence;
   }
 
-  public String[][] getChains()
+  public List<String>[][] getChains()
   {
     return chains;
   }
@@ -280,7 +284,7 @@ public abstract class AAStructureBindingModel
     this.sequence = sequence;
   }
 
-  protected void setChains(String[][] chains)
+  protected void setChains(List<String>[][] chains)
   {
     this.chains = chains;
   }
@@ -354,12 +358,11 @@ public abstract class AAStructureBindingModel
               new Object[]
               { Integer.valueOf(pe).toString() }));
     }
-    final String nullChain = "TheNullChain";
-    List<SequenceI> s = new ArrayList<SequenceI>();
-    List<String> c = new ArrayList<String>();
+    List<SequenceI> s = new ArrayList<>();
+    List<List<String>> c = new ArrayList<>();
     if (getChains() == null)
     {
-      setChains(new String[getPdbCount()][]);
+      setChains(new List[getPdbCount()][]);
     }
     if (getSequence()[pe] != null)
     {
@@ -374,14 +377,14 @@ public abstract class AAStructureBindingModel
           }
           else
           {
-            c.add(nullChain);
+            c.add(new ArrayList());
           }
         }
         else
         {
           if (tchain != null && tchain.length > 0)
           {
-            c.add(nullChain);
+            c.add(new ArrayList());
           }
         }
       }
@@ -393,7 +396,12 @@ public abstract class AAStructureBindingModel
         s.add(seq[i]);
         if (tchain != null && i < tchain.length)
         {
-          c.add(tchain[i] == null ? nullChain : tchain[i]);
+          List<String> clist = new ArrayList();
+          c.add(clist);
+          if (tchain[i] != null)
+          {
+            clist.add(tchain[i]);
+          }
         }
       }
     }
@@ -401,14 +409,7 @@ public abstract class AAStructureBindingModel
     getSequence()[pe] = tmp;
     if (c.size() > 0)
     {
-      String[] tch = c.toArray(new String[c.size()]);
-      for (int i = 0; i < tch.length; i++)
-      {
-        if (tch[i] == nullChain)
-        {
-          tch[i] = null;
-        }
-      }
+      List<String>[] tch = c.toArray(new List[c.size()]);
       getChains()[pe] = tch;
     }
     else
@@ -425,8 +426,8 @@ public abstract class AAStructureBindingModel
   public synchronized PDBEntry[] addSequenceAndChain(PDBEntry[] pdbe,
           SequenceI[][] seq, String[][] chns)
   {
-    List<PDBEntry> v = new ArrayList<PDBEntry>();
-    List<int[]> rtn = new ArrayList<int[]>();
+    List<PDBEntry> v = new ArrayList<>();
+    List<int[]> rtn = new ArrayList<>();
     for (int i = 0; i < getPdbCount(); i++)
     {
       v.add(getPdbEntry(i));
@@ -451,7 +452,7 @@ public abstract class AAStructureBindingModel
     {
       // expand the tied sequence[] and string[] arrays
       SequenceI[][] sqs = new SequenceI[getPdbCount()][];
-      String[][] sch = new String[getPdbCount()][];
+      List<String>[][] sch = new List[getPdbCount()][];
       System.arraycopy(getSequence(), 0, sqs, 0, getSequence().length);
       System.arraycopy(getChains(), 0, sch, 0, this.getChains().length);
       setSequence(sqs);
index 85aea40..78f9cdf 100644 (file)
@@ -34,6 +34,10 @@ import jalview.io.FileFormat;
 import jalview.io.FileLoader;
 import jalview.io.StructureFile;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 import org.testng.Assert;
 import org.testng.AssertJUnit;
 import org.testng.annotations.BeforeClass;
@@ -77,7 +81,9 @@ public class Mapping
 
       StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
       StructureFile pmap = ssm.setMapping(true, new SequenceI[] { uprot },
-              new String[] { "A" }, "test/jalview/ext/jmol/1QCF.pdb",
+              new List[]
+              { Arrays.asList(new String[] { "A" }) },
+              "test/jalview/ext/jmol/1QCF.pdb",
               DataSourceType.FILE);
       assertTrue(pmap != null);
       SequenceI protseq = pmap.getSeqsAsArray()[0];
@@ -148,8 +154,9 @@ public class Mapping
     // Associate the 1GAQ pdb file with the subsequence 'imported' from another
     // source
     StructureFile pde = ssm.setMapping(true, new SequenceI[] { sq },
-            new String[]
-    { "A" }, inFile = "examples/1gaq.txt", DataSourceType.FILE);
+            new List[]
+            { Arrays.asList(new String[] { "A" }) },
+            inFile = "examples/1gaq.txt", DataSourceType.FILE);
     assertTrue("PDB File couldn't be found", pde != null);
     StructureMapping[] mp = ssm.getMapping(inFile);
     assertTrue("No mappings made.", mp != null && mp.length > 0);
@@ -245,7 +252,8 @@ public class Mapping
     SequenceI newseq = seqf.getViewport().getAlignment().getSequenceAt(0);
     StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
     StructureFile pmap = ssm.setMapping(true, new SequenceI[] { newseq },
-            new String[] { null }, "examples/3W5V.pdb",
+            new List[]
+            { Arrays.asList(new String[0]) }, "examples/3W5V.pdb",
             DataSourceType.FILE);
     if (pmap == null)
     {
@@ -274,7 +282,8 @@ public class Mapping
     ssm.setProcessSecondaryStructure(true);
     ssm.setAddTempFacAnnot(true);
     StructureFile pmap = ssm.setMapping(true, new SequenceI[] { newseq },
-            new String[] { null }, "test/jalview/ext/jmol/1QCF.pdb",
+            new List[]
+            { new ArrayList() }, "test/jalview/ext/jmol/1QCF.pdb",
             DataSourceType.FILE);
     assertTrue(pmap != null);
     assertEquals("Original and copied sequence of different lengths.",
index a7e52ff..8273651 100644 (file)
@@ -134,7 +134,7 @@ public class StructureSelectionManagerTest
     sm.setProcessSecondaryStructure(true);
     sm.setAddTempFacAnnot(true);
     StructureFile pmap = sm.setMapping(true, new SequenceI[] { seq },
-            new String[] { null }, "examples/1gaq.txt", DataSourceType.FILE);
+            null, "examples/1gaq.txt", DataSourceType.FILE);
     assertTrue(pmap != null);
 
     assertEquals(3, pmap.getSeqs().size());
index aea3687..fb5437e 100644 (file)
@@ -237,12 +237,12 @@ public class AAStructureBindingModelTest
         
       }
     };
-    String[][] chains = binder.getChains();
+    List<String>[][] chains = binder.getChains();
     assertFalse(chains == null || chains[0] == null,
             "No chains discovered by binding");
     assertEquals(2, chains[0].length);
-    assertEquals("A", chains[0][0]);
-    assertEquals("B", chains[0][1]);
+    assertEquals("A", chains[0][0].get(0));
+    assertEquals("B", chains[0][1].get(0));
   }
   AAStructureBindingModel testee;