Merge branch 'develop' into features/JAL-2393customMatrices
[jalview.git] / src / jalview / ws / sifts / SiftsClient.java
index dad2b3f..0e9e888 100644 (file)
@@ -21,6 +21,8 @@
 package jalview.ws.sifts;
 
 import jalview.analysis.AlignSeq;
+import jalview.analysis.scoremodels.ScoreMatrix;
+import jalview.analysis.scoremodels.ScoreModels;
 import jalview.api.DBRefEntryI;
 import jalview.api.SiftsClientI;
 import jalview.datamodel.DBRefEntry;
@@ -29,6 +31,7 @@ import jalview.datamodel.SequenceI;
 import jalview.io.StructureFile;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureMapping;
+import jalview.util.Comparison;
 import jalview.util.DBRefUtils;
 import jalview.util.Format;
 import jalview.xml.binding.sifts.Entry;
@@ -73,6 +76,12 @@ import MCview.PDBChain;
 
 public class SiftsClient implements SiftsClientI
 {
+  /*
+   * for use in mocking out file fetch for tests only
+   * - reset to null after testing!
+   */
+  private static File mockSiftsFile;
+
   private Entry siftsEntry;
 
   private StructureFile pdb;
@@ -149,7 +158,6 @@ public class SiftsClient implements SiftsClientI
     siftsEntry = parseSIFTs(siftsFile);
   }
 
