Merge JAL-2136_phyre2_integration to develop
authortcofoegbu <tcnofoegbu@dundee.ac.uk>
Mon, 20 Mar 2017 15:14:27 +0000 (15:14 +0000)
committertcofoegbu <tcnofoegbu@dundee.ac.uk>
Mon, 20 Mar 2017 15:14:27 +0000 (15:14 +0000)
14 files changed:
1  2 
resources/lang/Messages.properties
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AppletJmol.java
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/ext/rbvi/chimera/AtomSpecModel.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AppJmol.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/StructureViewerBase.java
src/jalview/io/AnnotationFile.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/ws/sifts/SiftsClient.java
test/jalview/structures/models/AAStructureBindingModelTest.java

@@@ -1274,7 -1278,21 +1278,27 @@@ label.SEQUENCE_ID_no_longer_used = $SEQ
  label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window:
  label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'.
  label.do_not_display_again = Do not display this message again
+ exception.url_cannot_have_miriam_id = {0} is a MIRIAM id and cannot be used as a custom url name
+ exception.url_cannot_have_duplicate_id = {0} cannot be used as a label for more than one line
+ label.filter = Filter text:
+ action.customfilter = Custom only
+ action.showall = Show All
+ label.insert = Insert:
+ action.seq_id = $SEQUENCE_ID$
+ action.db_acc = $DB_ACCESSION$
+ label.primary = Double Click
+ label.inmenu = In Menu
+ label.id = ID
+ label.database = Database
+ label.urltooltip = Only one url, which must use a sequence id, can be selected for the 'On Click' option
+ label.edit_sequence_url_link = Edit sequence URL link
+ warn.name_cannot_be_duplicate = User-defined URL names must be unique and cannot be MIRIAM ids
+ label.invalid_name = Invalid Name !
  label.output_seq_details = Output Sequence Details to list all database references
++<<<<<<< HEAD
 +label.phyre2_model_prediction = 3D Protein Model prediction with Phyre2
 +label.run_phyre2_prediction = Run Phyre2 Prediction
