JAL-1894 update year/version in copyright
[jalview.git] / src / jalview / ext / jmol / PDBFileWithJmol.java
index 159955a..dccc9a4 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b1)
+ * Copyright (C) 2015 The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
@@ -27,22 +27,24 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.io.AlignFile;
 import jalview.io.FileParse;
+import jalview.schemes.ResidueProperties;
 import jalview.util.MessageManager;
 
 import java.io.IOException;
 import java.util.Hashtable;
 import java.util.Map;
 
+import javajs.awt.Dimension;
+
 import org.jmol.api.JmolStatusListener;
 import org.jmol.api.JmolViewer;
-import org.jmol.constant.EnumCallback;
+import org.jmol.c.CBK;
 import org.jmol.modelset.Group;
 import org.jmol.modelset.Model;
 import org.jmol.modelset.ModelSet;
-import org.jmol.modelset.Polymer;
+import org.jmol.modelsetbio.BioModel;
 import org.jmol.modelsetbio.BioPolymer;
 import org.jmol.viewer.Viewer;
-import org.openscience.jmol.app.JmolApp;
 
 /**
  * Import and process PDB files with Jmol
@@ -53,9 +55,6 @@ import org.openscience.jmol.app.JmolApp;
 public class PDBFileWithJmol extends AlignFile implements
         JmolStatusListener
 {
-
-  JmolApp jmolApp = null;
-
   Viewer viewer = null;
 
   public PDBFileWithJmol(String inFile, String type) throws IOException
@@ -70,7 +69,6 @@ public class PDBFileWithJmol extends AlignFile implements
 
   public PDBFileWithJmol()
   {
-    // TODO Auto-generated constructor stub
   }
 
   /**
@@ -81,23 +79,16 @@ public class PDBFileWithJmol extends AlignFile implements
   private Viewer getJmolData()
   {
     if (viewer == null)
-    { // note that -o -n -x are all implied
-      jmolApp = new JmolApp();
-      jmolApp.isDataOnly = true;
-      jmolApp.haveConsole = false;
-      jmolApp.haveDisplay = false;
-      jmolApp.exitUponCompletion = true;
+    {
       try
       {
         viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
-                null, jmolApp.commandOptions, this);
-        viewer.setScreenDimension(jmolApp.startupWidth,
-                jmolApp.startupHeight);
-        jmolApp.startViewer(viewer, null);
+                null, "-x -o -n", this);
       } catch (ClassCastException x)
       {
-        throw new Error(MessageManager.formatMessage("error.jmol_version_not_compatible_with_jalview_version", new String[]{JmolViewer.getJmolVersion()}),
-                x);
+        throw new Error(MessageManager.formatMessage(
+                "error.jmol_version_not_compatible_with_jalview_version",
+                new String[] { JmolViewer.getJmolVersion() }), x);
       }
     }
     return viewer;
@@ -128,123 +119,167 @@ public class PDBFileWithJmol extends AlignFile implements
     Viewer jmd = getJmolData();
     jmd.openReader(getDataName(), getDataName(), getReader());
     waitForScript(jmd);
-    if (jmd.getModelCount() > 0)
+
+    if (jmd.ms.mc > 0)
     {
-      ModelSet ms = jmd.getModelSet();
-      String structs = ms.calculateStructures(null, true, false, true);
+      ModelSet ms = jmd.ms;
+      // Jmol 14.2 added third argument doReport = false
+      ms.calculateStructures(null, true, false, false, true);
       // System.out.println("Structs\n"+structs);
-      for (Model model : ms.getModels())
+      Group group = null;
+      int modelIndex = -1;
+      for (Model model : ms.am)
       {
-        for (int _bp = 0, _bpc = model.getBioPolymerCount(); _bp < _bpc; _bp++)
+        modelIndex++;
+        for (BioPolymer bp : ((BioModel) model).bioPolymers)
         {
-          Polymer bp = model.getBioPolymer(_bp);
-          if (bp instanceof BioPolymer)
+          int lastChainId = 0; // int value of character e.g. 65 for A
+          String lastChainIdAlpha = "";
+
+          int[] groups = bp.getLeadAtomIndices();
+          char seq[] = new char[groups.length], secstr[] = new char[groups.length], secstrcode[] = new char[groups.length];
+          int groupc = 0, len = 0, firstrnum = 1, lastrnum = 0;
+
+          do
           {
-            BioPolymer biopoly = (BioPolymer) bp;
-            char _lastChainId = 0;
-            int[] groups = biopoly.getLeadAtomIndices();
-            Group[] bpgrp = biopoly.getGroups();
-            char seq[] = new char[groups.length], secstr[] = new char[groups.length], secstrcode[] = new char[groups.length];
-            int groupc = 0, len = 0, firstrnum = 1, lastrnum = 0;
-            do
+            if (groupc >= groups.length
+                    || ms.at[groups[groupc]].group.chain.chainID != lastChainId)
             {
-              if (groupc >= groups.length
-                      || ms.atoms[groups[groupc]].getChainID() != _lastChainId)
+              /*
+               * on change of chain (or at end), construct the sequence and
+               * secondary structure annotation for the last chain
+               */
+              if (len > 0)
               {
-                if (len > 0)
+                boolean isNa = bp.isNucleic();
+                // normalise sequence from Jmol to jalview
+                int[] cinds = isNa ? ResidueProperties.nucleotideIndex
+                        : ResidueProperties.aaIndex;
+                int nonGap = isNa ? ResidueProperties.maxNucleotideIndex
+                        : ResidueProperties.maxProteinIndex;
+                char ngc = 'X';
+                char newseq[] = new char[len];
+                Annotation asecstr[] = new Annotation[len + firstrnum - 1];
+                for (int p = 0; p < len; p++)
                 {
-                  char newseq[] = new char[len];
-                  System.arraycopy(seq, 0, newseq, 0, len);
-                  Annotation asecstr[] = new Annotation[len+firstrnum-1];
-                  for (int p = 0; p < len; p++)
+                  newseq[p] = cinds[seq[p]] == nonGap ? ngc : seq[p];
+                  if (secstr[p] >= 'A' && secstr[p] <= 'z')
                   {
-                    if (secstr[p] >= 'A' && secstr[p] <= 'z')
+                    try
                     {
                       asecstr[p] = new Annotation("" + secstr[p], null,
                               secstrcode[p], Float.NaN);
+                    } catch (ArrayIndexOutOfBoundsException e)
+                    {
+                      // skip - patch for JAL-1836
                     }
                   }
-                  SequenceI sq = new Sequence("" + getDataName() + "|"
-                          + model.getModelTitle() + "|" + _lastChainId,
-                          newseq, firstrnum, lastrnum);
-                  PDBEntry pdbe = new PDBEntry();
-                  pdbe.setFile(getDataName());
-                  pdbe.setId(getDataName());
-                  sq.addPDBId(pdbe);
-                  pdbe.setProperty(new Hashtable());
-                  pdbe.getProperty().put("CHAIN", "" + _lastChainId);
-                  // JAL-1533
-                  // Need to put the number of models for this polymer somewhere for Chimera/others to grab
-                  //                  pdbe.getProperty().put("PDBMODELS", biopoly.)
-                  seqs.add(sq);
-                  if (!(biopoly.isDna() || biopoly.isRna()))
+                }
+                String modelTitle = (String) ms
+                        .getInfo(modelIndex, "title");
+                SequenceI sq = new Sequence("" + getDataName() + "|"
+                        + modelTitle + "|" + lastChainIdAlpha, newseq,
+                        firstrnum, lastrnum);
+                PDBEntry pdbe = new PDBEntry();
+                pdbe.setFile(getDataName());
+                pdbe.setId(getDataName());
+                pdbe.setProperty(new Hashtable());
+                // pdbe.getProperty().put("CHAIN", "" + _lastChainId);
+                pdbe.setChainCode(lastChainIdAlpha);
+                sq.addPDBId(pdbe);
+                // JAL-1533
+                // Need to put the number of models for this polymer somewhere
+                // for Chimera/others to grab
+                // pdbe.getProperty().put("PDBMODELS", biopoly.)
+                seqs.add(sq);
+                if (!isNa)
+                {
+                  String mt = modelTitle == null ? getDataName()
+                          : modelTitle;
+                  if (lastChainId >= ' ')
                   {
-                    AlignmentAnnotation ann = new AlignmentAnnotation(
-                            "Secondary Structure",
-                            "Secondary Structure from PDB File", asecstr);
-                    ann.belowAlignment=true;
-                    ann.visible=true;
-                    ann.autoCalculated=false;
-                    ann.setCalcId(getClass().getName());
-                    sq.addAlignmentAnnotation(ann);
-                    ann.adjustForAlignment();
-                    ann.validateRangeAndDisplay();
-                    annotations.add(ann);
+                    mt += lastChainIdAlpha;
                   }
+                  AlignmentAnnotation ann = new AlignmentAnnotation(
+                          "Secondary Structure", "Secondary Structure for "
+                                  + mt, asecstr);
+                  ann.belowAlignment = true;
+                  ann.visible = true;
+                  ann.autoCalculated = false;
+                  ann.setCalcId(getClass().getName());
+                  sq.addAlignmentAnnotation(ann);
+                  ann.adjustForAlignment();
+                  ann.validateRangeAndDisplay();
+                  annotations.add(ann);
                 }
-                len = 0;
-                firstrnum = 1;
-                lastrnum = 0;
               }
