Merge branch 'develop' into features/ssFromPDBEntry
authorJim Procter <jprocter@dundee.ac.uk>
Thu, 30 Oct 2014 17:05:36 +0000 (17:05 +0000)
committerJim Procter <jprocter@dundee.ac.uk>
Thu, 30 Oct 2014 17:05:36 +0000 (17:05 +0000)
17 files changed:
src/MCview/PDBChain.java
src/MCview/PDBfile.java
src/jalview/analysis/AlignSeq.java
src/jalview/appletgui/AlignFrame.java
src/jalview/bin/JalviewLite.java
src/jalview/datamodel/AlignmentAnnotation.java
src/jalview/ext/jmol/PDBFileWithJmol.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AssociatePdbFileWithSeq.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/Jalview2XML_V1.java
src/jalview/gui/PopupMenu.java
src/jalview/io/FileLoader.java
src/jalview/schemes/AnnotationColourGradient.java
src/jalview/structure/StructureMapping.java
src/jalview/structure/StructureSelectionManager.java
test/jalview/structure/Mapping.java [new file with mode: 0644]

index 6055a5b..5dd38a4 100755 (executable)
@@ -23,6 +23,7 @@ package MCview;
 import jalview.analysis.AlignSeq;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.Mapping;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
@@ -53,7 +54,16 @@ public class PDBChain
 
   public int offset;
 
-  public Sequence sequence;
+  /**
+   * sequence is the sequence extracted by the chain parsing code
+   */
+  public SequenceI sequence;
+
+  /**
+   * shadow is the sequence created by any other parsing processes (e.g. Jmol,
+   * RNAview)
+   */
+  public SequenceI shadow = null;
 
   public boolean isNa = false;
 
@@ -80,6 +90,8 @@ public class PDBChain
    */
   protected String newline = System.getProperty("line.separator");
 
+  public Mapping shadowMap;
+
   public void setNewlineString(String nl)
   {
     newline = nl;
@@ -493,11 +505,51 @@ public class PDBChain
   public void transferResidueAnnotation(StructureMapping mapping)
   {
     SequenceI sq = mapping.getSequence();
+    SequenceI dsq = sq;
     if (sq != null)
     {
-      if (sequence != null && sequence.getAnnotation() != null)
+      while (dsq.getDatasetSequence() != null)
+      {
+        dsq = dsq.getDatasetSequence();
+      }
+      // any annotation will be transferred onto the dataset sequence
+
+      if (shadow != null && shadow.getAnnotation() != null)
       {
 
+        for (AlignmentAnnotation ana : shadow.getAnnotation())
+        {
+          List<AlignmentAnnotation> transfer = sq.getAlignmentAnnotations(
+                  ana.getCalcId(), ana.label);
+          if (transfer == null || transfer.size() == 0)
+          {
+            ana.liftOver(sequence, shadowMap);
+            mapping.transfer(ana);
+          }
+          else
+          {
+            continue;
+          }
+        }
+      }
+      else
+      {
+      if (sequence != null && sequence.getAnnotation() != null)
+      {
+        for (AlignmentAnnotation ana : sequence.getAnnotation())
+        {
+          List<AlignmentAnnotation> transfer = sq.getAlignmentAnnotations(
+                  ana.getCalcId(), ana.label);
+          if (transfer == null || transfer.size() == 0)
+          {
+            mapping.transfer(ana);
+          }
+          else
+          {
+            continue;
+          }
+        }
+      }
       }
       float min = -1, max = 0;
       Annotation[] an = new Annotation[sq.getEnd() - sq.getStart() + 1];
index a99f172..11e7188 100755 (executable)
@@ -33,11 +33,12 @@ import java.awt.Color;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Vector;
 
 public class PDBfile extends jalview.io.AlignFile
 {
-  public Vector chains;
+  public Vector<PDBChain> chains;
 
   public String id;
 
@@ -181,15 +182,15 @@ public class PDBfile extends jalview.io.AlignFile
       }
       for (int i = 0; i < chains.size(); i++)
       {
-        SequenceI dataset = ((PDBChain) chains.elementAt(i)).sequence;
+        SequenceI dataset = chains.elementAt(i).sequence;
         dataset.setName(id + "|" + dataset.getName());
         PDBEntry entry = new PDBEntry();
         entry.setId(id);
         entry.setProperty(new Hashtable());
-        if (((PDBChain) chains.elementAt(i)).id != null)
+        if (chains.elementAt(i).id != null)
         {
           entry.getProperty().put("CHAIN",
-                  ((PDBChain) chains.elementAt(i)).id);
+                  chains.elementAt(i).id);
         }
         if (inFile != null)
         {
@@ -338,13 +339,43 @@ public class PDBfile extends jalview.io.AlignFile
             sq.getPDBId().clear();
           }
         }
-        AlignSeq.replaceMatchingSeqsWith(seqs, annotations, prot, al, AlignSeq.PEP, false);
+        replaceAndUpdateChains(prot, al, AlignSeq.PEP, false);
       }
     } catch (ClassNotFoundException q)
     {
     }
   }
 
