Merge branch 'develop' into spike/JAL-4047/JAL-4048_columns_in_sequenceID
[jalview.git] / src / jalview / io / StructureFile.java
index d39ab38..df384a6 100644 (file)
  */
 package jalview.io;
 
+import java.awt.Color;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.net.MalformedURLException;
+import java.util.List;
+import java.util.Vector;
+
 import jalview.analysis.AlignSeq;
 import jalview.api.FeatureSettingsModelI;
 import jalview.datamodel.Alignment;
@@ -30,26 +37,15 @@ import jalview.datamodel.DBRefSource;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
 import jalview.datamodel.SequenceI;
+import jalview.ext.jmol.JmolParser;
 import jalview.structure.StructureImportSettings;
-
-import java.awt.Color;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.util.List;
-import java.util.Vector;
-
-import MCview.PDBChain;
+import jalview.structure.StructureImportSettings.TFType;
+import mc_view.PDBChain;
 
 public abstract class StructureFile extends AlignFile
 {
-
   private String id;
 
-  public enum StructureFileType
-  {
-    PDB, MMCIF, MMTF
-  };
-
   private PDBEntry.Type dbRefType;
 
   /**
@@ -74,15 +70,70 @@ public abstract class StructureFile extends AlignFile
 
   private boolean pdbIdAvailable;
 
-  public StructureFile(String inFile, DataSourceType sourceType)
+  private TFType temperatureFactorType = TFType.DEFAULT;
+
+  private String paeMatrix = null;
+
+  private boolean alphaFoldModel;
+
+  public void setPAEMatrix(String paeFilename)
+  {
+    paeMatrix = paeFilename;
+  }
+
+  public String getPAEMatrix()
+  {
+    return paeMatrix;
+  }
+
+  public boolean hasPAEMatrix()
+  {
+    return paeMatrix != null;
+  }
+
+  public void setTemperatureFactorType(TFType t)
+  {
+    this.temperatureFactorType = t;
+  }
+
+  public TFType getTemperatureFactorType()
+  {
+    return temperatureFactorType;
+  }
+
+  public void setAlphafoldModel(boolean afm)
+  {
+    alphaFoldModel = afm;
+  }
+
+  public boolean isAlphafoldModel()
+  {
+    return alphaFoldModel;
+  }
+
+  public StructureFile(Object inFile, DataSourceType sourceType)
           throws IOException
   {
-    super(inFile, sourceType);
+    this(inFile, sourceType, null);
+  }
+
+  public StructureFile(Object inFile, DataSourceType sourceType,
+          TFType tempfacType) throws IOException
+  {
+    super(false, inFile, sourceType);
+    this.setTemperatureFactorType(tempfacType);
+    doParse();
   }
 
   public StructureFile(FileParse fp) throws IOException
   {
-    super(fp);
+    this(fp, true);
+  }
+
+  public StructureFile(FileParse fp, boolean doXferSettings)
+          throws IOException
+  {
+    super(fp, doXferSettings);
   }
 
   public void addSettings(boolean addAlignmentAnnotations,
@@ -95,16 +146,20 @@ public abstract class StructureFile extends AlignFile
 
   public void xferSettings()
   {
-    this.visibleChainAnnotation = StructureImportSettings
-            .isVisibleChainAnnotation();
-    this.predictSecondaryStructure = StructureImportSettings
-            .isProcessSecondaryStructure();
-    this.externalSecondaryStructure = StructureImportSettings
-            .isExternalSecondaryStructure();
-
+    if (this.getDoXferSettings())
+    {
+      this.visibleChainAnnotation = StructureImportSettings
+              .isVisibleChainAnnotation();
+      this.predictSecondaryStructure = StructureImportSettings
+              .isProcessSecondaryStructure();
+      this.externalSecondaryStructure = StructureImportSettings
+              .isExternalSecondaryStructure();
+      this.temperatureFactorType = StructureImportSettings
+              .getTemperatureFactorType();
+    }
   }
 
-  public StructureFile(boolean parseImmediately, String dataObject,
+  public StructureFile(boolean parseImmediately, Object dataObject,
           DataSourceType sourceType) throws IOException
   {
     super(parseImmediately, dataObject, sourceType);
@@ -125,6 +180,7 @@ public abstract class StructureFile extends AlignFile
     pdbSequence.setName(getId() + "|" + pdbSequence.getName());
     PDBEntry entry = new PDBEntry();
     entry.setId(getId());
+    entry.setFakedPDBId(!isPPDBIdAvailable());
     entry.setType(getStructureFileType());
     if (chain.id != null)
     {
@@ -186,7 +242,7 @@ public abstract class StructureFile extends AlignFile
   protected void processPdbFileWithAnnotate3d(List<SequenceI> rna)
           throws Exception
   {
-    // System.out.println("this is a PDB format and RNA sequence");
+    // jalview.bin.Console.outPrintln("this is a PDB format and RNA sequence");
     // note: we use reflection here so that the applet can compile and run
     // without the HTTPClient bits and pieces needed for accessing Annotate3D
     // web service
@@ -197,11 +253,13 @@ public abstract class StructureFile extends AlignFile
       {
         // TODO: use the PDB ID of the structure if one is available, to save
         // bandwidth and avoid uploading the whole structure to the service
-        Object annotate3d = cl.getConstructor(new Class[] {}).newInstance(
-                new Object[] {});
-        AlignmentI al = ((AlignmentI) cl.getMethod("getRNAMLFor",
-                new Class[] { FileParse.class }).invoke(annotate3d,
-                new Object[] { new FileParse(getDataName(), dataSourceType) }));
+        Object annotate3d = cl.getConstructor(new Class[] {})
+                .newInstance(new Object[] {});
+        AlignmentI al = ((AlignmentI) cl
+                .getMethod("getRNAMLFor", new Class[]
+                { FileParse.class })
+                .invoke(annotate3d, new Object[]
+                { new FileParse(getDataName(), dataSourceType) }));
         for (SequenceI sq : al.getSequences())
         {
           if (sq.getDatasetSequence() != null)
@@ -228,8 +286,8 @@ public abstract class StructureFile extends AlignFile
   }
 
   @SuppressWarnings("unchecked")
-  protected void replaceAndUpdateChains(List<SequenceI> prot,
-          AlignmentI al, String pep, boolean b)
+  protected void replaceAndUpdateChains(List<SequenceI> prot, AlignmentI al,
+          String pep, boolean b)
   {
     List<List<? extends Object>> replaced = AlignSeq
             .replaceMatchingSeqsWith(seqs, annotations, prot, al, pep,
@@ -278,7 +336,7 @@ public abstract class StructureFile extends AlignFile
         processPdbFileWithAnnotate3d(rnaSequences);
       } catch (Exception x)
       {
-        System.err.println("Exceptions when dealing with RNA in pdb file");
+        jalview.bin.Console.errPrintln("Exceptions when dealing with RNA in pdb file");
         x.printStackTrace();
 
       }
@@ -291,59 +349,54 @@ public abstract class StructureFile extends AlignFile
     {
       try
       {
-        processWithJmolParser(proteinSequences);
+        processWithJmolParser(proteinSequences, true);
       } catch (Exception x)
       {
-        System.err
-                .println("Exceptions from Jmol when processing data in pdb file");
+        jalview.bin.Console.errPrintln(
+                "Exceptions from Jmol when processing data in pdb file");
         x.printStackTrace();
       }
     }
   }
 
-  @SuppressWarnings({ "unchecked", "rawtypes" })
-  private void processWithJmolParser(List<SequenceI> prot) throws Exception
+  private void processWithJmolParser(List<SequenceI> prot,
+          boolean doXferSettings) throws MalformedURLException, IOException
   {
-    try
-    {
+    FileParse fp = new FileParse(getDataName(), dataSourceType);
 
-      Class cl = Class.forName("jalview.ext.jmol.JmolParser");
-      if (cl != null)
+    StructureImportSettings.setShowSeqFeatures(false);
+    StructureImportSettings.setVisibleChainAnnotation(false);
+    StructureImportSettings
+            .setProcessSecondaryStructure(predictSecondaryStructure);
+    StructureImportSettings
+            .setExternalSecondaryStructure(externalSecondaryStructure);
+    StructureImportSettings.setTemperatureFactorType(temperatureFactorType);
+    JmolParser jmf = new JmolParser(fp, doXferSettings);
+    AlignmentI al = new Alignment((SequenceI[]) jmf.getSeqsAsArray());
+    jmf.addAnnotations(al);
+    for (SequenceI sq : al.getSequences())
+    {
+      if (sq.getDatasetSequence() != null)
       {
-        final Constructor constructor = cl.getConstructor(new Class[] {FileParse.class });
-        final Object[] args = new Object[] { new FileParse(getDataName(), dataSourceType) };
-
-        StructureImportSettings.setShowSeqFeatures(false);
-        StructureImportSettings.setVisibleChainAnnotation(false);
-        StructureImportSettings
-                .setProcessSecondaryStructure(predictSecondaryStructure);
-        StructureImportSettings
-                .setExternalSecondaryStructure(externalSecondaryStructure);
-        Object jmf = constructor.newInstance(args);
-        AlignmentI al = new Alignment((SequenceI[]) cl.getMethod(
-                "getSeqsAsArray", new Class[] {}).invoke(jmf));
-        cl.getMethod("addAnnotations", new Class[] { AlignmentI.class })
-                .invoke(jmf, al);
-        for (SequenceI sq : al.getSequences())
-        {
-          if (sq.getDatasetSequence() != null)
-          {
-            sq.getDatasetSequence().getAllPDBEntries().clear();
-          }
-          else
-          {
-            sq.getAllPDBEntries().clear();
-          }
-        }
-        replaceAndUpdateChains(prot, al, AlignSeq.PEP, false);
+        sq.getDatasetSequence().getAllPDBEntries().clear();
+      }
+      else
+      {
+        sq.getAllPDBEntries().clear();
       }
-    } catch (ClassNotFoundException q)
-    {
     }
+    replaceAndUpdateChains(prot, al, AlignSeq.PEP, false);
     StructureImportSettings.setShowSeqFeatures(true);
   }
 
-  public PDBChain findChain(String id) throws Exception
+  /**
+   * Answers the first PDBChain found matching the given id, or null if none is
+   * found
+   * 
+   * @param id
+   * @return
+   */
+  public PDBChain findChain(String id)
   {
     for (PDBChain chain : getChains())
     {
@@ -352,7 +405,7 @@ public abstract class StructureFile extends AlignFile
         return chain;
       }
     }
-    throw new Exception("PDB chain not Found!");
+    return null;
   }
 
   public void makeResidueList()
