Merge branch 'patch/Release_2_11_1_Branch_patch_JAL-3490' into releases/Release_2_11_...
[jalview.git] / src / jalview / ws / sifts / SiftsClient.java
index e1b539e..9790f79 100644 (file)
  */
 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;
-import jalview.datamodel.DBRefSource;
-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;
-import jalview.xml.binding.sifts.Entry.Entity;
-import jalview.xml.binding.sifts.Entry.Entity.Segment;
-import jalview.xml.binding.sifts.Entry.Entity.Segment.ListMapRegion.MapRegion;
-import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue;
-import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.CrossRefDb;
-import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.ResidueDetail;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -73,6 +51,28 @@ import javax.xml.stream.XMLStreamReader;
 
 import MCview.Atom;
 import MCview.PDBChain;
+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;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.SequenceI;
+import jalview.io.BackupFiles;
+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;
+import jalview.xml.binding.sifts.Entry.Entity;
+import jalview.xml.binding.sifts.Entry.Entity.Segment;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListMapRegion.MapRegion;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.CrossRefDb;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.ResidueDetail;
 
 public class SiftsClient implements SiftsClientI
 {
@@ -108,6 +108,8 @@ public class SiftsClient implements SiftsClientI
 
   private static final int PDB_ATOM_POS = 1;
 
+  private static final int PDBE_POS = 2;
+
   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/";
@@ -121,6 +123,7 @@ public class SiftsClient implements SiftsClientI
   private enum CoordinateSys
   {
     UNIPROT("UniProt"), PDB("PDBresnum"), PDBe("PDBe");
+
     private String name;
 
     private CoordinateSys(String name)
@@ -138,6 +141,7 @@ public class SiftsClient implements SiftsClientI
   {
     NAME_SEC_STRUCTURE("nameSecondaryStructure"),
     CODE_SEC_STRUCTURE("codeSecondaryStructure"), ANNOTATION("Annotation");
+
     private String code;
 
     private ResidueDetailType(String code)
@@ -223,7 +227,7 @@ public class SiftsClient implements SiftsClientI
               SiftsSettings.getCacheThresholdInDays()))
       {
         File oldSiftsFile = new File(siftsFileName + "_old");
-        siftsFile.renameTo(oldSiftsFile);
+        BackupFiles.moveFileToFile(siftsFile, oldSiftsFile);
         try
         {
           siftsFile = downloadSiftsFile(pdbId.toLowerCase());
@@ -232,7 +236,7 @@ public class SiftsClient implements SiftsClientI
         } catch (IOException e)
         {
           e.printStackTrace();
-          oldSiftsFile.renameTo(siftsFile);
+          BackupFiles.moveFileToFile(oldSiftsFile, siftsFile);
           return new File(siftsFileName);
         }
       }
@@ -458,8 +462,8 @@ public class SiftsClient implements SiftsClientI
   public HashMap<Integer, int[]> getGreedyMapping(String entityId,
           SequenceI seq, java.io.PrintStream os) throws SiftsException
   {
-    List<Integer> omitNonObserved = new ArrayList<Integer>();
-    int nonObservedShiftIndex = 0;
+    List<Integer> omitNonObserved = new ArrayList<>();
+    int nonObservedShiftIndex = 0, pdbeNonObserved = 0;
     // System.out.println("Generating mappings for : " + entityId);
     Entity entity = null;
     entity = getEntityById(entityId);
@@ -490,7 +494,7 @@ public class SiftsClient implements SiftsClientI
     TreeMap<Integer, String> resNumMap = new TreeMap<Integer, String>();
     List<Segment> segments = entity.getSegment();
     SegmentHelperPojo shp = new SegmentHelperPojo(seq, mapping, resNumMap,
-            omitNonObserved, nonObservedShiftIndex);
+            omitNonObserved, nonObservedShiftIndex, pdbeNonObserved);
     processSegments(segments, shp);
     try
     {
@@ -512,18 +516,20 @@ public class SiftsClient implements SiftsClientI
     {
       throw new SiftsException("SIFTS mapping failed");
     }
-    // also construct a mapping object between the seq-coord sys and the PDB seq's coord sys
+    // also construct a mapping object between the seq-coord sys and the PDB
+    // seq's coord sys
 
     Integer[] keys = mapping.keySet().toArray(new Integer[0]);
     Arrays.sort(keys);
     seqStart = keys[0];
     seqEnd = keys[keys.length - 1];
-    List<int[]> from=new ArrayList<>(),to=new ArrayList<>();
-    int[]_cfrom=null,_cto=null;
+    List<int[]> from = new ArrayList<>(), to = new ArrayList<>();
+    int[] _cfrom = null, _cto = null;
     String matchedSeq = originalSeq;
-    if (seqStart != UNASSIGNED) // fixme! seqStart can map to -1 for a pdb sequence that starts <-1
+    if (seqStart != UNASSIGNED) // fixme! seqStart can map to -1 for a pdb
+                                // sequence that starts <-1
     {
-      for (int seqps:keys)
+      for (int seqps : keys)
       {
         int pdbpos = mapping.get(seqps)[PDBE_POS];
         if (pdbpos == UNASSIGNED)
@@ -531,19 +537,23 @@ public class SiftsClient implements SiftsClientI
           // not correct - pdbpos might be -1, but leave it for now
           continue;
         }
-        if (_cfrom==null || seqps!=_cfrom[1]+1)
+        if (_cfrom == null || seqps != _cfrom[1] + 1)
         {
-          _cfrom = new int[] { seqps,seqps};
+          _cfrom = new int[] { seqps, seqps };
           from.add(_cfrom);
           _cto = null; // discontinuity
-        } else {
-          _cfrom[1]= seqps;
         }
-        if (_cto==null || pdbpos!=1+_cto[1])
+        else
+        {
+          _cfrom[1] = seqps;
+        }
+        if (_cto == null || pdbpos != 1 + _cto[1])
         {
-          _cto = new int[] { pdbpos,pdbpos};
+          _cto = new int[] { pdbpos, pdbpos };
           to.add(_cto);
-        } else {
+        }
+        else
+        {
           _cto[1] = pdbpos;
         }
       }
@@ -565,8 +575,7 @@ public class SiftsClient implements SiftsClientI
       ;
 
       seqFromPdbMapping = new jalview.datamodel.Mapping(null, _cto, _cfrom,
-              1,
-              1);
+              1, 1);
       pdbStart = mapping.get(seqStart)[PDB_RES_POS];
       pdbEnd = mapping.get(seqEnd)[PDB_RES_POS];
       int orignalSeqStart = seq.getStart();
@@ -628,6 +637,7 @@ public class SiftsClient implements SiftsClientI
       List<Residue> residues = segment.getListResidue().getResidue();
       for (Residue residue : residues)
       {
+        boolean isObserved = isResidueObserved(residue);
         int pdbeIndex = getLeadingIntegerValue(residue.getDbResNum(),
                 UNASSIGNED);
         int currSeqIndex = UNASSIGNED;
@@ -638,6 +648,19 @@ public class SiftsClient implements SiftsClientI
           if (cRefDb.getDbSource().equalsIgnoreCase(DBRefSource.PDB))
           {
             pdbRefDb = cRefDb;
+            if (firstPDBResNum == UNASSIGNED)
+            {
+              firstPDBResNum = getLeadingIntegerValue(cRefDb.getDbResNum(),
+                      UNASSIGNED);
+            }
+            else
+            {
+              if (isObserved)
+              {
+                // after we find the first observed residue we just increment
+                firstPDBResNum++;
+              }
+            }
           }
           if (cRefDb.getDbCoordSys().equalsIgnoreCase(seqCoordSys.getName())
                   && isAccessionMatched(cRefDb.getDbAccessionId()))
@@ -650,35 +673,45 @@ public class SiftsClient implements SiftsClientI
             }
           }
         }