+  private void replaceAndUpdateChains(ArrayList<SequenceI> prot,
+          AlignmentI al, String pep, boolean b)
+  {
+    List<List<? extends Object>> replaced = AlignSeq
+            .replaceMatchingSeqsWith(seqs,
+            annotations, prot, al, AlignSeq.PEP, false);
+    for (PDBChain ch : chains)
+    {
+      int p = 0;
+      for (SequenceI sq : (List<SequenceI>) replaced.get(0))
+      {
+        p++;
+        if (sq == ch.sequence || sq.getDatasetSequence() == ch.sequence)
+        {
+          p = -p;
+          break;
+        }
+      }
+      if (p < 0)
+      {
+        p = -p - 1;
+        // set shadow entry for chains
+        ch.shadow = (SequenceI) replaced.get(1).get(p);
+        ch.shadowMap = ((AlignSeq) replaced.get(2)
+.get(p))
+                .getMappingFromS1(false);
+      }
+    }
+  }
+
   private void processPdbFileWithAnnotate3d(ArrayList<SequenceI> rna)
           throws Exception
   {
@@ -370,14 +401,20 @@ public class PDBfile extends jalview.io.AlignFile
         {
           if (sq.getDatasetSequence() != null)
           {
-            sq.getDatasetSequence().getPDBId().clear();
+            if (sq.getDatasetSequence().getPDBId() != null)
+            {
+              sq.getDatasetSequence().getPDBId().clear();
+            }
           }
           else
           {
-            sq.getPDBId().clear();
+            if (sq.getPDBId() != null)
+            {
+              sq.getPDBId().clear();
+            }
           }
         }
-        AlignSeq.replaceMatchingSeqsWith(seqs, annotations, rna, al, AlignSeq.DNA, false);
+        replaceAndUpdateChains(rna, al, AlignSeq.DNA, false);
       }
     } catch (ClassNotFoundException x)
     {
@@ -406,7 +443,7 @@ public class PDBfile extends jalview.io.AlignFile
   {
     for (int i = 0; i < chains.size(); i++)
     {
-      ((PDBChain) chains.elementAt(i)).makeResidueList();
+      chains.elementAt(i).makeResidueList();
     }
   }
 
@@ -414,7 +451,7 @@ public class PDBfile extends jalview.io.AlignFile
   {
     for (int i = 0; i < chains.size(); i++)
     {
-      ((PDBChain) chains.elementAt(i)).makeCaBondList();
+      chains.elementAt(i).makeCaBondList();
     }
   }
 
@@ -422,9 +459,9 @@ public class PDBfile extends jalview.io.AlignFile
   {
     for (int i = 0; i < chains.size(); i++)
     {
-      if (((PDBChain) chains.elementAt(i)).id.equals(id))
+      if (chains.elementAt(i).id.equals(id))
       {
-        return (PDBChain) chains.elementAt(i);
+        return chains.elementAt(i);
       }
     }
 
@@ -435,7 +472,7 @@ public class PDBfile extends jalview.io.AlignFile
   {
     for (int i = 0; i < chains.size(); i++)
     {
-      ((PDBChain) chains.elementAt(i)).setChargeColours();
+      chains.elementAt(i).setChargeColours();
     }
   }
 
@@ -443,7 +480,7 @@ public class PDBfile extends jalview.io.AlignFile
   {
     for (int i = 0; i < chains.size(); i++)
     {
-      ((PDBChain) chains.elementAt(i)).setChainColours(cs);
+      chains.elementAt(i).setChainColours(cs);
     }
   }
 
@@ -451,7 +488,7 @@ public class PDBfile extends jalview.io.AlignFile
   {
     for (int i = 0; i < chains.size(); i++)
     {
-      ((PDBChain) chains.elementAt(i)).setChainColours(Color.getHSBColor(
+      chains.elementAt(i).setChainColours(Color.getHSBColor(
               1.0f / i, .4f, 1.0f));
     }
   }
index f5afa9c..c546310 100755 (executable)
@@ -1069,11 +1069,19 @@ public class AlignSeq
    * @param ochains
    * @param al
    * @param dnaOrProtein
-   * @param removeOldAnnots when true, old annotation is cleared before new annotation transferred
+   * @param removeOldAnnots
+   *          when true, old annotation is cleared before new annotation
+   *          transferred
+   * @return List<List<SequenceI> originals, List<SequenceI> replacement,
+   *         List<AlignSeq> alignment between each>
    */
-  public static void replaceMatchingSeqsWith(List<SequenceI> seqs, List<AlignmentAnnotation> annotations, List<SequenceI> ochains,
+  public static List<List<? extends Object>> replaceMatchingSeqsWith(
+          List<SequenceI> seqs, List<AlignmentAnnotation> annotations,
+          List<SequenceI> ochains,
           AlignmentI al, String dnaOrProtein, boolean removeOldAnnots)
   {
+    List<SequenceI> orig = new ArrayList<SequenceI>(), repl = new ArrayList<SequenceI>();
+    List<AlignSeq> aligs = new ArrayList<AlignSeq>();
     if (al != null && al.getHeight() > 0)
     {
       ArrayList<SequenceI> matches = new ArrayList<SequenceI>();
@@ -1108,10 +1116,13 @@ public class AlignSeq
         if ((q = ochains.indexOf(sp)) > -1)
         {
           seqs.set(p, sq = matches.get(q));
+          orig.add(sp);
+          repl.add(sq);
           sq.setName(sp.getName());
           sq.setDescription(sp.getDescription());
           Mapping sp2sq;
           sq.transferAnnotation(sp, sp2sq = aligns.get(q).getMappingFromS1(false));
+          aligs.add(aligns.get(q));
           int inspos = -1;
           for (int ap = 0; ap < annotations.size();)
           {
@@ -1142,6 +1153,7 @@ public class AlignSeq
         }
       }
     }
+    return Arrays.asList(orig, repl, aligs);
   }
 
   /**
index f267858..34ec2cf 100644 (file)
@@ -21,7 +21,6 @@
 package jalview.appletgui;
 
 import jalview.analysis.AlignmentSorter;
-import jalview.analysis.Conservation;
 import jalview.api.AlignViewControllerGuiI;
 import jalview.api.AlignViewControllerI;
 import jalview.api.SequenceStructureBinding;
@@ -56,7 +55,6 @@ import jalview.schemes.PIDColourScheme;
 import jalview.schemes.PurinePyrimidineColourScheme;
 import jalview.schemes.RNAHelicesColourChooser;
 import jalview.schemes.RNAInteractionColourScheme;
-import jalview.schemes.ResidueProperties;
 import jalview.schemes.StrandColourScheme;
 import jalview.schemes.TCoffeeColourScheme;
 import jalview.schemes.TaylorColourScheme;
@@ -324,7 +322,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
                     .getKeyCode() >= KeyEvent.VK_NUMPAD0 && evt
                     .getKeyCode() <= KeyEvent.VK_NUMPAD9))
             && Character.isDigit(evt.getKeyChar()))
+    {
       alignPanel.seqPanel.numberPressed(evt.getKeyChar());
+    }
 
     switch (evt.getKeyCode())
     {
@@ -385,16 +385,24 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
     case KeyEvent.VK_LEFT:
       if (evt.isAltDown() || !viewport.cursorMode)
+      {
         slideSequences(false, alignPanel.seqPanel.getKeyboardNo1());
+      }
       else
+      {
         alignPanel.seqPanel.moveCursor(-1, 0);
+      }
       break;
 
     case KeyEvent.VK_RIGHT:
       if (evt.isAltDown() || !viewport.cursorMode)
+      {
         slideSequences(true, alignPanel.seqPanel.getKeyboardNo1());
+      }
       else
+      {
         alignPanel.seqPanel.moveCursor(1, 0);
+      }
       break;
 
     case KeyEvent.VK_SPACE:
@@ -1257,7 +1265,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     else
     {
       if (features == null)
+      {
         features = "";
+      }
     }
 
     return features;
@@ -1573,7 +1583,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     for (int i = 0; i < viewport.getAlignment().getHeight(); i++)
     {
       if (!sg.contains(viewport.getAlignment().getSequenceAt(i)))
+      {
         invertGroup.addElement(viewport.getAlignment().getSequenceAt(i));
+      }
     }
 
     SequenceI[] seqs1 = sg.toArray(new SequenceI[sg.size()]);
@@ -1581,30 +1593,44 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     SequenceI[] seqs2 = invertGroup.toArray(new SequenceI[invertGroup
             .size()]);
     for (int i = 0; i < invertGroup.size(); i++)
+    {
       seqs2[i] = invertGroup.elementAt(i);
+    }
 
     SlideSequencesCommand ssc;
     if (right)
+    {
       ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1,
               size, viewport.getGapCharacter());
+    }
     else
+    {
       ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2,
               size, viewport.getGapCharacter());
+    }
 
     int groupAdjustment = 0;
     if (ssc.getGapsInsertedBegin() && right)
     {
       if (viewport.cursorMode)
+      {
         alignPanel.seqPanel.moveCursor(size, 0);
+      }
       else
+      {
         groupAdjustment = size;
+      }
     }
     else if (!ssc.getGapsInsertedBegin() && !right)
     {
       if (viewport.cursorMode)
+      {
         alignPanel.seqPanel.moveCursor(-size, 0);
+      }
       else
+      {
         groupAdjustment = -size;
+      }
     }
 
     if (groupAdjustment != 0)
@@ -1625,7 +1651,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     }
 
     if (!appendHistoryItem)
+    {
       addHistoryItem(ssc);
+    }
 
     repaint();
   }
@@ -3656,6 +3684,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
         }
         pdbentry.getProperty().put("protocol", protocol);
         toaddpdb.addPDBId(pdbentry);
+        alignPanel.getStructureSelectionManager()
+                .registerPDBEntry(pdbentry);
       }
     }
     return true;
index ef1e16e..0abd31b 100644 (file)
@@ -2076,10 +2076,12 @@ public class JalviewLite extends Applet implements
             {
               String sequence = applet.getParameter("PDBSEQ");
               if (sequence != null)
+              {
                 seqs = new SequenceI[]
                 { matcher == null ? (Sequence) newAlignFrame
                         .getAlignViewport().getAlignment()
                         .findName(sequence) : matcher.findIdMatch(sequence) };
+              }
 
             }
             else
@@ -2139,6 +2141,8 @@ public class JalviewLite extends Applet implements
                 if (seqs[i] != null)
                 {
                   ((Sequence) seqs[i]).addPDBId(pdb);
+                  StructureSelectionManager.getStructureSelectionManager(
+                          applet).registerPDBEntry(pdb);
                 }
                 else
                 {
@@ -2323,7 +2327,9 @@ public class JalviewLite extends Applet implements
     // note separator local variable intentionally masks object field
     int seplen = separator.length();
     if (list == null || list.equals("") || list.equals(separator))
+    {
       return null;
+    }
     java.util.Vector jv = new Vector();
     int cp = 0, pos;
     while ((pos = list.indexOf(separator, cp)) > cp)
index c0d911e..4159ddb 100755 (executable)
@@ -1182,6 +1182,76 @@ public class AlignmentAnnotation
         // trim positions
       }
     }
+  }
 
+  /**
+   * like liftOver but more general.
+   * 
+   * Takes an array of int pairs that will be used to update the internal
+   * sequenceMapping and so shuffle the annotated positions
+   * 
+   * @param newref
+   *          - new sequence reference for the annotation row - if null,
+   *          sequenceRef is left unchanged
+   * @param mapping
+   *          array of ints containing corresponding positions
+   * @param from
+   *          - column for current coordinate system (-1 for index+1)
+   * @param to
+   *          - column for destination coordinate system (-1 for index+1)
+   * @param idxoffset
+   *          - offset added to index when referencing either coordinate system
+   * @note no checks are made as to whether from and/or to are sensible
+   * @note caller should add the remapped annotation to newref if they have not
+   *       already
+   */
+  public void remap(SequenceI newref, int[][] mapping, int from, int to,
+          int idxoffset)
+  {
+    if (mapping != null)
+    {
+      Hashtable<Integer, Annotation> old = sequenceMapping, remap = new Hashtable<Integer, Annotation>();
+      int index = -1;
+      for (int mp[] : mapping)
+      {
+        if (index++ < 0)
+        {
+          continue;
+        }
+        Annotation ann = null;
+        if (from == -1)
+        {
+          ann = sequenceMapping.get(Integer.valueOf(idxoffset + index));
+        }
+        else
+        {
+          if (mp != null && mp.length > from)
+          {
+            ann = sequenceMapping.get(Integer.valueOf(mp[from]));
+          }
+        }
+        if (ann != null)
+        {
+          if (to == -1)
+          {
+            remap.put(Integer.valueOf(idxoffset + index), ann);
+          }
+          else
+          {
+            if (to > -1 && to < mp.length)
+            {
+              remap.put(Integer.valueOf(mp[to]), ann);
+            }
+          }
+        }
+      }
+      sequenceMapping = remap;
+      old.clear();
+      if (newref != null)
+      {
+        sequenceRef = newref;
+      }
+      adjustForAlignment();
+    }
   }
 }
index 847453f..159955a 100644 (file)
  */
 package jalview.ext.jmol;
 
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.io.AlignFile;
+import jalview.io.FileParse;
+import jalview.util.MessageManager;
+
 import java.io.IOException;
 import java.util.Hashtable;
 import java.util.Map;
@@ -35,15 +44,6 @@ import org.jmol.modelsetbio.BioPolymer;
 import org.jmol.viewer.Viewer;
 import org.openscience.jmol.app.JmolApp;
 
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.PDBEntry;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceI;
-import jalview.io.AlignFile;
-import jalview.io.FileParse;
-import jalview.util.MessageManager;
-
 /**
  * Import and process PDB files with Jmol
  * 
@@ -307,11 +307,16 @@ public class PDBFileWithJmol extends AlignFile implements
     case MEASURE:
       String mystatus = (String) data[3];
       if (mystatus.indexOf("Picked") >= 0
-              || mystatus.indexOf("Sequence") >= 0) // picking mode
+              || mystatus.indexOf("Sequence") >= 0)
+      {
+        // Picking mode
         sendConsoleMessage(strInfo);
+      }
       else if (mystatus.indexOf("Completed") >= 0)
+      {
         sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
                 strInfo.length() - 1));
+      }
       break;
     case MESSAGE:
       sendConsoleMessage(data == null ? null : strInfo);
index d9c0c6a..6d8fe6d 100644 (file)
@@ -377,7 +377,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                         .getKeyCode() >= KeyEvent.VK_NUMPAD0 && evt
                         .getKeyCode() <= KeyEvent.VK_NUMPAD9))
                 && Character.isDigit(evt.getKeyChar()))
+        {
           alignPanel.seqPanel.numberPressed(evt.getKeyChar());
+        }
 
         switch (evt.getKeyCode())
         {
@@ -389,32 +391,48 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
         case KeyEvent.VK_DOWN:
           if (evt.isAltDown() || !viewport.cursorMode)
+          {
             moveSelectedSequences(false);
+          }
           if (viewport.cursorMode)
+          {
             alignPanel.seqPanel.moveCursor(0, 1);
+          }
           break;
 
         case KeyEvent.VK_UP:
           if (evt.isAltDown() || !viewport.cursorMode)
+          {
             moveSelectedSequences(true);
+          }
           if (viewport.cursorMode)
+          {
             alignPanel.seqPanel.moveCursor(0, -1);
+          }
 
           break;
 
         case KeyEvent.VK_LEFT:
           if (evt.isAltDown() || !viewport.cursorMode)
+          {
             slideSequences(false, alignPanel.seqPanel.getKeyboardNo1());
+          }
           else
+          {
             alignPanel.seqPanel.moveCursor(-1, 0);
+          }
 
           break;
 
         case KeyEvent.VK_RIGHT:
           if (evt.isAltDown() || !viewport.cursorMode)
+          {
             slideSequences(true, alignPanel.seqPanel.getKeyboardNo1());
+          }
           else
+          {
             alignPanel.seqPanel.moveCursor(1, 0);
+          }
           break;
 
         case KeyEvent.VK_SPACE:
@@ -551,14 +569,18 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         {
         case KeyEvent.VK_LEFT:
           if (evt.isAltDown() || !viewport.cursorMode)
+          {
             viewport.firePropertyChange("alignment", null, viewport
                     .getAlignment().getSequences());
+          }
           break;
 
         case KeyEvent.VK_RIGHT:
           if (evt.isAltDown() || !viewport.cursorMode)
+          {
             viewport.firePropertyChange("alignment", null, viewport
                     .getAlignment().getSequences());
+          }
           break;
         }
       }
@@ -1458,7 +1480,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void undoMenuItem_actionPerformed(ActionEvent e)
   {
     if (viewport.historyList.empty())
+    {
       return;
+    }
     CommandI command = (CommandI) viewport.historyList.pop();
     viewport.redoList.push(command);
     command.undoCommand(getViewAlignments());
@@ -1611,37 +1635,53 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     for (int i = 0; i < viewport.getAlignment().getHeight(); i++)
     {
       if (!sg.contains(viewport.getAlignment().getSequenceAt(i)))
+      {
         invertGroup.add(viewport.getAlignment().getSequenceAt(i));
+      }
     }
 
     SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
 
     SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
     for (int i = 0; i < invertGroup.size(); i++)
+    {
       seqs2[i] = (SequenceI) invertGroup.elementAt(i);
+    }
 
     SlideSequencesCommand ssc;
     if (right)
+    {
       ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1,
               size, viewport.getGapCharacter());
+    }
     else
+    {
       ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2,
               size, viewport.getGapCharacter());
+    }
 
     int groupAdjustment = 0;
     if (ssc.getGapsInsertedBegin() && right)
     {
       if (viewport.cursorMode)
+      {
         alignPanel.seqPanel.moveCursor(size, 0);
+      }
       else
+      {
         groupAdjustment = size;
+      }
     }
     else if (!ssc.getGapsInsertedBegin() && !right)
     {
       if (viewport.cursorMode)
+      {
         alignPanel.seqPanel.moveCursor(-size, 0);
+      }
       else
+      {
         groupAdjustment = -size;
+      }
     }
 
     if (groupAdjustment != 0)
@@ -1662,7 +1702,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
 
     if (!appendHistoryItem)
+    {
       addHistoryItem(ssc);
+    }
 
     repaint();
   }
@@ -1997,7 +2039,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           {
             AlignmentAnnotation sann[] = sequences[i].getAnnotation();
             if (sann == null)
+            {
               continue;
+            }
             for (int avnum = 0; avnum < alview.length; avnum++)
             {
               if (alview[avnum] != alignment)
@@ -4643,7 +4687,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               if (ds.getSequences() == null
                       || !ds.getSequences().contains(
                               sprods[s].getDatasetSequence()))
+              {
                 ds.addSequence(sprods[s].getDatasetSequence());
+              }
               sprods[s].updatePDBIds();
             }
             Alignment al = new Alignment(sprods);
@@ -5005,7 +5051,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               {
                 PDBEntry pe = new AssociatePdbFileWithSeq()
                         .associatePdbWithSeq((String) fm[0],
-                                (String) fm[1], toassoc, false);
+                                (String) fm[1], toassoc, false,
+                                Desktop.instance);
                 if (pe != null)
                 {
                   System.err.println("Associated file : "
index ce75821..a854bdf 100644 (file)
  */
 package jalview.gui;
 
-import javax.swing.JOptionPane;
+import jalview.api.StructureSelectionManagerProvider;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
+import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
 
+import javax.swing.JOptionPane;
+
 /**
  * GUI related routines for associating PDB files with sequences
  * 
@@ -41,46 +44,50 @@ public class AssociatePdbFileWithSeq
    * @param sequence
    */
   public PDBEntry associatePdbWithSeq(String choice, String protocol,
-          SequenceI sequence, boolean prompt)
+          SequenceI sequence, boolean prompt,
+          StructureSelectionManagerProvider ssmp)
   {
     PDBEntry entry = new PDBEntry();
     MCview.PDBfile pdbfile = null;
-    try
+    pdbfile = StructureSelectionManager.getStructureSelectionManager(ssmp)
+            .setMapping(false, new SequenceI[]
+            { sequence }, null, choice, protocol);
+    if (pdbfile == null)
     {
-      // TODO JAL-674 extract secondary structure and transfer it to associated
-      // sequence
-      pdbfile = new MCview.PDBfile(false, false, choice, protocol);
-      if (pdbfile.id == null)
-      {
-        String reply = null;
-
-        if (prompt)
-        {
-          reply = JOptionPane.showInternalInputDialog(Desktop.desktop,
-                  MessageManager
-                          .getString("label.couldnt_find_pdb_id_in_file"),
-                  MessageManager.getString("label.no_pdb_id_in_file"),
-                  JOptionPane.QUESTION_MESSAGE);
-        }
-        if (reply == null)
-        {
-          return null;
-        }
+      // stacktrace already thrown so just return
+      return null;
+    }
+    if (pdbfile.id == null)
+    {
+      String reply = null;
 
-        entry.setId(reply);
+      if (prompt)
+      {
+        reply = JOptionPane.showInternalInputDialog(Desktop.desktop,
+                MessageManager
+                        .getString("label.couldnt_find_pdb_id_in_file"),
+                MessageManager.getString("label.no_pdb_id_in_file"),
+                JOptionPane.QUESTION_MESSAGE);
       }
-      else
+      if (reply == null)
       {
-        entry.setId(pdbfile.id);
+        return null;
       }
 
-    } catch (java.io.IOException ex)
+      entry.setId(reply);
+    }
+    else
     {
-      ex.printStackTrace();
+      entry.setId(pdbfile.id);
     }
 
-    entry.setFile(choice);
-    sequence.getDatasetSequence().addPDBId(entry);
+    if (pdbfile != null)
+    {
+      entry.setFile(choice);
+      sequence.getDatasetSequence().addPDBId(entry);
+      StructureSelectionManager.getStructureSelectionManager(ssmp)
+              .registerPDBEntry(entry);
+    }
     return entry;
   }
 }
index 105209f..dfacd54 100644 (file)
  */
 package jalview.gui;
 
-import java.awt.Rectangle;
-import java.io.*;
-import java.lang.reflect.InvocationTargetException;
-import java.net.*;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.jar.*;
-
-import javax.swing.*;
-
-import org.exolab.castor.xml.*;
-
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
-import jalview.schemabinding.version2.*;
-import jalview.schemes.*;
+import jalview.schemabinding.version2.AlcodMap;
+import jalview.schemabinding.version2.Alcodon;
+import jalview.schemabinding.version2.AlcodonFrame;
+import jalview.schemabinding.version2.Annotation;
+import jalview.schemabinding.version2.AnnotationColours;
+import jalview.schemabinding.version2.AnnotationElement;
+import jalview.schemabinding.version2.CalcIdParam;
+import jalview.schemabinding.version2.DBRef;
+import jalview.schemabinding.version2.Features;
+import jalview.schemabinding.version2.Group;
+import jalview.schemabinding.version2.HiddenColumns;
+import jalview.schemabinding.version2.JGroup;
+import jalview.schemabinding.version2.JSeq;
+import jalview.schemabinding.version2.JalviewModel;
+import jalview.schemabinding.version2.JalviewModelSequence;
+import jalview.schemabinding.version2.MapListFrom;
+import jalview.schemabinding.version2.MapListTo;
+import jalview.schemabinding.version2.Mapping;
+import jalview.schemabinding.version2.MappingChoice;
+import jalview.schemabinding.version2.OtherData;
+import jalview.schemabinding.version2.PdbentryItem;
+import jalview.schemabinding.version2.Pdbids;
+import jalview.schemabinding.version2.Property;
+import jalview.schemabinding.version2.Sequence;
+import jalview.schemabinding.version2.SequenceSet;
+import jalview.schemabinding.version2.SequenceSetProperties;
+import jalview.schemabinding.version2.Setting;
+import jalview.schemabinding.version2.StructureState;
+import jalview.schemabinding.version2.ThresholdLine;
+import jalview.schemabinding.version2.Tree;
+import jalview.schemabinding.version2.UserColours;
+import jalview.schemabinding.version2.Viewport;
+import jalview.schemes.AnnotationColourGradient;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.GraduatedColor;
+import jalview.schemes.ResidueColourScheme;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.util.jarInputStreamProvider;
@@ -51,6 +76,41 @@ import jalview.ws.params.ArgumentI;
 import jalview.ws.params.AutoCalcSetting;
 import jalview.ws.params.WsParamSetI;
 
+import java.awt.Rectangle;
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+
+import javax.swing.JInternalFrame;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+import org.exolab.castor.xml.Unmarshaller;
+
 /**
  * Write out the current jalview desktop state as a Jalview XML stream.
  * 
@@ -678,7 +738,9 @@ public class Jalview2XML
                                 .startsWith(
                                         jmol.jmb.pdbentry[peid].getId()
                                                 .toLowerCase())))
+                {
                   continue;
+                }
                 if (matchedFile == null)
                 {
                   matchedFile = jmol.jmb.pdbentry[peid].getFile();
@@ -1371,18 +1433,26 @@ public class Jalview2XML
 
           ae = new AnnotationElement();
           if (aa[i].annotations[a].description != null)
+          {
             ae.setDescription(aa[i].annotations[a].description);
+          }
           if (aa[i].annotations[a].displayCharacter != null)
+          {
             ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
+          }
 
           if (!Float.isNaN(aa[i].annotations[a].value))
+          {
             ae.setValue(aa[i].annotations[a].value);
+          }
 
           ae.setPosition(a);
           if (aa[i].annotations[a].secondaryStructure != ' '
                   && aa[i].annotations[a].secondaryStructure != '\0')
+          {
             ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
                     + "");
+          }
 
           if (aa[i].annotations[a].colour != null
                   && aa[i].annotations[a].colour != java.awt.Color.black)
@@ -2046,7 +2116,7 @@ public class Jalview2XML
     errorMessage = null;
   }
 
-  Hashtable alreadyLoadedPDB;
+  Hashtable<String, String> alreadyLoadedPDB;
 
   /**
    * when set, local views will be updated from view stored in JalviewXML
@@ -2058,10 +2128,14 @@ public class Jalview2XML
   String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
   {
     if (alreadyLoadedPDB == null)
+    {
       alreadyLoadedPDB = new Hashtable();
+    }
 
     if (alreadyLoadedPDB.containsKey(pdbId))
+    {
       return alreadyLoadedPDB.get(pdbId).toString();
+    }
 
     try
     {
@@ -2293,7 +2367,9 @@ public class Jalview2XML
                 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
               }
             }
-
+            StructureSelectionManager.getStructureSelectionManager(
+                    Desktop.instance)
+                    .registerPDBEntry(entry);
             al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
           }
         }
@@ -2409,7 +2485,9 @@ public class Jalview2XML
           // in principle Visible should always be true for annotation displayed
           // in multiple views
           if (an[i].hasVisible())
+          {
             jda.visible = an[i].getVisible();
+          }
 
           al.addAnnotation(jda);
 
@@ -2428,7 +2506,9 @@ public class Jalview2XML
             anpos = ae[aa].getPosition();
 
             if (anpos >= anot.length)
+            {
               continue;
+            }
 
             anot[anpos] = new jalview.datamodel.Annotation(
 
@@ -2522,10 +2602,14 @@ public class Jalview2XML
           jaa.setScore(an[i].getScore());
         }
         if (an[i].hasVisible())
+        {
           jaa.visible = an[i].getVisible();
+        }
 
         if (an[i].hasCentreColLabels())
+        {
           jaa.centreColLabels = an[i].getCentreColLabels();
+        }
 
         if (an[i].hasScaleColLabels())
         {
@@ -2547,7 +2631,6 @@ public class Jalview2XML
           jaa.belowAlignment = an[i].isBelowAlignment();
         }
         jaa.setCalcId(an[i].getCalcId());
-
         if (jaa.autoCalculated)
         {
           autoAlan.add(new JvAnnotRow(i, jaa));
@@ -3544,12 +3627,16 @@ public class Jalview2XML
         }
         renderOrder[fs] = setting.getType();
         if (setting.hasOrder())
+        {
           af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
                   setting.getType(), setting.getOrder());
+        }
         else
+        {
           af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
                   setting.getType(),
                   fs / jms.getFeatureSettings().getSettingCount());
+        }
         if (setting.getDisplay())
         {
           af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
@@ -4392,7 +4479,9 @@ public class Jalview2XML
         }
       }
       else
+      {
         Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
+      }
     }
   }
 
index 946181c..9263cd9 100755 (executable)
  */
 package jalview.gui;
 
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import javax.swing.*;
-
-import org.exolab.castor.xml.*;
-import jalview.binding.*;
-import jalview.schemes.*;
+import jalview.binding.Annotation;
+import jalview.binding.AnnotationElement;
+import jalview.binding.Features;
+import jalview.binding.JGroup;
+import jalview.binding.JSeq;
+import jalview.binding.JalviewModel;
+import jalview.binding.JalviewModelSequence;
+import jalview.binding.Pdbids;
+import jalview.binding.Sequence;
+import jalview.binding.SequenceSet;
+import jalview.binding.Setting;
+import jalview.binding.Tree;
+import jalview.binding.UserColours;
+import jalview.binding.Viewport;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
 import jalview.util.jarInputStreamProvider;
 
+import java.io.InputStreamReader;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import javax.swing.JOptionPane;
+
+import org.exolab.castor.xml.IDResolver;
+
 /**
  * DOCUMENT ME!
  * 
@@ -120,7 +139,7 @@ public class Jalview2XML_V1
           InputStreamReader in = new InputStreamReader(jin, "UTF-8");
           JalviewModel object = new JalviewModel();
 
-          object = (JalviewModel) object.unmarshal(in);
+          object = object.unmarshal(in);
 
           af = LoadFromObject(object, file);
           entryCount++;
@@ -222,6 +241,8 @@ public class Jalview2XML_V1
           entry.setId(ids[p].getId());
           entry.setType(ids[p].getType());
           al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
+          StructureSelectionManager.getStructureSelectionManager(
+                  Desktop.instance).registerPDBEntry(entry);
         }
 
       }
@@ -315,7 +336,7 @@ public class Jalview2XML_V1
 
         for (int s = 0; s < ids.length; s++)
         {
-          seqs.addElement((jalview.datamodel.SequenceI) seqids
+          seqs.addElement(seqids
                   .elementAt(ids[s]));
         }
 
index 3da4494..2845122 100644 (file)
@@ -2567,7 +2567,8 @@ public class PopupMenu extends JPopupMenu
       String choice = chooser.getSelectedFile().getPath();
       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
       new AssociatePdbFileWithSeq().associatePdbWithSeq(choice,
-              jalview.io.AppletFormatAdapter.FILE, sequence, true);
+              jalview.io.AppletFormatAdapter.FILE, sequence, true,
+              Desktop.instance);
     }
 
   }
index 0f94efa..82b94c3 100755 (executable)
 package jalview.io;
 
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
 import jalview.gui.AlignViewport;
 import jalview.gui.Desktop;
 import jalview.gui.Jalview2XML;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.MessageManager;
 
+import java.util.List;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
-import jalview.util.MessageManager;
 import javax.swing.JOptionPane;
 import javax.swing.SwingUtilities;
 
@@ -310,6 +314,21 @@ public class FileLoader implements Runnable
 
         if ((al != null) && (al.getHeight() > 0))
         {
+          for (SequenceI sq : al.getSequences())
+          {
+            while (sq.getDatasetSequence() != null)
+            {
+              sq = sq.getDatasetSequence();
+            }
+            if (sq.getPDBId() != null)
+            {
+              for (PDBEntry pdbe : (List<PDBEntry>) sq.getPDBId())
+              {
+                StructureSelectionManager.getStructureSelectionManager(
+                        Desktop.instance).registerPDBEntry(pdbe);
+              }
+            }
+          }
           if (viewport != null)
           {
             // TODO: create undo object for this JAL-1101
@@ -319,7 +338,6 @@ public class FileLoader implements Runnable
             }
             viewport.firePropertyChange("alignment", null, viewport
                     .getAlignment().getSequences());
-
           }
           else
           {
@@ -331,7 +349,9 @@ public class FileLoader implements Runnable
                     { title }));
 
             if (!protocol.equals(AppletFormatAdapter.PASTE))
+            {
               alignFrame.setFileName(file, format);
+            }
             if (raiseGUI)
             {
               // add the window to the GUI
index e975884..3bca94b 100755 (executable)
@@ -244,7 +244,10 @@ public class AnnotationColourGradient extends FollowerColourScheme
         {
           if (predefinedColours)
           {
-            return currentColour;
+            return (annotation.annotations[j].secondaryStructure == 'H' ? jalview.renderer.AnnotationRenderer.HELIX_COLOUR
+                    : annotation.annotations[j].secondaryStructure == 'E' ? jalview.renderer.AnnotationRenderer.SHEET_COLOUR
+                            : annotation.annotations[j].secondaryStructure != ' ' ? jalview.renderer.AnnotationRenderer.STEM_COLOUR
+                                    : currentColour);
           }
         }
         if (aboveAnnotationThreshold == NO_THRESHOLD
index d2dcb34..e4749c9 100644 (file)
@@ -20,7 +20,8 @@
  */
 package jalview.structure;
 
-import jalview.datamodel.*;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.SequenceI;
 
 public class StructureMapping
 {
@@ -98,4 +99,34 @@ public class StructureMapping
     }
     return -1;
   }
+
+  /**
+   * transfer a copy of an alignment annotation row in the PDB chain coordinate
+   * system onto the mapped sequence
+   * 
+   * @param ana
+   * @return the copy that was remapped to the mapped sequence
+   * @note this method will create a copy and add it to the dataset sequence for
+   *       the mapped sequence as well as the mapped sequence (if it is not a
+   *       dataset sequence).
+   */
+  public AlignmentAnnotation transfer(AlignmentAnnotation ana)
+  {
+    AlignmentAnnotation ala_copy = new AlignmentAnnotation(ana);
+    SequenceI ds = sequence;
+    while (ds.getDatasetSequence() != null)
+    {
+      ds = ds.getDatasetSequence();
+    }
+    ala_copy.remap(ds, mapping, 0, -1, 1);
+    ds.addAlignmentAnnotation(ala_copy);
+    if (ds != sequence)
+    {
+      // mapping wasn't to an original dataset sequence, so we make a copy on
+      // the mapped sequence too
+      ala_copy = new AlignmentAnnotation(ala_copy);
+      sequence.addAlignmentAnnotation(ala_copy);
+    }
+    return ala_copy;
+  }
 }
