Merge branch 'bug/JAL-2154projectMappings' into develop
authorJim Procter <jprocter@issues.jalview.org>
Mon, 1 Aug 2016 14:40:24 +0000 (15:40 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Mon, 1 Aug 2016 14:40:24 +0000 (15:40 +0100)
22 files changed:
help/html/features/sifts_mapping_output.png
help/html/features/siftsmapping.html
src/MCview/Atom.java
src/MCview/PDBfile.java
src/jalview/api/DBRefEntryI.java
src/jalview/bin/Cache.java
src/jalview/datamodel/DBRefEntry.java
src/jalview/ext/jmol/JmolParser.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/Desktop.java
src/jalview/gui/Jalview2XML.java
src/jalview/io/AppletFormatAdapter.java
src/jalview/io/StructureFile.java
src/jalview/structure/StructureImportSettings.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/ws/dbsources/Pdb.java
test/jalview/ext/jmol/JmolParserTest.java
test/jalview/ext/jmol/JmolVsJalviewPDBParserEndToEndTest.java [new file with mode: 0644]
test/jalview/io/AnnotatedPDBFileInputTest.java
test/jalview/io/Jalview2xmlTests.java
test/jalview/ws/PDBSequenceFetcherTest.java
test/jalview/ws/sifts/SiftsClientTest.java

index 3c28b81..ddc8a1f 100644 (file)
Binary files a/help/html/features/sifts_mapping_output.png and b/help/html/features/sifts_mapping_output.png differ
index c344a20..08089ad 100644 (file)
@@ -9,8 +9,8 @@
   <p><strong>SIFTS Mapping</strong></p>
   
   <p>
-       SIFTS (Structure integration with function, taxonomy
-       and sequences) provides an up-to-date resource for residue-level
+       SIFTS (Structure Integration with Function, Taxonomy
+       and Sequences) provides an up-to-date resource for residue-level
        mapping between Uniprot and PDB entries. The information is updated and
        released weekly simultaneously with the release of new PDB entries.
        SIFTS Entries are published as XML files and made publicly available via an FTP
@@ -18,7 +18,8 @@
   </p>
        
   <p>
-    At the point of viewing a PDB structure, Jalview downloads a SIFTS file 
+    At the point of viewing a PDB structure, if the default mapping method is set as 'SIFTS', 
+    Jalview will download a SIFTS file 
        for the target entry and uses it to accurately map the sequence residues with the 
        structure residue. Prior to SIFTS integration, Jalview uses Needleman and Wunsch 
        Alignment algorithm to  map sequence residues to structure residues, and that may not 
   </p>
   
   <p>
-       The default method for 'Sequence &harr; Structure' mapping can be configured 
-       in the Structure tab in the <strong>Tools &rarr; Preferences</strong> dialog box. When 'SIFTS' 
-       is enabled as the default, all mappings between 'Sequence &harr; Structure' is 
-       performed via SIFTS provided that there is a valid SIFTS entry for PDB structure. If no 
-       valid SIFTS resource is available, then the 'Sequence &harr; Structure' mapping falls 
-       back to Needleman and Wunsch Alignment algorithm.
+  <strong>Configuration</strong><br/>
+       The default mapping method can be configured via <strong>Tools &rarr; Preferences &rarr; 
+       Structure tab</strong> Then scroll to the 'Sequence &harr; Structure method' section of 
+       the dialog box and change the default method. When 'SIFTS' is enabled as the default, all 
+       mappings between 'Sequence &harr; Structure' is performed via SIFTS provided that there 
+       is a valid SIFTS resource for the PDB entry. If no valid SIFTS resource is available, then 
+       the 'Sequence &harr; Structure' mapping falls back to Needleman and Wunsch Alignment algorithm.
   </p>
        
-  <p>To verify the mapping method used, you can view the mapping output via the structure viewer menu <strong>File &rarr; View mapping.</strong> A sample mapping output can be seen in the screenshot below. The highlighted position shows the method used. </p>     
+  <p><strong>Multi-Chain Mappings</strong>
+  <br/>One of the main merits of SIFTS is the ability to accurately achieve multi-chain mapping 
+  (one-to-many) between a single Uniprot sequence and its corresponding multiple chains in 
+  PDB. Consequently, mousing over the uniprot sequence in the alignment window results 
+  to highlighting multiple corresponding positions in the structure viewer for the mapped chains. 
+  </p>
   <p>
-       <img src="sifts_mapping_output.png" align="left" alt="SIFTS mapping output" />
+  To see this in action, load uniprot sequence for FER1_MAIZE then veiw PDB structure for 3B2F, you
+  will notice that mousing over the sequence results to two positions being highlighted in the 
+  structure, also colouring the sequence transfers the color to all the mapped chains in the structure.
   </p>
+  
+  <p>
+  <Strong>Viewing Mapping Output</Strong> <br/>
+  The mapping output is accessible via <strong>File &rarr; View mapping</strong> menu of the structure 
+  viewers. The screenshot below is the mapping output for the <Strong>{FER1_MAIZE &harr; 3B2F}</Strong> 
+  example described above. Observe that all the two chains were mapped. The mapping method used can be 
+  seen within the area highlighted with red boarder. This is useful for visually ascertaining the 
+  mapping method when in doubt.    
+  <p>
+       
+       &emsp;<img src="sifts_mapping_output.png" align="left" alt="SIFTS mapping output" />
        
   <p><em>SIFTS Mapping integration was added in Jalview 2.9.1</em></p>
        
index 68a7c21..ab038a0 100755 (executable)
@@ -109,6 +109,23 @@ public class Atom
     }
   }
 