- status.obtaining_mapping_with_phyre2_template_alignment = Obtaining mapping with Phyre2 Template alignment 
++status.obtaining_mapping_with_phyre2_template_alignment = Obtaining mapping with Phyre2 Template alignment 
++=======
+ label.urllinks = Links
++>>>>>>> develop
Simple merge
Simple merge
index 0000000,d62cc3c..7632b65
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,180 +1,180 @@@
+ package jalview.ext.rbvi.chimera;
+ import jalview.util.RangeComparator;
+ import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.TreeMap;
+ /**
+  * A class to model a Chimera atomspec pattern, for example
+  * 
+  * <pre>
+  * #0:15.A,28.A,54.A,63.A,70-72.A,83-84.A,97-98.A|#1:2.A,6.A,11.A,13-14.A,70.A,82.A,96-97.A
+  * </pre>
+  * 
+  * where
+  * <ul>
+  * <li>#0 is a model number</li>
+  * <li>15 or 70-72 is a residue number, or range of residue numbers</li>
+  * <li>.A is a chain identifier</li>
+  * <li>residue ranges are separated by comma</li>
+  * <li>atomspecs for distinct models are separated by | (or)</li>
+  * </ul>
+  * 
+  * <pre>
+  * @see http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec.html
+  * </pre>
+  */
+ public class AtomSpecModel
+ {
+   private Map<Integer, Map<String, List<int[]>>> atomSpec;
+   /**
+    * Constructor
+    */
+   public AtomSpecModel()
+   {
+     atomSpec = new TreeMap<Integer, Map<String, List<int[]>>>();
+   }
+   /**
+    * Adds one contiguous range to this atom spec
+    * 
+    * @param model
+    * @param startPos
+    * @param endPos
+    * @param chain
+    */
+   public void addRange(int model, int startPos, int endPos, String chain)
+   {
+     /*
+      * Get/initialize map of data for the colour and model
+      */
+     Map<String, List<int[]>> modelData = atomSpec.get(model);
+     if (modelData == null)
+     {
+       atomSpec.put(model, modelData = new TreeMap<String, List<int[]>>());
+     }
+     /*
+      * Get/initialize map of data for colour, model and chain
+      */
+     List<int[]> chainData = modelData.get(chain);
+     if (chainData == null)
+     {
+       chainData = new ArrayList<int[]>();
+       modelData.put(chain, chainData);
+     }
+     /*
+      * Add the start/end positions
+      */
+     chainData.add(new int[] { startPos, endPos });
+     // TODO add intelligently, using a RangeList class
+   }
+   /**
+    * Returns the range(s) formatted as a Chimera atomspec
+    * 
+    * @return
+    */
+   public String getAtomSpec()
+   {
+     StringBuilder sb = new StringBuilder(128);
+     boolean firstModel = true;
+     for (Integer model : atomSpec.keySet())
+     {
+       if (!firstModel)
+       {
+         sb.append("|");
+       }
+       firstModel = false;
+       sb.append("#").append(model).append(":");
+       boolean firstPositionForModel = true;
+       final Map<String, List<int[]>> modelData = atomSpec.get(model);
+       for (String chain : modelData.keySet())
+       {
 -        chain = chain.trim();
++        // chain = chain.trim();
+         List<int[]> rangeList = modelData.get(chain);
+         /*
+          * sort ranges into ascending start position order
+          */
+         Collections.sort(rangeList, new RangeComparator(true));
+         int start = rangeList.isEmpty() ? 0 : rangeList.get(0)[0];
+         int end = rangeList.isEmpty() ? 0 : rangeList.get(0)[1];
+         Iterator<int[]> iterator = rangeList.iterator();
+         while (iterator.hasNext())
+         {
+           int[] range = iterator.next();
+           if (range[0] <= end + 1)
+           {
+             /*
+              * range overlaps or is contiguous with the last one
+              * - so just extend the end position, and carry on
+              * (unless this is the last in the list)
+              */
+             end = Math.max(end, range[1]);
+           }
+           else
+           {
+             /*
+              * we have a break so append the last range
+              */
+             appendRange(sb, start, end, chain, firstPositionForModel);
+             firstPositionForModel = false;
+             start = range[0];
+             end = range[1];
+           }
+         }
+         /*
+          * and append the last range
+          */
+         if (!rangeList.isEmpty())
+         {
+           appendRange(sb, start, end, chain, firstPositionForModel);
+           firstPositionForModel = false;
+         }
+       }
+     }
+     return sb.toString();
+   }
+   /**
+    * @param sb
+    * @param start
+    * @param end
+    * @param chain
+    * @param firstPositionForModel
+    */
+   protected void appendRange(StringBuilder sb, int start, int end,
+           String chain, boolean firstPositionForModel)
+   {
+     if (!firstPositionForModel)
+     {
+       sb.append(",");
+     }
+     if (end == start)
+     {
+       sb.append(start);
+     }
+     else
+     {
+       sb.append(start).append("-").append(end);
+     }
+     if (chain.length() > 0)
+     {
+       sb.append(".").append(chain);
+     }
+   }
+ }
Simple merge
@@@ -163,85 -138,20 +138,21 @@@ public class AppJmol extends StructureV
          closeViewer(false);
        }
      });
 -    initJmol(loadStatus); // pdbentry, seq, JBPCHECK!
 +    initJmol(loadStatus); // pdbentry, seq, JBPCHECK!ˇ
 +
    }
  
-   private void initMenus()
+   @Override
+   protected void initMenus()
    {
-     seqColour.setSelected(jmb.isColourBySequence());
-     viewerColour.setSelected(!jmb.isColourBySequence());
-     if (_colourwith == null)
-     {
-       _colourwith = new Vector<AlignmentPanel>();
-     }
-     if (_alignwith == null)
-     {
-       _alignwith = new Vector<AlignmentPanel>();
-     }
-     seqColourBy = new ViewSelectionMenu(
-             MessageManager.getString("label.colour_by"), this, _colourwith,
-             new ItemListener()
-             {
-               @Override
-               public void itemStateChanged(ItemEvent e)
-               {
-                 if (!seqColour.isSelected())
-                 {
-                   seqColour.doClick();
-                 }
-                 else
-                 {
-                   // update the jmol display now.
-                   seqColour_actionPerformed(null);
-                 }
-               }
-             });
-     viewMenu.add(seqColourBy);
-     final ItemListener handler;
-     JMenu alpanels = new ViewSelectionMenu(
-             MessageManager.getString("label.superpose_with"), this,
-             _alignwith, handler = new ItemListener()
-             {
-               @Override
-               public void itemStateChanged(ItemEvent e)
-               {
-                 alignStructs.setEnabled(_alignwith.size() > 0);
-                 alignStructs.setToolTipText(MessageManager
-                         .formatMessage(
-                                 "label.align_structures_using_linked_alignment_views",
-                                 new String[] { new Integer(_alignwith
-                                         .size()).toString() }));
-               }
-             });
-     handler.itemStateChanged(null);
-     viewerActionMenu.add(alpanels);
-     viewerActionMenu.addMenuListener(new MenuListener()
-     {
-       @Override
-       public void menuSelected(MenuEvent e)
-       {
-         handler.itemStateChanged(null);
-       }
-       @Override
-       public void menuDeselected(MenuEvent e)
-       {
-         // TODO Auto-generated method stub
+     super.initMenus();
  
-       }
-       @Override
-       public void menuCanceled(MenuEvent e)
-       {
-         // TODO Auto-generated method stub
+     viewerActionMenu.setText(MessageManager.getString("label.jmol"));
  
-       }
-     });
+     viewerColour
+             .setText(MessageManager.getString("label.colour_with_jmol"));
+     viewerColour.setToolTipText(MessageManager
+             .getString("label.let_jmol_manage_structure_colours"));
    }
  
    IProgressIndicator progressBar = null;
    }
  
    @Override