@@ -398,8 +451,10 @@ public abstract class StructureFile extends AlignFile
 
   public static boolean isRNA(SequenceI seq)
   {
-    for (char c : seq.getSequence())
+    int length = seq.getLength();
+    for (int i = 0; i < length; i++)
     {
+      char c = seq.getCharAt(i);
       if ((c != 'A') && (c != 'C') && (c != 'G') && (c != 'U'))
       {
         return false;
@@ -412,7 +467,8 @@ public abstract class StructureFile extends AlignFile
    * make a friendly ID string.
    * 
    * @param dataName
-   * @return truncated dataName to after last '/'
+   * @return truncated dataName to after last '/' and pruned .extension if
+   *         present
    */
   protected String safeName(String dataName)
   {
@@ -421,6 +477,10 @@ public abstract class StructureFile extends AlignFile
     {
       dataName = dataName.substring(p + 1);
     }
+    if (dataName.indexOf(".") > -1)
+    {
+      dataName = dataName.substring(0, dataName.lastIndexOf("."));
+    }
     return dataName;
   }
 
@@ -488,20 +548,4 @@ public abstract class StructureFile extends AlignFile
   {
     this.pdbIdAvailable = pdbIdAvailable;
   }
-
-  public static boolean isStructureFile(String fileType)
-  {
-    if (fileType == null)
-    {
-      return false;
-    }
-    for (StructureFileType sfType : StructureFileType.values())
-    {
-      if (sfType.name().equalsIgnoreCase(fileType))
-      {
-        return true;
-      }
-    }
-    return false;
-  }
 }