+  @Override
+  public boolean equals(Object that)
+  {
+    if (this == that || that == null)
+    {
+      return true;
+    }
+    if (that instanceof Atom)
+    {
+      Atom other = (Atom) that;
+      return other.resName.equals(this.resName)
+              && other.resNumber == this.resNumber
+              && other.resNumIns.equals(this.resNumIns)
+              && other.chain.equals(this.chain);
+    }
+    return false;
+  }
   public Atom(float x, float y, float z)
   {
     this.x = x;
index 9acc2e7..2746807 100755 (executable)
@@ -25,7 +25,6 @@ import jalview.datamodel.DBRefSource;
 import jalview.datamodel.SequenceI;
 import jalview.io.FileParse;
 import jalview.io.StructureFile;
-import jalview.structure.StructureImportSettings;
 import jalview.util.MessageManager;
 
 import java.io.IOException;
@@ -132,8 +131,7 @@ public class PDBfile extends StructureFile
           break;
         }
         if (line.indexOf("ATOM") == 0
-                || (StructureImportSettings.isProcessHETATMs()
-                        && line.indexOf("HETATM") == 0 && !terFlag))
+                || (line.indexOf("HETATM") == 0 && !terFlag))
         {
           terFlag = false;
 
index 2ce7e4a..32245b3 100644 (file)
@@ -48,32 +48,6 @@ public interface DBRefEntryI
   public void setVersion(String version);
 
   /**
-   * 
-   * @param startRes
-   *          index of start residue in the source DB
-   */
-  public void setStartRes(int startRes);
-
-  /**
-   * 
-   * @return index of start residue in the source DB
-   */
-  public int getStartRes();
-
-  /**
-   * 
-   * @param endRes
-   *          index of end residue in the source DB
-   */
-  public void setEndRes(int endRes);
-
-  /**
-   * 
-   * @return index of end residue in the source DB
-   */
-  public int getEndRes();
-
-  /**
    * access a mapping, if present that can be used to map positions from the
    * associated dataset sequence to the DBRef's sequence frame.
    * 
index 23277a4..4be7830 100755 (executable)
@@ -20,6 +20,7 @@
  */
 package jalview.bin;
 
+import jalview.datamodel.PDBEntry;
 import jalview.structure.StructureImportSettings;
 import jalview.ws.dbsources.das.api.DasSourceRegistryI;
 import jalview.ws.dbsources.das.datamodel.DasSourceRegistry;
@@ -226,10 +227,15 @@ public class Cache
   private final static String DEFAULT_CACHE_THRESHOLD_IN_DAYS = "2";
 
   private final static String DEFAULT_FAIL_SAFE_PID_THRESHOLD = "30";
-
-  private final static String DEFAULT_STRUCTURE_FORMAT = StructureImportSettings.MMCIF;
   
-  private final static String DEFAULT_PDB_FILE_PARSER = StructureImportSettings.JMOL_PARSER;
+  /**
+   * Allowed values are PDB or mmCIF
+   */
+  private final static String DEFAULT_STRUCTURE_FORMAT = PDBEntry.Type.MMCIF
+          .toString();
+
+  private final static String DEFAULT_PDB_FILE_PARSER = StructureImportSettings.StructureParser.JMOL_PARSER
+          .toString();
 
   /**
    * Initialises the Jalview Application Log
@@ -433,8 +439,6 @@ public class Cache
     StructureImportSettings
             .setDefaultPDBFileParser(jalview.bin.Cache.getDefault(
                     "DEFAULT_PDB_FILE_PARSER", DEFAULT_PDB_FILE_PARSER));
-    StructureImportSettings.setProcessHETATMs(jalview.bin.Cache.getDefault(
-            "PROCESS_HETATM", false));
     // jnlpVersion will be null if we're using InstallAnywhere
     // Dont do this check if running in headless mode
     if (jnlpVersion == null
index efdf0ac..a641b1b 100755 (executable)
@@ -25,8 +25,6 @@ import jalview.api.DBRefEntryI;
 public class DBRefEntry implements DBRefEntryI
 {
   String source = "", version = "", accessionId = "";
-
-  private int startRes, endRes;
   /**
    * maps from associated sequence to the database sequence's coordinate system
    */
@@ -282,28 +280,4 @@ public class DBRefEntry implements DBRefEntryI
   {
     return getSrcAccString();
   }
-
-  @Override
-  public int getStartRes()
-  {
-    return startRes;
-  }
-
-  @Override
-  public void setStartRes(int startRes)
-  {
-    this.startRes = startRes;
-  }
-
-  @Override
-  public int getEndRes()
-  {
-    return endRes;
-  }
-
-  @Override
-  public void setEndRes(int endRes)
-  {
-    this.endRes = endRes;
-  }
 }