index 4d94b2d..9396be1 100644 (file)
@@ -25,13 +25,15 @@ import jalview.api.StructureSelectionManagerProvider;
 import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.SequenceI;
+import jalview.io.FormatAdapter;
 import jalview.util.MessageManager;
 
 import java.io.PrintStream;
 import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.IdentityHashMap;
 import java.util.Vector;
 
@@ -64,7 +66,36 @@ public class StructureSelectionManager
     }
   }
 
-  Hashtable mappingData = new Hashtable();
+  /**
+   * map between the PDB IDs (or structure identifiers) used by Jalview and the
+   * absolute filenames for PDB data that corresponds to it
+   */
+  HashMap<String, String> pdbIdFileName = new HashMap<String, String>(),
+          pdbFileNameId = new HashMap<String, String>();
+
+  public void registerPDBFile(String idForFile, String absoluteFile)
+  {
+    pdbIdFileName.put(idForFile, absoluteFile);
+    pdbFileNameId.put(absoluteFile, idForFile);
+  }
+
+  public String findIdForPDBFile(String idOrFile)
+  {
+    String id = pdbFileNameId.get(idOrFile);
+    return id;
+  }
+
+  public String findFileForPDBId(String idOrFile)
+  {
+    String id = pdbIdFileName.get(idOrFile);
+    return id;
+  }
+
+  public boolean isPDBFileRegistered(String idOrFile)
+  {
+    return pdbFileNameId.containsKey(idOrFile)
+            || pdbIdFileName.containsKey(idOrFile);
+  }
 
   private static StructureSelectionManager nullProvider = null;
 
