JAL-1620 version bump and release notes
[jalview.git] / src / jalview / ext / jmol / JalviewJmolBinding.java
index 216c09e..65c27d9 100644 (file)
@@ -1,19 +1,22 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
- * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2b1)
+ * Copyright (C) 2014 The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
  * Jalview is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
  *  
  * Jalview is distributed in the hope that it will be useful, but 
  * WITHOUT ANY WARRANTY; without even the implied warranty 
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
  * PURPOSE.  See the GNU General Public License for more details.
  * 
- * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
 package jalview.ext.jmol;
 
@@ -32,6 +35,8 @@ import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureListener;
 import jalview.structure.StructureMapping;
 import jalview.structure.StructureSelectionManager;
+import jalview.structures.models.SequenceStructureBindingModel;
+import jalview.util.MessageManager;
 
 import java.awt.Color;
 import java.awt.Container;
@@ -53,26 +58,13 @@ import org.jmol.api.JmolViewer;
 import org.jmol.constant.EnumCallback;
 import org.jmol.popup.JmolPopup;
 
-public abstract class JalviewJmolBinding implements StructureListener,
+public abstract class JalviewJmolBinding extends SequenceStructureBindingModel implements StructureListener,
         JmolStatusListener, SequenceStructureBinding,
         JmolSelectionListener, ComponentListener,
         StructureSelectionManagerProvider
 
 {
   /**
-   * set if Jmol state is being restored from some source - instructs binding
-   * not to apply default display style when structure set is updated for first
-   * time.
-   */
-  private boolean loadingFromArchive = false;
-  
-  /**
-   * second flag to indicate if the jmol viewer should ignore sequence colouring
-   * events from the structure manager because the GUI is still setting up
-   */
-  private boolean loadingFinished = true;
-
-  /**
    * state flag used to check if the Jmol viewer's paint method can be called
    */
   private boolean finishedInit = false;
@@ -326,7 +318,56 @@ public abstract class JalviewJmolBinding implements StructureListener,
     assert (_alignment.length == _refStructure.length && _alignment.length != _hiddenCols.length);
 
     String[] files = getPdbFile();
+    // check to see if we are still waiting for Jmol files
+    long starttime = System.currentTimeMillis();
+    boolean waiting = true;
+    do
+    {
+      waiting = false;
+      for (String file : files)
+      {
+        try
+        {
+          // HACK - in Jalview 2.8 this call may not be threadsafe so we catch
+          // every possible exception
+          StructureMapping[] sm = ssm.getMapping(file);
+          if (sm == null || sm.length == 0)
+          {
+            waiting = true;
+          }
+        } catch (Exception x)
+        {
+          waiting = true;
+        } catch (Error q)
+        {
+          waiting = true;
+        }
+      }
+      // we wait around for a reasonable time before we give up
+    } while (waiting
+            && System.currentTimeMillis() < (10000 + 1000 * files.length + starttime));
+    if (waiting)
+    {
+      System.err
+              .println("RUNTIME PROBLEM: Jmol seems to be taking a long time to process all the structures.");
+      return;
+    }
     StringBuffer selectioncom = new StringBuffer();
+    // In principle - nSeconds specifies the speed of animation for each
+    // superposition - but is seems to behave weirdly, so we don't specify it.
+    String nSeconds = " ";
+    if (files.length > 10)
+    {
+      nSeconds = " 0.00001 ";
+    }
+    else
+    {
+      nSeconds = " " + (2.0 / files.length) + " ";
+      // if (nSeconds).substring(0,5)+" ";
+    }
+    // see JAL-1345 - should really automatically turn off the animation for
+    // large numbers of structures, but Jmol doesn't seem to allow that.
+    nSeconds = " ";
     // union of all aligned positions are collected together.
     for (int a = 0; a < _alignment.length; a++)
     {
@@ -371,8 +412,9 @@ public abstract class JalviewJmolBinding implements StructureListener,
         // RACE CONDITION - getMapping only returns Jmol loaded filenames once
         // Jmol callback has completed.
         if (mapping == null || mapping.length < 1)
-          continue;
-
+        {
+          throw new Error(MessageManager.getString("error.implementation_error_jmol_getting_data"));
+        }
         int lastPos = -1;
         for (int s = 0; s < sequence[pdbfnum].length; s++)
         {
@@ -437,6 +479,13 @@ public abstract class JalviewJmolBinding implements StructureListener,
           }
         }
       }
+
+      // TODO: consider bailing if nmatched less than 4 because superposition
+      // not
+      // well defined.
+      // TODO: refactor superposable position search (above) from jmol selection
+      // construction (below)
+
       String[] selcom = new String[files.length];
       int nmatched = 0;
       // generate select statements to select regions to superimpose structures