index ea347ae..baebe08 100644 (file)
@@ -31,6 +31,7 @@ import jalview.util.MessageManager;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Vector;
@@ -176,7 +177,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener
           prot.add(chainseq);
         }
 
-        if (StructureImportSettings.isPredictSecondaryStructure())
+        if (StructureImportSettings.isProcessSecondaryStructure())
         {
           createAnnotation(chainseq, chain, ms.at);
         }
@@ -194,17 +195,17 @@ public class JmolParser extends StructureFile implements JmolStatusListener
   private List<Atom> convertSignificantAtoms(ModelSet ms)
   {
     List<Atom> significantAtoms = new ArrayList<Atom>();
+    HashMap<String, org.jmol.modelset.Atom> chainTerMap = new HashMap<String, org.jmol.modelset.Atom>();
+    org.jmol.modelset.Atom prevAtom = null;
     for (org.jmol.modelset.Atom atom : ms.at)
     {
-      // System.out.println("Seq Id : " + atom.getSeqID());
-      // System.out.println("To String : " + atom.toString());
-      if (!StructureImportSettings.isProcessHETATMs() && atom.isHetero())
-      {
-        continue;
-      }
       if (atom.getAtomName().equalsIgnoreCase("CA")
               || atom.getAtomName().equalsIgnoreCase("P"))
       {
+        if (!atomValidated(atom, prevAtom, chainTerMap))
+        {
+          continue;
+        }
         Atom curAtom = new Atom(atom.x, atom.y, atom.z);
         curAtom.atomIndex = atom.getIndex();
         curAtom.chain = atom.getChainIDStr();
@@ -218,12 +219,65 @@ public class JmolParser extends StructureFile implements JmolStatusListener
         curAtom.resNumIns = "" + curAtom.resNumber + curAtom.insCode;
         curAtom.tfactor = atom.getBfactor100() / 100f;
         curAtom.type = 0;
-        significantAtoms.add(curAtom);
+        // significantAtoms.add(curAtom);
+        // ignore atoms from subsequent models
+        if (!significantAtoms.contains(curAtom))
+        {
+          significantAtoms.add(curAtom);
+        }
+        prevAtom = atom;
       }
     }
     return significantAtoms;
   }
 