@@ -167,9 +198,33 @@ public class StructureSelectionManager
   }
 
   /**
+   * Import structure data and register a structure mapping for broadcasting
+   * colouring, mouseovers and selection events (convenience wrapper).
+   * 
+   * @param sequence
+   *          - one or more sequences to be mapped to pdbFile
+   * @param targetChains
+   *          - optional chain specification for mapping each sequence to pdb
+   *          (may be nill, individual elements may be nill)
+   * @param pdbFile
+   *          - structure data resource
+   * @param protocol
+   *          - how to resolve data from resource
+   * @return null or the structure data parsed as a pdb file
+   */
+  synchronized public MCview.PDBfile setMapping(SequenceI[] sequence,
+          String[] targetChains, String pdbFile, String protocol)
+  {
+    return setMapping(true, sequence, targetChains, pdbFile, protocol);
+  }
+
+  /**
    * create sequence structure mappings between each sequence and the given
    * pdbFile (retrieved via the given protocol).
    * 
+   * @param forStructureView
+   *          when true, record the mapping for use in mouseOvers
+   * 
    * @param sequence
    *          - one or more sequences to be mapped to pdbFile
    * @param targetChains
@@ -181,7 +236,8 @@ public class StructureSelectionManager
    *          - how to resolve data from resource
    * @return null or the structure data parsed as a pdb file
    */