-              if (groupc < groups.length)
+              len = 0;
+              firstrnum = 1;
+              lastrnum = 0;
+            }
+            if (groupc < groups.length)
+            {
+              group = ms.at[groups[groupc]].group;
+              if (len == 0)
               {
-                if (len == 0)
+                firstrnum = group.getResno();
+                lastChainId = group.chain.chainID;
+                lastChainIdAlpha = group.chain.getIDStr();
+              }
+              else
+              {
+                lastrnum = group.getResno();
+              }
+              seq[len] = group.getGroup1();
+
+              /*
+               * JAL-1828 replace a modified amino acid with its standard
+               * equivalent (e.g. MSE with MET->M) to maximise sequence matching
+               */
+              String threeLetterCode = group.getGroup3();
+              String canonical = ResidueProperties
+                      .getCanonicalAminoAcid(threeLetterCode);
+              if (canonical != null
+                      && !canonical.equalsIgnoreCase(threeLetterCode))
+              {
+                seq[len] = ResidueProperties
+                        .getSingleCharacterCode(canonical);
+              }
+              switch (group.getProteinStructureSubType())
+              {
+              case HELIX310:
+                if (secstr[len] == 0)
                 {
-                  firstrnum = bpgrp[groupc].getResno();
-                  _lastChainId = bpgrp[groupc].getChainID();
+                  secstr[len] = '3';
                 }
-                else
+              case HELIXALPHA:
+                if (secstr[len] == 0)
                 {
-                  lastrnum = bpgrp[groupc].getResno();
+                  secstr[len] = 'H';
                 }
-                seq[len] = bpgrp[groupc].getGroup1();
-                switch (bpgrp[groupc].getProteinStructureSubType())
+              case HELIXPI:
+                if (secstr[len] == 0)
                 {
-                case HELIX_310:
-                  if (secstr[len] == 0)
-                  {
-                    secstr[len] = '3';
-                  }
-                case HELIX_ALPHA:
-                  if (secstr[len] == 0)
-                  {
-                    secstr[len] = 'H';
-                  }
-                case HELIX_PI:
-                  if (secstr[len] == 0)
-                  {
-                    secstr[len] = 'P';
-                  }
-                case HELIX:
-                  if (secstr[len] == 0)
-                  {
-                    secstr[len] = 'H';
-                  }
-                  secstrcode[len] = 'H';
-                  break;
-                case SHEET:
-                  secstr[len] = 'E';
-                  secstrcode[len] = 'E';
-                  break;
-                default:
-                  secstr[len] = 0;
-                  secstrcode[len] = 0;
+                  secstr[len] = 'P';
+                }
+              case HELIX:
+                if (secstr[len] == 0)
+                {
+                  secstr[len] = 'H';
                 }
-                len++;
+                secstrcode[len] = 'H';
+                break;
+              case SHEET:
+                secstr[len] = 'E';
+                secstrcode[len] = 'E';
+                break;
+              default:
+                secstr[len] = 0;
+                secstrcode[len] = 0;
               }
-            } while (groupc++ < groups.length);
-
-          }
+              len++;
+            }
+          } while (groupc++ < groups.length);
         }
       }
 