@@ -489,27 +538,30 @@ public abstract class JalviewJmolBinding implements StructureListener,
             molsel.append(chainCd);
             molsel.append("}");
           }
-          selcom[pdbfnum] = molsel.toString();
-          selectioncom.append("((");
-          selectioncom.append(selcom[pdbfnum].substring(1,
-                  selcom[pdbfnum].length() - 1));
-          selectioncom.append(" )& ");
-          selectioncom.append(pdbfnum + 1);
-          selectioncom.append(".1)");
-          if (pdbfnum < files.length - 1)
+          if (molsel.length() > 1)
+          {
+            selcom[pdbfnum] = molsel.toString();
+            selectioncom.append("((");
+            selectioncom.append(selcom[pdbfnum].substring(1,
+                    selcom[pdbfnum].length() - 1));
+            selectioncom.append(" )& ");
+            selectioncom.append(pdbfnum + 1);
+            selectioncom.append(".1)");
+            if (pdbfnum < files.length - 1)
+            {
+              selectioncom.append("|");
+            }
+          }
+          else
           {
-            selectioncom.append("|");
+            selcom[pdbfnum] = null;
           }
         }
       }
-      // TODO: consider bailing if nmatched less than 4 because superposition
-      // not
-      // well defined.
-      // TODO: refactor superposable position search (above) from jmol selection
-      // construction (below)
       for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
       {
-        if (pdbfnum == refStructure)
+        if (pdbfnum == refStructure || selcom[pdbfnum] == null
+                || selcom[refStructure] == null)
         {
           continue;
         }
@@ -518,7 +570,7 @@ public abstract class JalviewJmolBinding implements StructureListener,
         command.append(chainNames[pdbfnum]);
         command.append(") against reference (");
         command.append(chainNames[refStructure]);
-        command.append(")\";\ncompare ");
+        command.append(")\";\ncompare " + nSeconds);
         command.append("{");
         command.append(1 + pdbfnum);
         command.append(".1} {");
@@ -533,13 +585,17 @@ public abstract class JalviewJmolBinding implements StructureListener,
         }
         command.append(" ROTATE TRANSLATE;\n");
       }
-      System.out.println("Select regions:\n" + selectioncom.toString());
-      evalStateCommand("select *; cartoons off; backbone; select ("
-              + selectioncom.toString() + "); cartoons; ");
-      // selcom.append("; ribbons; ");
-      System.out.println("Superimpose command(s):\n" + command.toString());
-
-      evalStateCommand(command.toString());
+      if (selectioncom.length() > 0)
+      {
+        System.out.println("Select regions:\n" + selectioncom.toString());
+        evalStateCommand("select *; cartoons off; backbone; select ("
+                + selectioncom.toString() + "); cartoons; ");
+        // selcom.append("; ribbons; ");
+        System.out
+                .println("Superimpose command(s):\n" + command.toString());
+
+        evalStateCommand(command.toString());
+      }
     }
     if (selectioncom.length() > 0)
     {// finally, mark all regions that were superposed.
@@ -573,7 +629,7 @@ public abstract class JalviewJmolBinding implements StructureListener,
   public void colourBySequence(boolean showFeatures,
           jalview.api.AlignmentViewPanel alignmentv)
   {
-    if (!colourBySequence || !loadingFinished)
+    if (!colourBySequence || !isLoadingFinished())
       return;
     if (ssm == null)
     {
@@ -1441,30 +1497,6 @@ public abstract class JalviewJmolBinding implements StructureListener,
     showConsole(false);
   }
 
-  public void setLoadingFromArchive(boolean loadingFromArchive)
-  {
-    this.loadingFromArchive = loadingFromArchive;
-  }
-  
-  /**
-   * 
-   * @return true if Jmol is still restoring state or loading is still going on (see setFinsihedLoadingFromArchive)
-   */
-  public boolean isLoadingFromArchive()
-  {
-    return loadingFromArchive && !loadingFinished;
-  }
-
-  /**
-   * modify flag which controls if sequence colouring events are honoured by the binding. 
-   * Should be true for normal operation
-   * @param finishedLoading
-   */
-  public void setFinishedLoadingFromArchive(boolean finishedLoading)
-  {
-    loadingFinished = finishedLoading;
-  }
-
   public void setBackgroundColour(java.awt.Color col)
   {
     jmolHistory(false);
@@ -1542,9 +1574,7 @@ public abstract class JalviewJmolBinding implements StructureListener,
   {
     if (pe < 0 || pe >= pdbentry.length)
     {
-      throw new Error(
-              "Implementation error - no corresponding pdbentry (for index "
-                      + pe + ") to add sequences mappings to");
+      throw new Error(MessageManager.formatMessage("error.implementation_error_no_pdbentry_from_index", new String[]{Integer.valueOf(pe).toString()}));
     }
     final String nullChain = "TheNullChain";
     Vector s = new Vector();