+        if (!isObserved)
+        {
+          ++pdbeNonObservedCount;
+        }
         if (seqCoordSys == seqCoordSys.PDB) // FIXME: is seqCoordSys ever PDBe
                                             // ???
         {
           // if the sequence has a primary reference to the PDB, then we are
           // dealing with a sequence extracted directly from the PDB. In that
           // case, numbering is PDBe - non-observed residues
-          currSeqIndex = pdbeIndex;
+          currSeqIndex = seq.getStart() - 1 + pdbeIndex;
         }
-        if (currSeqIndex == UNASSIGNED)
+        if (!isObserved)
         {
-          continue;
+          if (seqCoordSys != CoordinateSys.UNIPROT) // FIXME: PDB or PDBe only
+                                                    // here
+          {
+            // mapping to PDB or PDBe so we need to bookkeep for the
+            // non-observed
+            // SEQRES positions
+            omitNonObserved.add(currSeqIndex);
+            ++nonObservedShiftIndex;
+          }
         }
-        if (!isResidueObserved(residue)
-                && seqCoordSys != seqCoordSys.UNIPROT)
+        if (currSeqIndex == UNASSIGNED)
         {
-          // mapping to PDB or PDBe so we need to bookkeep for the non-observed
-          // SEQRES positions
-          omitNonObserved.add(currSeqIndex);
-          ++nonObservedShiftIndex;
+          // change in logic - unobserved residues with no currSeqIndex
+          // corresponding are still counted in both nonObservedShiftIndex and
+          // pdbeIndex...
+          continue;
         }
