JAL-2434 omit unmapped positions from mapping
[jalview.git] / src / jalview / ws / sifts / SiftsClient.java
index 83af0e0..30ac0ae 100644 (file)
@@ -29,6 +29,9 @@ import jalview.datamodel.SequenceI;
 import jalview.io.StructureFile;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureMapping;
+import jalview.structure.StructureMappingClient;
+import jalview.structures.models.MappingOutputModel;
+import jalview.util.Comparison;
 import jalview.util.DBRefUtils;
 import jalview.util.Format;
 import jalview.xml.binding.sifts.Entry;
@@ -52,7 +55,6 @@ import java.nio.file.Path;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
@@ -68,14 +70,20 @@ import javax.xml.bind.Unmarshaller;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamReader;
 
-import MCview.Atom;
-import MCview.PDBChain;
-
-public class SiftsClient implements SiftsClientI
+public class SiftsClient extends StructureMappingClient implements
+        SiftsClientI
 {
-  private Entry siftsEntry;
+  /*
+   * for use in mocking out file fetch for tests only
+   * - reset to null after testing!
+   */
+  private static File mockSiftsFile;
+
+  private static final int UNASSIGNED = StructureMapping.UNASSIGNED; // -1
 
-  private StructureFile pdb;
+  private static final int PDB_RES_POS = StructureMapping.PDB_RES_NUM_INDEX; // 0
+
+  private Entry siftsEntry;
 
   private String pdbId;
 
@@ -85,12 +93,6 @@ public class SiftsClient implements SiftsClientI
 
   private static final int BUFFER_SIZE = 4096;
 
-  public static final int UNASSIGNED = -1;
-
-  private static final int PDB_RES_POS = 0;
-
-  private static final int PDB_ATOM_POS = 1;
-
   private static final String NOT_OBSERVED = "Not_Observed";
 
   private static final String SIFTS_FTP_BASE_URL = "http://ftp.ebi.ac.uk/pub/databases/msd/sifts/xml/";
@@ -141,10 +143,10 @@ public class SiftsClient implements SiftsClientI
    * @param pdbId
    * @throws SiftsException
    */
-  public SiftsClient(StructureFile pdb) throws SiftsException
+  public SiftsClient(StructureFile structureFile) throws SiftsException
   {
-    this.pdb = pdb;
-    this.pdbId = pdb.getId();
+    this.structureFile = structureFile;
+    this.pdbId = structureFile.getId();
     File siftsFile = getSiftsFile(pdbId);
     siftsEntry = parseSIFTs(siftsFile);
   }
@@ -186,6 +188,14 @@ public class SiftsClient implements SiftsClientI
    */
   public static File getSiftsFile(String pdbId) throws SiftsException
   {
+    /*
+     * return mocked file if it has been set
+     */
+    if (mockSiftsFile != null)
+    {
+      return mockSiftsFile;
+    }
+
     String siftsFileName = SiftsSettings.getSiftDownloadDirectory()
             + pdbId.toLowerCase() + ".xml.gz";
     File siftsFile = new File(siftsFileName);
@@ -211,6 +221,10 @@ public class SiftsClient implements SiftsClientI
           return new File(siftsFileName);
         }
       }
+      else
+      {
+        return siftsFile;
+      }
     }
     try
     {
@@ -276,6 +290,7 @@ public class SiftsClient implements SiftsClientI
       siftsDownloadDir.mkdirs();
     }
     // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
+    // long now = System.currentTimeMillis();
     URL url = new URL(siftsFileFTPURL);
     URLConnection conn = url.openConnection();
     InputStream inputStream = conn.getInputStream();
@@ -289,7 +304,8 @@ public class SiftsClient implements SiftsClientI
     }
     outputStream.close();
     inputStream.close();
-    // System.out.println(">>> File downloaded : " + downloadedSiftsFile);
+//    System.out.println(">>> File downloaded : " + downloadedSiftsFile
+//            + " took " + (System.currentTimeMillis() - now) + "ms");
     return new File(downloadedSiftsFile);
   }
 
@@ -386,8 +402,9 @@ public class SiftsClient implements SiftsClientI
   }
 
   @Override