+  private boolean atomValidated(org.jmol.modelset.Atom curAtom,
+          org.jmol.modelset.Atom prevAtom,
+          HashMap<String, org.jmol.modelset.Atom> chainTerMap)
+  {
+    // System.out.println("Atom: " + curAtom.getAtomNumber()
+    // + "   Last atom index " + curAtom.group.lastAtomIndex);
+    if (chainTerMap == null || prevAtom == null)
+    {
+      return true;
+    }
+    String curAtomChId = curAtom.getChainIDStr();
+    String prevAtomChId = prevAtom.getChainIDStr();
+    // new chain encoutered
+    if (!prevAtomChId.equals(curAtomChId))
+    {
+      // On chain switch add previous chain termination to xTerMap if not exists
+      if (!chainTerMap.containsKey(prevAtomChId))
+      {
+        chainTerMap.put(prevAtomChId, prevAtom);
+      }
+      // if current atom belongs to an already terminated chain and the resNum
+      // diff < 5 then mark as valid and update termination Atom
+      if (chainTerMap.containsKey(curAtomChId))
+      {
+        if ((curAtom.getResno() - chainTerMap.get(curAtomChId).getResno()) < 5)
+        {
+          chainTerMap.put(curAtomChId, curAtom);
+          return true;
+        }
+        return false;
+      }
+    }
+    // atom with previously terminated chain encountered
+    else if (chainTerMap.containsKey(curAtomChId))
+    {
+      if ((curAtom.getResno() - chainTerMap.get(curAtomChId).getResno()) < 5)
+      {
+        chainTerMap.put(curAtomChId, curAtom);
+        return true;
+      }
+      return false;
+    }
+    // HETATM with resNum jump > 2
+    return !(curAtom.isHetero() && ((curAtom.getResno() - prevAtom
+            .getResno()) > 2));
+  }
+
   private void createAnnotation(SequenceI sequence, PDBChain chain,
           org.jmol.modelset.Atom[] jmolAtoms)
   {
index 3736791..15f88fb 100644 (file)
@@ -2831,7 +2831,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void expandViews_actionPerformed(ActionEvent e)
   {
-    Desktop.instance.explodeViews(this);
+    Desktop.explodeViews(this);
   }
 
   /**
index d54e553..7811e41 100644 (file)
@@ -1806,7 +1806,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * 
    * @param af
    */
-  public void explodeViews(AlignFrame af)
+  public static void explodeViews(AlignFrame af)
   {
     int size = af.alignPanels.size();
     if (size < 2)
index af820ca..68245b6 100644 (file)
@@ -2377,12 +2377,20 @@ public class Jalview2XML
           if (true) // !skipViewport(object))
           {
             _af = loadFromObject(object, file, true, jprovider);
-            if (object.getJalviewModelSequence().getViewportCount() > 0)
+            if (_af != null
+                    && object.getJalviewModelSequence().getViewportCount() > 0)
             {
-              af = _af;
-              if (af.viewport.isGatherViewsHere())
+              if (af == null)
               {
-                gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
+                // store a reference to the first view
+                af = _af;
+              }
+              if (_af.viewport.isGatherViewsHere())
+              {
+                // if this is a gathered view, keep its reference since
+                // after gathering views, only this frame will remain
+                af = _af;
+                gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
               }
               // Save dataset to register mappings once all resolved
               importedDatasets.put(af.viewport.getAlignment().getDataset(),
index fca7263..55bb03d 100755 (executable)
@@ -26,6 +26,7 @@ import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
+import jalview.datamodel.PDBEntry.Type;
 import jalview.structure.StructureImportSettings;
 import jalview.util.MessageManager;
 
@@ -282,7 +283,8 @@ public class AppletFormatAdapter
         // Set value to 'true' to test PDB processing with Jmol: JAL-1213
         boolean isParseWithJMOL = StructureImportSettings
                 .getDefaultPDBFileParser().equalsIgnoreCase(
-                        StructureImportSettings.JMOL_PARSER);
+                        StructureImportSettings.StructureParser.JMOL_PARSER
+                                .toString());
         if (isParseWithJMOL)
         {
           StructureImportSettings.addSettings(annotFromStructure,
@@ -302,7 +304,7 @@ public class AppletFormatAdapter
         }
         ((StructureFile) alignFile).setDbRefType(format);
       }
-      else if (format.equals("mmCIF"))
+      else if (format.equalsIgnoreCase("mmCIF"))
       {
         StructureImportSettings.addSettings(annotFromStructure,
                 localSecondaryStruct, serviceSecondaryStruct);
@@ -450,17 +452,15 @@ public class AppletFormatAdapter
           alignFile = new MCview.PDBfile(annotFromStructure,
                   localSecondaryStruct, serviceSecondaryStruct, source);
         }
-        ((StructureFile) alignFile)
-                .setDbRefType(StructureImportSettings.PDB);
+        ((StructureFile) alignFile).setDbRefType(Type.PDB);
       }
-      else if (format.equals("mmCIF"))
+      else if (format.equalsIgnoreCase("mmCIF"))
       {
         StructureImportSettings.addSettings(annotFromStructure,
                 localSecondaryStruct, serviceSecondaryStruct);
         alignFile = new jalview.ext.jmol.JmolParser(annotFromStructure,
                 localSecondaryStruct, serviceSecondaryStruct, source);
-        ((StructureFile) alignFile)
-                .setDbRefType(StructureImportSettings.MMCIF);
+        ((StructureFile) alignFile).setDbRefType(Type.MMCIF);
       }
       else if (format.equals("STH"))
       {
index 97e11eb..fc0e207 100644 (file)
@@ -8,6 +8,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.PDBEntry;
+import jalview.datamodel.PDBEntry.Type;
 import jalview.datamodel.SequenceI;
 import jalview.structure.StructureImportSettings;
 
@@ -25,7 +26,7 @@ public abstract class StructureFile extends AlignFile
 
   private String id;
 
-  private String dbRefType;
+  private PDBEntry.Type dbRefType;
 
   /**
    * set to true to add derived sequence annotations (temp factor read from
@@ -70,7 +71,7 @@ public abstract class StructureFile extends AlignFile
     this.visibleChainAnnotation = StructureImportSettings
             .isVisibleChainAnnotation();
     this.predictSecondaryStructure = StructureImportSettings
-            .isPredictSecondaryStructure();
+            .isProcessSecondaryStructure();
     this.externalSecondaryStructure = StructureImportSettings
             .isExternalSecondaryStructure();
 
@@ -116,8 +117,6 @@ public abstract class StructureFile extends AlignFile
     DBRefEntry sourceDBRef = new DBRefEntry();
     sourceDBRef.setAccessionId(getId());
     sourceDBRef.setSource(DBRefSource.PDB);
-    sourceDBRef.setStartRes(pdbSequence.getStart());
-    sourceDBRef.setEndRes(pdbSequence.getEnd());
     pdbSequence.setSourceDBRef(sourceDBRef);
     pdbSequence.addPDBId(entry);
     pdbSequence.addDBRef(sourceDBRef);
@@ -273,7 +272,7 @@ public abstract class StructureFile extends AlignFile
         StructureImportSettings.setShowSeqFeatures(false);
         StructureImportSettings.setVisibleChainAnnotation(false);
         StructureImportSettings
-                .setPredictSecondaryStructure(predictSecondaryStructure);
+                .setProcessSecondaryStructure(predictSecondaryStructure);
         StructureImportSettings
                 .setExternalSecondaryStructure(externalSecondaryStructure);
         Object jmf = constructor.newInstance(args);
@@ -401,13 +400,18 @@ public abstract class StructureFile extends AlignFile
     this.chains = chains;
   }
 
-  public String getDbRefType()
+  public Type getDbRefType()
   {
     return dbRefType;
   }
 
   public void setDbRefType(String dbRefType)
   {
+    this.dbRefType = Type.valueOf(dbRefType);
+  }
+
+  public void setDbRefType(Type dbRefType)
+  {
     this.dbRefType = dbRefType;
   }
 
index 4c06e0f..82b5f69 100644 (file)
@@ -1,7 +1,15 @@
 package jalview.structure;
 
-import jalview.datamodel.DBRefSource;
-
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.PDBEntry.Type;
+
+/**
+ * bean holding settings for structure IO. TODO: tests for validation of values
+ * TODO: tests for race conditions (all fields are static, is that correct ?)
+ * 
+ * @author tcofoegbu
+ *
+ */
 public class StructureImportSettings
 {
   /**
@@ -14,7 +22,7 @@ public class StructureImportSettings
    * Set true to predict secondary structure (using JMol for protein, Annotate3D
    * for RNA)
    */
-  private static boolean predictSecStr = false;
+  private static boolean processSecStr = false;
 
   /**
    * Set true (with predictSecondaryStructure=true) to predict secondary
@@ -24,32 +32,28 @@ public class StructureImportSettings
 
   private static boolean showSeqFeatures = true;
 
-  private static boolean processHETATMs = false;
-
-  public static final String JMOL_PARSER = "JMolParser";
-
-  public static final String JALVIEW_PARSER = "JalViewParser";
-
-  public static final String MMCIF = "mmCIF";
+  public enum StructureParser
+  {
+    JMOL_PARSER, JALVIEW_PARSER
+  }
 
-  public static final String PDB = "PDB";
 
   /**
    * Determines the default file format for structure files to be downloaded
    * from the PDB sequence fetcher. Possible options include: PDB|mmCIF
    */
-  private static String defaultStructureFileFormat = DBRefSource.PDB;
+  private static PDBEntry.Type defaultStructureFileFormat = Type.PDB;
 
   /**
    * Determines the parser used for parsing PDB format file. Possible options
    * are : JMolParser|JalveiwParser
    */
-  private static String defaultPDBFileParser = JMOL_PARSER;
+  private static StructureParser defaultPDBFileParser = StructureParser.JMOL_PARSER;
   public static void addSettings(boolean addAlignmentAnnotations,
-          boolean predictSecStr, boolean externalSecStr)
+          boolean processSecStr, boolean externalSecStr)
   {
     StructureImportSettings.visibleChainAnnotation = addAlignmentAnnotations;
-    StructureImportSettings.predictSecStr = predictSecStr;
+    StructureImportSettings.processSecStr = processSecStr;
     StructureImportSettings.externalSecondaryStructure = externalSecStr;
     StructureImportSettings.showSeqFeatures = true;
   }
@@ -65,15 +69,15 @@ public class StructureImportSettings
     StructureImportSettings.visibleChainAnnotation = visibleChainAnnotation;
   }
 
-  public static boolean isPredictSecondaryStructure()
+  public static boolean isProcessSecondaryStructure()
   {
-    return predictSecStr;
+    return processSecStr;
   }
 
-  public static void setPredictSecondaryStructure(
-          boolean predictSecondaryStructure)
+  public static void setProcessSecondaryStructure(
+          boolean processSecondaryStructure)
   {
-    StructureImportSettings.predictSecStr = predictSecondaryStructure;
+    StructureImportSettings.processSecStr = processSecondaryStructure;
   }
 
   public static boolean isExternalSecondaryStructure()
@@ -99,33 +103,31 @@ public class StructureImportSettings
 
   public static String getDefaultStructureFileFormat()
   {
-    return defaultStructureFileFormat;
+    return defaultStructureFileFormat.toString();
   }
 
   public static void setDefaultStructureFileFormat(
           String defaultStructureFileFormat)
   {
-    StructureImportSettings.defaultStructureFileFormat = defaultStructureFileFormat;
+    StructureImportSettings.defaultStructureFileFormat = PDBEntry.Type
+            .valueOf(defaultStructureFileFormat.toUpperCase());
   }
 
-  public static boolean isProcessHETATMs()
-  {
-    return processHETATMs;
-  }
-
-  public static void setProcessHETATMs(boolean processHETATMs)
+  public static String getDefaultPDBFileParser()
   {
-    StructureImportSettings.processHETATMs = processHETATMs;
+    return defaultPDBFileParser.toString();
   }
 
-  public static String getDefaultPDBFileParser()
+  public static void setDefaultPDBFileParser(
+          StructureParser defaultPDBFileParser)
   {
-    return defaultPDBFileParser;
+    StructureImportSettings.defaultPDBFileParser = defaultPDBFileParser;
   }
 
   public static void setDefaultPDBFileParser(String defaultPDBFileParser)
   {
-    StructureImportSettings.defaultPDBFileParser = defaultPDBFileParser;
+    StructureImportSettings.defaultPDBFileParser = StructureParser
+            .valueOf(defaultPDBFileParser.toUpperCase());
   }
 
 }
index fb96b22..be042e6 100644 (file)
@@ -385,7 +385,11 @@ public class StructureSelectionManager
     try
     {
 
-      if (pdbFile != null && isCIFFile(pdbFile))
+      boolean isParseWithJMOL = StructureImportSettings
+              .getDefaultPDBFileParser().equalsIgnoreCase(
+                      StructureImportSettings.StructureParser.JMOL_PARSER
+                              .toString());
+      if (isParseWithJMOL || (pdbFile != null && isCIFFile(pdbFile)))
       {
         pdb = new jalview.ext.jmol.JmolParser(addTempFacAnnot, parseSecStr,
                 secStructServices, pdbFile, protocol);
index 1a58466..61c5c04 100644 (file)
@@ -27,6 +27,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.PDBEntry;
+import jalview.datamodel.PDBEntry.Type;
 import jalview.datamodel.SequenceI;
 import jalview.io.FormatAdapter;
 import jalview.io.PDBFeatureSettings;
@@ -133,8 +134,7 @@ public class Pdb extends EbiFileRetrievedProxy
       return null;
     }
     String ext = StructureImportSettings.getDefaultStructureFileFormat()
-            .equalsIgnoreCase("mmcif") ? ".cif"
-            : ".xml";
+            .equalsIgnoreCase(Type.MMCIF.toString()) ? ".cif" : ".xml";
     EBIFetchClient ebi = new EBIFetchClient();
     file = ebi.fetchDataAsFile("pdb:" + id,
             StructureImportSettings.getDefaultStructureFileFormat().toLowerCase(),
index 0010321..7ab058e 100644 (file)
@@ -31,6 +31,7 @@ import jalview.gui.AlignFrame;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.FileLoader;
 import jalview.structure.StructureImportSettings;
+import jalview.structure.StructureImportSettings.StructureParser;
 
 import java.util.Vector;
 
@@ -91,7 +92,7 @@ public class JmolParserTest
             Boolean.TRUE.toString());
     StructureImportSettings.setDefaultStructureFileFormat("PDB");
     StructureImportSettings
-            .setDefaultPDBFileParser(StructureImportSettings.JALVIEW_PARSER);
+            .setDefaultPDBFileParser(StructureParser.JALVIEW_PARSER);
   }
 
   @Test(groups = { "Functional" })
@@ -109,7 +110,6 @@ public class JmolParserTest
   @Test(groups = { "Functional" })
   public void testFileParser() throws Exception
   {
-    StructureImportSettings.setProcessHETATMs(false);
     for (String pdbStr : testFile)
     {
       PDBfile mctest = new PDBfile(false, false, false, pdbStr,
@@ -133,30 +133,7 @@ public class JmolParserTest
         validateSecStrRows(al);
       }
     }
-    StructureImportSettings.setProcessHETATMs(true);
-    for (String pdbStr : testFile)
-    {
-      PDBfile mctest = new PDBfile(false, false, false, pdbStr,
-              AppletFormatAdapter.FILE);
-      JmolParser jtest = new JmolParser(false, false, false, pdbStr,
-              jalview.io.AppletFormatAdapter.FILE);
-      Vector<SequenceI> seqs = jtest.getSeqs(), mcseqs = mctest.getSeqs();
 
-      assertTrue(
-              "No sequences extracted from testfile\n"
-                      + (jtest.hasWarningMessage() ? jtest.getWarningMessage()
-                              : "(No warnings raised)"), seqs != null
-                      && seqs.size() > 0);
-      for (SequenceI sq : seqs)
-      {
-        assertEquals("JMol didn't process " + pdbStr
-                + " to the same sequence as MCView",
-                sq.getSequenceAsString(), mcseqs.remove(0)
-                        .getSequenceAsString());
-        AlignmentI al = new Alignment(new SequenceI[] { sq });
-        validateSecStrRows(al);
-      }
-    }
   }
 
   private void validateSecStrRows(AlignmentI al)
diff --git a/test/jalview/ext/jmol/JmolVsJalviewPDBParserEndToEndTest.java b/test/jalview/ext/jmol/JmolVsJalviewPDBParserEndToEndTest.java
new file mode 100644 (file)
index 0000000..8a89830
--- /dev/null
@@ -0,0 +1,102 @@
+package jalview.ext.jmol;
+
+import jalview.datamodel.SequenceI;
+import jalview.io.AppletFormatAdapter;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import MCview.PDBfile;
+
+/**
+ * This is not a unit test, rather it is a bulk End-to-End scan for sequences
+ * consistency for PDB files parsed with JmolParser vs. Jalview's PDBfile
+ * parser. The directory of PDB files to test must be provided in the launch
+ * args.
+ * 
+ * @author tcnofoegbu
+ *
+ */
+public class JmolVsJalviewPDBParserEndToEndTest
+{
+
+  public static void main(String[] args)
+  {
+    if (args == null || args[0] == null)
+    {
+      System.err
+              .println("You must provide a PDB directory in the launch argument");
+      return;
+    }
+
+    // args[0] must provide the directory of PDB files to run the test with
+    String testDir = args[0];
+    System.out.println("PDB directory : " + testDir);
+    File pdbDir = new File(testDir);
+    String testFiles[] = pdbDir.list();
+    testFileParser(testDir, testFiles);
+  }
+
+  public static void testFileParser(String testDir, String[] testFiles)
+  {
+    Set<String> failedFiles = new HashSet<String>();
+    int totalSeqScanned = 0, totalFail = 0;
+    for (String pdbStr : testFiles)
+    {
+      String testFile = testDir + "/" + pdbStr;
+      PDBfile mctest = null;
+      JmolParser jtest = null;
+      try
+      {
+        mctest = new PDBfile(false, false, false, testFile,
+                AppletFormatAdapter.FILE);
+        jtest = new JmolParser(false, false, false, testFile,
+                jalview.io.AppletFormatAdapter.FILE);
+      } catch (IOException e)
+      {
+        System.err.println("Exception thrown while parsing : " + pdbStr);
+      }
+      Vector<SequenceI> seqs = jtest.getSeqs();
+      Vector<SequenceI> mcseqs = mctest.getSeqs();
+
+      for (SequenceI sq : seqs)
+      {
+        try
+        {
+        String testSeq = mcseqs.remove(0).getSequenceAsString();
+          if (!sq.getSequenceAsString().equals(testSeq))
+        {
+          ++totalFail;
+            System.err.println("Test Failed for " + pdbStr + ". Diff:");
+          System.err.println(sq.getSequenceAsString());
+          System.err.println(testSeq);
+          failedFiles.add(pdbStr);
+        }
+          ++totalSeqScanned;
+        } catch (Exception e)
+        {
+          e.printStackTrace();
+        }
+      }
+    }
+    int count = 0;
+
+    System.out.println("\n\nTotal sequence Scanned : " + totalSeqScanned);
+    System.out.println("Total sequence passed : "
+            + (totalSeqScanned - totalFail));
+    System.out.println("Total sequence failed : " + totalFail);
+    System.out
+            .println("Success rate: "
+                    + ((totalSeqScanned - totalFail) * 100)
+                    / totalSeqScanned + "%");
+    System.out.println("\nList of " + failedFiles.size()
+            + " file(s) with sequence diffs:");
+    for (String problemFile : failedFiles)
+    {
+      System.out.println(++count + ". " + problemFile);
+    }
+  }
+}
index 5368d41..e6019aa 100644 (file)
@@ -32,6 +32,7 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
 import jalview.structure.StructureImportSettings;
+import jalview.structure.StructureImportSettings.StructureParser;
 
 import java.io.File;
 
@@ -68,7 +69,7 @@ public class AnnotatedPDBFileInputTest
             .get(0).getId();
     StructureImportSettings.setDefaultStructureFileFormat("PDB");
     StructureImportSettings
-            .setDefaultPDBFileParser(StructureImportSettings.JALVIEW_PARSER);
+            .setDefaultPDBFileParser(StructureParser.JALVIEW_PARSER);
   }
 
   @Test(groups = { "Functional" })
index 38153df..ddc615f 100644 (file)
@@ -44,7 +44,9 @@ import jalview.schemes.ColourSchemeI;
 import jalview.viewmodel.AlignmentViewport;
 
 import java.io.File;
+import java.time.Instant;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -67,6 +69,9 @@ public class Jalview2xmlTests
   {
     jalview.bin.Jalview.main(new String[] { "-props",
         "test/jalview/io/testProps.jvprops" });
+    jalview.bin.Cache.setProperty("JALVIEW_NEWS_RSS_LASTMODIFIED",
+            Cache.date_format.format(Date.from(Instant.now().plusSeconds(
+                    3600))));
   }
 
   /**
@@ -364,37 +369,29 @@ public class Jalview2xmlTests
   }
 
   /**
-   * test store and recovery of expanded views - currently this is disabled
-   * since the Desktop.explodeViews method doesn't seem to result in the views
-   * being expanded to distinct align frames when executed programmatically.
+   * test store and recovery of expanded views
    * 
    * @throws Exception
    */
   @Test(groups = { "Functional" }, enabled = true)
   public void testStoreAndRecoverExpandedviews() throws Exception
   {
+    Desktop.instance.closeAll_actionPerformed(null);
+
     AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
             "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
     assertTrue("Didn't read in the example file correctly.", af != null);
+    Assert.assertEquals(Desktop.getAlignFrames().length, 1);
     String afid = af.getViewport().getSequenceSetId();
-    {
-      final AlignFrame xaf = af;
-      af = null;
-      new Thread(new Runnable()
-      {
-        @Override
-        public void run()
-        {
-          Desktop.instance.explodeViews(xaf);
-        }
-      }).start();
-      Thread.sleep(1000);
-    }
-    // int times = 0;
-    // while (++times < 5 && Desktop.getAlignFrames().length < )
-    // {
-    // Thread.sleep(300);
-    // }
+
+    // check FileLoader returned a reference to the one alignFrame that is
+    // actually on the Desktop
+    assertTrue(
+            "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window",
+            af == Desktop.getAlignFrameFor(af.getViewport()));
+
+    Desktop.explodeViews(af);
+
     int oldviews = Desktop.getAlignFrames().length;
     Assert.assertEquals(Desktop.getAlignFrames().length,
             Desktop.getAlignmentPanels(afid).length);
index d082785..fda0198 100644 (file)
@@ -26,6 +26,7 @@ import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
 import jalview.structure.StructureImportSettings;
+import jalview.structure.StructureImportSettings.StructureParser;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.util.List;
@@ -88,7 +89,7 @@ public class PDBSequenceFetcherTest
             Boolean.TRUE.toString());
     StructureImportSettings.setDefaultStructureFileFormat("PDB");
     StructureImportSettings
-            .setDefaultPDBFileParser(StructureImportSettings.JALVIEW_PARSER);
+            .setDefaultPDBFileParser(StructureParser.JALVIEW_PARSER);
 
     testRetrieveProteinSeqFromPDB();
   }