-
         // if (currSeqIndex >= seq.getStart() && currSeqIndex <= seqlength) //
         // true
-                                                                         // numbering
-                                                                         // is
-                                                                         // not
-                                                                         // up
-                                                                         // to
-                                                                         // seq.getEnd()
+        // numbering
+        // is
+        // not
+        // up
+        // to
+        // seq.getEnd()
         {
 
           int resNum = (pdbRefDb == null)
@@ -687,18 +720,18 @@ public class SiftsClient implements SiftsClientI
                   : getLeadingIntegerValue(pdbRefDb.getDbResNum(),
                           UNASSIGNED);
 
-          if (isResidueObserved(residue)
-                  || seqCoordSys == CoordinateSys.UNIPROT)
+          if (isObserved)
           {
             char resCharCode = ResidueProperties
                     .getSingleCharacterCode(ResidueProperties
                             .getCanonicalAminoAcid(residue.getDbResName()));
             resNumMap.put(currSeqIndex, String.valueOf(resCharCode));
-          }
 
-          mapping.put(currSeqIndex - nonObservedShiftIndex,
-                  new int[]
-                  { Integer.valueOf(resNum), UNASSIGNED });
+            int[] mappingcols = new int[] { Integer.valueOf(resNum),
+                UNASSIGNED, isObserved ? firstPDBResNum : UNASSIGNED };
+
+            mapping.put(currSeqIndex - nonObservedShiftIndex, mappingcols);
+          }
         }
       }
     }
@@ -988,15 +1021,35 @@ public class SiftsClient implements SiftsClientI
 
     private int nonObservedShiftIndex;
 
+    /**
+     * count of number of 'not observed' positions in the PDB record's SEQRES
+     * (total number of residues with coordinates == length(SEQRES) -
+     * pdbeNonObserved
+     */
+    private int pdbeNonObserved;
+
     public SegmentHelperPojo(SequenceI seq, HashMap<Integer, int[]> mapping,
             TreeMap<Integer, String> resNumMap,
-            List<Integer> omitNonObserved, int nonObservedShiftIndex)
+            List<Integer> omitNonObserved, int nonObservedShiftIndex,
+            int pdbeNonObserved)
     {
       setSeq(seq);
       setMapping(mapping);
       setResNumMap(resNumMap);
       setOmitNonObserved(omitNonObserved);
       setNonObservedShiftIndex(nonObservedShiftIndex);
+      setPdbeNonObserved(pdbeNonObserved);
+
+    }
+
+    public void setPdbeNonObserved(int pdbeNonObserved2)
+    {
+      this.pdbeNonObserved = pdbeNonObserved2;
+    }
+
+    public int getPdbeNonObserved()
+    {
+      return pdbeNonObserved;
     }
 
     public SequenceI getSeq()
@@ -1048,6 +1101,7 @@ public class SiftsClient implements SiftsClientI
     {
       this.nonObservedShiftIndex = nonObservedShiftIndex;
     }
+
   }
 
   @Override