+   protected String getViewerName()
+   {
+     return "Jmol";
+   }
++
++  @Override
 +  protected AAStructureBindingModel getBindingModel()
 +  {
 +    return jmb;
 +  }
  }
@@@ -1140,14 -852,24 +853,36 @@@ public class ChimeraViewFrame extends S
    }
  
    @Override
-   protected AAStructureBindingModel getBindingModel()
+   protected String getViewerName()
    {
-     return jmb;
+     return "Chimera";
+   }
+   /**
+    * Sends commands to align structures according to associated alignment(s).
+    * 
+    * @return
+    */
+   @Override
+   protected String alignStructs_withAllAlignPanels()
+   {
+     String reply = super.alignStructs_withAllAlignPanels();
+     if (reply != null)
+     {
+       statusBar.setText("Superposition failed: " + reply);
+     }
+     return reply;
    }
 +
 +  @Override
 +  protected IProgressIndicator getIProgressIndicator()
 +  {
 +    return progressBar;
 +  }
++
++  @Override
++  protected AAStructureBindingModel getBindingModel()
++  {
++    return jmb;
++  }
  }
Simple merge
@@@ -28,18 -28,14 +28,19 @@@ import jalview.datamodel.Annotation
  import jalview.datamodel.ColumnSelection;
  import jalview.datamodel.GraphLine;
  import jalview.datamodel.HiddenSequences;
 +import jalview.datamodel.PDBEntry;
 +import jalview.datamodel.PDBEntry.Type;
  import jalview.datamodel.SequenceGroup;
  import jalview.datamodel.SequenceI;
 +import jalview.gui.Desktop;
  import jalview.schemes.ColourSchemeI;
  import jalview.schemes.ColourSchemeProperty;
- import jalview.schemes.UserColourScheme;
 +import jalview.structure.StructureSelectionManager;
+ import jalview.util.ColorUtils;
  
+ import java.awt.Color;
  import java.io.BufferedReader;
 +import java.io.File;
  import java.io.FileReader;
  import java.io.InputStreamReader;
  import java.io.StringReader;
@@@ -1400,26 -1369,4 +1415,31 @@@ public class StructureSelectionManage
      return seqmappings;
    }
  
 +  public boolean isPhyre2Template(String structureFile)
 +  {
 +    if (structureFile == null || phyre2ModelTemplates == null
 +            || phyre2ModelTemplates.isEmpty())
 +    {
 +      return false;
 +    }
 +    return phyre2ModelTemplates.get(structureFile) != null
 +            && !phyre2ModelTemplates.get(structureFile).isEmpty();
 +  }
 +
 +  public String getPhyre2FastaFileFor(String structureFile)
 +  {
 +    return phyre2ModelTemplates.get(structureFile);
 +  }
 +
 +
 +  public static StructureSelectionManager getStructureSelectionManager()
 +  {
 +    return instances.values().iterator().next();
 +  }
 +
++  public void addStructureMapping(StructureMapping smapping)
++  {
++    mappings.add(smapping);
++  }
++
  }
@@@ -70,11 -69,21 +70,17 @@@ 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
  {
+   /*
+    * 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;
 -
    private String pdbId;
  
    private String structId;