-  public StructureMapping getSiftsStructureMapping(SequenceI seq,
-          String pdbFile, String chain) throws SiftsException
+  public StructureMapping getStructureMapping(SequenceI seq,
+          String pdbFile, String chain) throws Exception,
+          StructureMappingException
   {
     structId = (chain == null) ? pdbId : pdbId + "|" + chain;
     System.out.println("Getting SIFTS mapping for " + structId + ": seq "
@@ -418,7 +435,8 @@ public class SiftsClient implements SiftsClientI
 
   @Override
   public HashMap<Integer, int[]> getGreedyMapping(String entityId,
-          SequenceI seq, java.io.PrintStream os) throws SiftsException
+          SequenceI seq, java.io.PrintStream os) throws SiftsException,
+          StructureMappingException
   {
     List<Integer> omitNonObserved = new ArrayList<Integer>();
     int nonObservedShiftIndex = 0;
@@ -509,14 +527,14 @@ public class SiftsClient implements SiftsClientI
 
     if (os != null)
     {
-      MappingOutputPojo mop = new MappingOutputPojo();
-      mop.setSeqStart(pdbStart);
-      mop.setSeqEnd(pdbEnd);
+      MappingOutputModel mop = new MappingOutputModel();
+      mop.setSeqStart(seqStart);
+      mop.setSeqEnd(seqEnd);
       mop.setSeqName(seq.getName());
       mop.setSeqResidue(matchedSeq);
 
-      mop.setStrStart(seqStart);
-      mop.setStrEnd(seqEnd);
+      mop.setStrStart(pdbStart);
+      mop.setStrEnd(pdbEnd);
       mop.setStrName(structId);
       mop.setStrResidue(targetStrucSeqs.toString());
 
@@ -612,68 +630,6 @@ public class SiftsClient implements SiftsClientI
     }
   }
 
-  /**
-   * 
-   * @param chainId
-   *          Target chain to populate mapping of its atom positions.
-   * @param mapping
-   *          Two dimension array of residue index versus atom position
-   * @throws IllegalArgumentException
-   *           Thrown if chainId or mapping is null
-   * @throws SiftsException
-   */
-  void populateAtomPositions(String chainId, Map<Integer, int[]> mapping)
-          throws IllegalArgumentException, SiftsException
-  {
-    try
-    {
-      PDBChain chain = pdb.findChain(chainId);
-
-      if (chain == null || mapping == null)
-      {
-        throw new IllegalArgumentException(
-                "Chain id or mapping must not be null.");
-      }
-      for (int[] map : mapping.values())
-      {
-        if (map[PDB_RES_POS] != UNASSIGNED)
-        {
-          map[PDB_ATOM_POS] = getAtomIndex(map[PDB_RES_POS], chain.atoms);
-        }
-      }
-    } catch (NullPointerException e)
-    {
-      throw new SiftsException(e.getMessage());
-    } catch (Exception e)
-    {
-      throw new SiftsException(e.getMessage());
-    }
-  }
-
-  /**
-   * 
-   * @param residueIndex
-   *          The residue index used for the search
-   * @param atoms
-   *          A collection of Atom to search
-   * @return atom position for the given residue index
-   */
-  int getAtomIndex(int residueIndex, Collection<Atom> atoms)
-  {
-    if (atoms == null)
-    {
-      throw new IllegalArgumentException(
-              "atoms collection must not be null!");
-    }
-    for (Atom atom : atoms)
-    {
-      if (atom.resNumber == residueIndex)
-      {
-        return atom.atomIndex;
-      }
-    }
-    return UNASSIGNED;
-  }
 
   /**
    * Checks if the residue instance is marked 'Not_observed' or not
@@ -936,8 +892,8 @@ public class SiftsClient implements SiftsClientI
   }
 
   @Override
-  public StringBuffer getMappingOutput(MappingOutputPojo mp)
-          throws SiftsException
+  public StringBuffer getMappingOutput(MappingOutputModel mp)
+          throws StructureMappingException
   {
     String seqRes = mp.getSeqResidue();
     String seqName = mp.getSeqName();
@@ -1004,8 +960,10 @@ public class SiftsClient implements SiftsClientI
         {
           if ((i + (j * len)) < seqRes.length())
           {
-            if (seqRes.charAt(i + (j * len)) == strRes
-                    .charAt(i + (j * len))
+            boolean sameChar = Comparison.isSameResidue(
+                    seqRes.charAt(i + (j * len)),
+                    strRes.charAt(i + (j * len)), false);
+            if (sameChar
                     && !jalview.util.Comparison.isGap(seqRes.charAt(i
                             + (j * len))))
             {
@@ -1050,7 +1008,8 @@ public class SiftsClient implements SiftsClientI
     float pid = (float) matchedSeqCount / seqRes.length() * 100;
     if (pid < SiftsSettings.getFailSafePIDThreshold())
     {
-      throw new SiftsException(">>> Low PID detected for SIFTs mapping...");
+      throw new StructureMappingException(
+              ">>> Low PID detected for SIFTs mapping...");
     }
     output.append("Length of alignment = " + seqRes.length()).append(
             NEWLINE);
@@ -1088,4 +1047,9 @@ public class SiftsClient implements SiftsClientI
     return siftsEntry.getDbVersion();
   }
 
+  public static void setMockSiftsFile(File file)
+  {
+    mockSiftsFile = file;
+  }
+
 }