-
   /**
    * Parse the given SIFTs File and return a JAXB POJO of parsed data
    * 
@@ -187,6 +195,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);
@@ -212,6 +228,10 @@ public class SiftsClient implements SiftsClientI
           return new File(siftsFileName);
         }
       }
+      else
+      {
+        return siftsFile;
+      }
     }
     try
     {
@@ -276,21 +296,23 @@ public class SiftsClient implements SiftsClientI
     {
       siftsDownloadDir.mkdirs();
     }
-      // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
-      URL url = new URL(siftsFileFTPURL);
-      URLConnection conn = url.openConnection();
-      InputStream inputStream = conn.getInputStream();
-      FileOutputStream outputStream = new FileOutputStream(
-              downloadedSiftsFile);
-      byte[] buffer = new byte[BUFFER_SIZE];
-      int bytesRead = -1;
-      while ((bytesRead = inputStream.read(buffer)) != -1)
-      {
-        outputStream.write(buffer, 0, bytesRead);
-      }
-      outputStream.close();
-      inputStream.close();
-      // System.out.println(">>> File downloaded : " + downloadedSiftsFile);
+    // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
+    // long now = System.currentTimeMillis();
+    URL url = new URL(siftsFileFTPURL);
+    URLConnection conn = url.openConnection();
+    InputStream inputStream = conn.getInputStream();
+    FileOutputStream outputStream = new FileOutputStream(
+            downloadedSiftsFile);
+    byte[] buffer = new byte[BUFFER_SIZE];
+    int bytesRead = -1;
+    while ((bytesRead = inputStream.read(buffer)) != -1)
+    {
+      outputStream.write(buffer, 0, bytesRead);
+    }
+    outputStream.close();
+    inputStream.close();
+//    System.out.println(">>> File downloaded : " + downloadedSiftsFile
+//            + " took " + (System.currentTimeMillis() - now) + "ms");
     return new File(downloadedSiftsFile);
   }
 
@@ -324,25 +346,24 @@ public class SiftsClient implements SiftsClientI
   public DBRefEntryI getValidSourceDBRef(SequenceI seq)
           throws SiftsException
   {
-    DBRefEntry[] dbRefs = seq.getDBRefs();
-    if (dbRefs == null || dbRefs.length < 1)
+    List<DBRefEntry> dbRefs = seq.getPrimaryDBRefs();
+    if (dbRefs == null || dbRefs.size() < 1)
     {
       throw new SiftsException(
               "Source DBRef could not be determined. DBRefs might not have been retrieved.");
     }
 
-    for (DBRefEntryI dbRef : dbRefs)
+    for (DBRefEntry dbRef : dbRefs)
     {
       if (dbRef == null || dbRef.getAccessionId() == null
               || dbRef.getSource() == null)
       {
         continue;
       }
+      String canonicalSource = DBRefUtils.getCanonicalName(dbRef
+              .getSource());
       if (isValidDBRefEntry(dbRef)
-              && dbRef.isPrimary()
-              && (DBRefUtils.getCanonicalName(dbRef.getSource())
-                      .equalsIgnoreCase(DBRefSource.UNIPROT) || DBRefUtils
-                      .getCanonicalName(dbRef.getSource())
+              && (canonicalSource.equalsIgnoreCase(DBRefSource.UNIPROT) || canonicalSource
                       .equalsIgnoreCase(DBRefSource.PDB)))
       {
         return dbRef;
@@ -392,8 +413,8 @@ public class SiftsClient implements SiftsClientI
           String pdbFile, String chain) throws SiftsException
   {
     structId = (chain == null) ? pdbId : pdbId + "|" + chain;
-    System.out.println("Getting mapping for: " + pdbId + "|" + chain
-            + " : seq- " + seq.getName());
+    System.out.println("Getting SIFTS mapping for " + structId + ": seq "
+            + seq.getName());
 
     final StringBuilder mappingDetails = new StringBuilder(128);
     PrintStream ps = new PrintStream(System.out)
@@ -472,12 +493,13 @@ public class SiftsClient implements SiftsClientI
     int pdbStart = UNASSIGNED;
     int pdbEnd = UNASSIGNED;
 
-    Integer[] keys = mapping.keySet().toArray(new Integer[0]);
-    Arrays.sort(keys);
-    if (keys.length < 1)
+    if (mapping.isEmpty())
     {
-      throw new SiftsException(">>> Empty SIFTS mapping generated!!");
+      throw new SiftsException("SIFTS mapping failed");
     }
+
+    Integer[] keys = mapping.keySet().toArray(new Integer[0]);
+    Arrays.sort(keys);
     seqStart = keys[0];
     seqEnd = keys[keys.length - 1];
 
@@ -511,13 +533,13 @@ public class SiftsClient implements SiftsClientI
     if (os != null)
     {
       MappingOutputPojo mop = new MappingOutputPojo();
-      mop.setSeqStart(pdbStart);
-      mop.setSeqEnd(pdbEnd);
+      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());
 
@@ -587,8 +609,12 @@ public class SiftsClient implements SiftsClientI
                     .getDbResNum());
           } catch (NumberFormatException nfe)
           {
-            resNum = (pdbRefDb == null) ? Integer.valueOf(residue
-                    .getDbResNum()) : Integer.valueOf(pdbRefDb
+            if (pdbRefDb == null || pdbRefDb.getDbResNum().equals("null"))
+            {
+              resNum = UNASSIGNED;
+              continue;
+            }
+            resNum = Integer.valueOf(pdbRefDb
                     .getDbResNum().split("[a-zA-Z]")[0]);
             continue;
           }
@@ -612,6 +638,7 @@ public class SiftsClient implements SiftsClientI
       }
     }
   }
+
   /**
    * 
    * @param chainId
@@ -763,8 +790,6 @@ public class SiftsClient implements SiftsClientI
     }
   }
 
-
-
   @Override
   public Entity getEntityById(String id) throws SiftsException
   {
@@ -828,6 +853,10 @@ public class SiftsClient implements SiftsClientI
 
     if (sPojo[0].entityId != null)
     {
+      if (sPojo[0].pid < 1)
+      {
+        return null;
+      }
       for (Entity entity : entities)
       {
         if (!entity.getEntityId().equalsIgnoreCase(sPojo[0].entityId))
@@ -934,7 +963,7 @@ public class SiftsClient implements SiftsClientI
   }
 
   @Override
-  public StringBuffer getMappingOutput(MappingOutputPojo mp)
+  public StringBuilder getMappingOutput(MappingOutputPojo mp)
           throws SiftsException
   {
     String seqRes = mp.getSeqResidue();
@@ -956,7 +985,7 @@ public class SiftsClient implements SiftsClientI
     int nochunks = ((seqRes.length()) / len)
             + ((seqRes.length()) % len > 0 ? 1 : 0);
     // output mappings
-    StringBuffer output = new StringBuffer();
+    StringBuilder output = new StringBuilder(512);
     output.append(NEWLINE);
     output.append("Sequence \u27f7 Structure mapping details").append(
             NEWLINE);
@@ -977,6 +1006,7 @@ public class SiftsClient implements SiftsClientI
     output.append(String.valueOf(pdbEnd));
     output.append(NEWLINE).append(NEWLINE);
 
+    ScoreMatrix pam250 = ScoreModels.getInstance().getPam250();
     int matchedSeqCount = 0;
     for (int j = 0; j < nochunks; j++)
     {
@@ -995,25 +1025,29 @@ public class SiftsClient implements SiftsClientI
       output.append(NEWLINE);
       output.append(new Format("%" + (maxid) + "s").form(" ")).append(" ");
 
-      // Print out the matching chars
+      /*
+       * Print out the match symbols:
+       * | for exact match (ignoring case)
+       * . if PAM250 score is positive
+       * else a space
+       */
       for (int i = 0; i < len; i++)
       {
         try
         {
           if ((i + (j * len)) < seqRes.length())
           {
-            if (seqRes.charAt(i + (j * len)) == strRes
-                    .charAt(i + (j * len))
-                    && !jalview.util.Comparison.isGap(seqRes.charAt(i
-                            + (j * len))))
+            char c1 = seqRes.charAt(i + (j * len));
+            char c2 = strRes.charAt(i + (j * len));
+            boolean sameChar = Comparison.isSameResidue(c1, c2, false);
+            if (sameChar && !Comparison.isGap(c1))
             {
               matchedSeqCount++;
               output.append("|");
             }
             else if (type.equals("pep"))
             {
-              if (ResidueProperties.getPAM250(seqRes.charAt(i + (j * len)),
-                      strRes.charAt(i + (j * len))) > 0)
+              if (pam250.getPairwiseScore(c1, c2) > 0)
               {
                 output.append(".");
               }
@@ -1086,4 +1120,9 @@ public class SiftsClient implements SiftsClientI
     return siftsEntry.getDbVersion();
   }
 
+  public static void setMockSiftsFile(File file)
+  {
+    mockSiftsFile = file;
+  }
+
 }