@@ -291,7 +326,7 @@ public class PDBFileWithJmol extends AlignFile implements
    * System.err.println("Squashed Jmol callback handler error:");
    * e.printStackTrace(); } }
    */
-  public void notifyCallback(EnumCallback type, Object[] data)
+  public void notifyCallback(CBK type, Object[] data)
   {
     String strInfo = (data == null || data[1] == null ? null : data[1]
             .toString());
@@ -329,13 +364,6 @@ public class PDBFileWithJmol extends AlignFile implements
     }
   }
 
-  private void notifyFileLoaded(String string, String string2,
-          String string3, String string4, int intValue)
-  {
-    // TODO Auto-generated method stub
-
-  }
-
   String lastConsoleEcho = "";
 
   private void sendConsoleEcho(String string)
@@ -364,7 +392,7 @@ public class PDBFileWithJmol extends AlignFile implements
   }
 
   @Override
-  public boolean notifyEnabled(EnumCallback callbackPick)
+  public boolean notifyEnabled(CBK callbackPick)
   {
     switch (callbackPick)
     {
@@ -374,16 +402,9 @@ public class PDBFileWithJmol extends AlignFile implements
     case LOADSTRUCT:
     case ERROR:
       return true;
-    case MEASURE:
-    case PICK:
-    case HOVER:
-    case RESIZE:
-    case SYNC:
-    case CLICK:
-    case ANIMFRAME:
-    case MINIMIZATION:
+    default:
+      return false;
     }
-    return false;
   }
 
   @Override
@@ -430,10 +451,15 @@ public class PDBFileWithJmol extends AlignFile implements
   }
 
   @Override
-  public void resizeInnerPanel(String data)
+  public Dimension resizeInnerPanel(String data)
   {
-    // TODO Auto-generated method stub
+    return null;
+  }
 
+  @Override
+  public Map<String, Object> getJSpecViewProperty(String arg0)
+  {
+    return null;
   }
 
 }