-  synchronized public MCview.PDBfile setMapping(SequenceI[] sequence,
+  synchronized public MCview.PDBfile setMapping(boolean forStructureView,
+          SequenceI[] sequence,
           String[] targetChains, String pdbFile, String protocol)
   {
     /*
@@ -190,17 +246,29 @@ public class StructureSelectionManager
      */
     MCview.PDBfile pdb = null;
     boolean parseSecStr=true;
-    for (SequenceI sq:sequence)
+    if (isPDBFileRegistered(pdbFile))
     {
-      SequenceI ds = sq;while (ds.getDatasetSequence()!=null) { ds = ds.getDatasetSequence();};
-      if (ds.getAnnotation()!=null)
+      for (SequenceI sq : sequence)
       {
-        for (AlignmentAnnotation ala:ds.getAnnotation())
+        SequenceI ds = sq;
+        while (ds.getDatasetSequence() != null)
+        {
+          ds = ds.getDatasetSequence();
+        }
+        ;
+        if (ds.getAnnotation() != null)
         {
-          // false if any annotation present from this structure
-          if (MCview.PDBfile.isCalcIdForFile(ala.getCalcId(), pdbFile))
+          for (AlignmentAnnotation ala : ds.getAnnotation())
           {
-            parseSecStr = false;
+
+            // false if any annotation present from this structure
+            // JBPNote this fails for jmol/chimera view because the *file* is
+            // passed, not the structure data ID -
+            if (MCview.PDBfile.isCalcIdForFile(ala.getCalcId(),
+                    findIdForPDBFile(pdbFile)))
+            {
+              parseSecStr = false;
+            }
           }
         }
       }
@@ -208,7 +276,11 @@ public class StructureSelectionManager
     try
     {
       pdb = new MCview.PDBfile(true, parseSecStr, pdbFile, protocol);
-      
+      if (pdb.id != null && pdb.id.trim().length() > 0
+              && FormatAdapter.FILE.equals(protocol))
+      {
+        registerPDBFile(pdb.id.trim(), pdbFile);
+      }
     } catch (Exception ex)
     {
       ex.printStackTrace();
@@ -253,7 +325,7 @@ public class StructureSelectionManager
       boolean first = true;
       for (int i = 0; i < pdb.chains.size(); i++)
       {
-        PDBChain chain = ((PDBChain) pdb.chains.elementAt(i));
+        PDBChain chain = (pdb.chains.elementAt(i));
         if (targetChain.length() > 0 && !targetChain.equals(chain.id)
                 && !infChain)
         {
@@ -262,8 +334,8 @@ public class StructureSelectionManager
         // TODO: correctly determine sequence type for mixed na/peptide
         // structures
         AlignSeq as = new AlignSeq(sequence[s],
-                ((PDBChain) pdb.chains.elementAt(i)).sequence,
-                ((PDBChain) pdb.chains.elementAt(i)).isNa ? AlignSeq.DNA
+                pdb.chains.elementAt(i).sequence,
+                pdb.chains.elementAt(i).isNa ? AlignSeq.DNA
                         : AlignSeq.PEP);
         as.calcScoreMatrix();
         as.traceAlignment();
@@ -332,26 +404,30 @@ public class StructureSelectionManager
         index++;
       } while (index < maxChain.atoms.size());
 
-      if (mappings == null)
-      {
-        mappings = new StructureMapping[1];
-      }
-      else
-      {
-        StructureMapping[] tmp = new StructureMapping[mappings.length + 1];
-        System.arraycopy(mappings, 0, tmp, 0, mappings.length);
-        mappings = tmp;
-      }
-
       if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
       {
         pdbFile = "INLINE" + pdb.id;
       }
-
-      mappings[mappings.length - 1] = new StructureMapping(sequence[s],
+      StructureMapping newMapping = new StructureMapping(sequence[s],
               pdbFile, pdb.id, maxChainId, mapping,
               mappingDetails.toString());
-      maxChain.transferResidueAnnotation(mappings[mappings.length - 1]);
+      if (forStructureView)
+      {
+
+        if (mappings == null)
+        {
+          mappings = new StructureMapping[1];
+        }
+        else
+        {
+          StructureMapping[] tmp = new StructureMapping[mappings.length + 1];
+          System.arraycopy(mappings, 0, tmp, 0, mappings.length);
+          mappings = tmp;
+        }
+
+        mappings[mappings.length - 1] = newMapping;
+      }
+      maxChain.transferResidueAnnotation(newMapping);
     }
     // ///////
 
@@ -855,10 +931,10 @@ public class StructureSelectionManager
       listeners.clear();
       listeners = null;
     }
-    if (mappingData != null)
+    if (pdbIdFileName != null)
     {
-      mappingData.clear();
-      mappingData = null;
+      pdbIdFileName.clear();
+      pdbIdFileName = null;
     }
     if (sel_listeners != null)
     {
@@ -902,4 +978,13 @@ public class StructureSelectionManager
     }
   }
 
+  public void registerPDBEntry(PDBEntry pdbentry)
+  {
+    if (pdbentry.getFile() != null
+            && pdbentry.getFile().trim().length() > 0)
+    {
+      registerPDBFile(pdbentry.getId(), pdbentry.getFile());
+    }
+  }
+
 }
diff --git a/test/jalview/structure/Mapping.java b/test/jalview/structure/Mapping.java
new file mode 100644 (file)
index 0000000..8cf005b
--- /dev/null
@@ -0,0 +1,111 @@
+package jalview.structure;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import org.junit.Test;
+
+import MCview.PDBfile;
+
+public class Mapping
+{
+
+  @Test
+  public void testPDBentryMapping() throws Exception
+  {
+    Sequence sq = new Sequence(
+            "1GAQ A subseq 126 to 219",
+            "EIVKGVCSNFLCDLQPGDNVQITGPVGKEMLMPKDPNATIIMLATGTGIAPFRSFLWKMFFEKHDDYKFNGLGWLFLGVPTSSSLLYKEEFGKM");
+    Sequence sq1 = new Sequence(sq);
+    String inFile;
+    StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
+    // Associate the 1GAQ pdb file with the subsequence 'imported' from another
+    // source
+    PDBfile pde = ssm.setMapping(true, new SequenceI[]
+    { sq }, new String[]
+    { "A" }, inFile = "examples/1gaq.txt", jalview.io.FormatAdapter.FILE);
+    assertTrue("PDB File couldn't be found", pde != null);
+    StructureMapping[] mp = ssm.getMapping(inFile);
+    assertTrue("No mappings made.", mp != null && mp.length > 0);
+    int nsecStr = 0, nsTemp = 0;
+    // test for presence of transferred annotation on sequence
+    for (AlignmentAnnotation alan : sq.getAnnotation())
+    {
+      if (alan.hasIcons)
+      {
+        nsecStr++;
+      }
+      if (alan.graph == alan.LINE_GRAPH)
+      {
+        nsTemp++;
+      }
+    }
+    assertEquals(
+            "Only one secondary structure should be transferred to associated sequence.",
+            1, nsecStr);
+    assertEquals(
+            "Only two line graphs should be transferred to associated sequence.",
+            2, nsTemp);
+    // Now test the transfer function and compare annotated positions
+    for (StructureMapping origMap:mp)
+    {
+      if (origMap.getSequence()==sq)
+      {
+        assertEquals("Mapping was incomplete.", sq.getLength() - 1,
+                (origMap.getPDBResNum(sq.getEnd()) - origMap
+                        .getPDBResNum(sq.getStart())));
+        // sanity check - if this fails, mapping from first position in sequence
+        // we want to transfer to is not where we expect
+        assertEquals(1, origMap.getSeqPos(126));
+        SequenceI firstChain = pde.getSeqs().get(0);
+        // Compare the annotated positions on the PDB chain sequence with the
+        // annotation on the associated sequence
+        for (AlignmentAnnotation alan : firstChain.getAnnotation())
+        {
+          AlignmentAnnotation transfer = origMap.transfer(alan);
+          System.out.println("pdb:" + firstChain.getSequenceAsString());
+          System.out.println("ann:" + alan.toString());
+          System.out.println("pdb:" + sq.getSequenceAsString());
+          System.out.println("ann:" + transfer.toString());
+
+          for (int p = 0, pSize = firstChain.getLength() - 1; p < pSize; p++)
+          {
+            // walk along the pdb chain's jalview sequence
+            int rseqpos;
+            int fpos = origMap.getSeqPos(rseqpos = firstChain
+                    .findPosition(p));
+            // only look at positions where there is a corresponding position in
+            // mapping
+            if (fpos < 1)
+            {
+              continue;
+            }
+            // p is index into PDB residue entries
+            // rseqpos is pdb sequence position for position p
+            // fpos is sequence position for associated position for rseqpos
+            int tanpos = sq.findIndex(fpos);
+            if (transfer.annotations.length <= tanpos)
+            {
+              // gone beyond mapping to the sequence
+              break;
+            }
+            Annotation a = transfer.annotations[sq.findIndex(fpos)], b = alan.annotations[p];
+            assertEquals("Non-equivalent annotation element at " + p + "("
+                    + rseqpos + ")"
+                            + " expected at " + fpos + " (alIndex "
+                            + sq.findIndex(fpos) + ")",
+                    a == null ? a : a.toString(),
+                    b == null ? b : b.toString());
+            System.out.print("(" + a + "|" + b + ")");
+          }
+
+        }
+      }
+    }
+  }
+
+}