index 9141bad..6f9a864 100644 (file)
@@ -251,8 +251,6 @@ public class SiftsClientTest
 
     // TODO delete when auto-fetching of DBRefEntry is implemented
     DBRefEntry dbRef = new DBRefEntry("uniprot", "", "P00221");
-    dbRef.setStartRes(1);
-    dbRef.setEndRes(147);
     testSeq.addDBRef(dbRef);
     // testSeq.setSourceDBRef(dbRef);
 
@@ -327,8 +325,6 @@ public class SiftsClientTest
       DBRefEntryI expectedDBRef = new DBRefEntry();
       expectedDBRef.setSource(DBRefSource.UNIPROT);
       expectedDBRef.setAccessionId("P00221");
-      expectedDBRef.setStartRes(1);
-      expectedDBRef.setEndRes(147);
       expectedDBRef.setVersion("");
       Assert.assertEquals(actualValidSrcDBRef, expectedDBRef);
     } catch (Exception e)
@@ -376,8 +372,6 @@ public class SiftsClientTest
     DBRefEntryI validDBRef = new DBRefEntry();
     validDBRef.setSource(DBRefSource.UNIPROT);
     validDBRef.setAccessionId("P00221");
-    validDBRef.setStartRes(1);
-    validDBRef.setEndRes(147);
     validDBRef.setVersion("");
     Assert.assertTrue(siftsClient.isValidDBRefEntry(validDBRef));
   }