JAL-3032 adds Java 8 functionality (2/2)
[jalview.git] / src2 / fr / orsay / lri / varna / factories / RNAFactory.java
diff --git a/src2/fr/orsay/lri/varna/factories/RNAFactory.java b/src2/fr/orsay/lri/varna/factories/RNAFactory.java
new file mode 100644 (file)
index 0000000..c514f31
--- /dev/null
@@ -0,0 +1,805 @@
+package fr.orsay.lri.varna.factories;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EmptyStackException;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Stack;
+import java.util.Vector;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.InputSource;
+
+import fr.orsay.lri.varna.exceptions.ExceptionExportFailed;
+import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
+import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
+import fr.orsay.lri.varna.exceptions.ExceptionPermissionDenied;
+import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
+import fr.orsay.lri.varna.models.rna.ModeleBP;
+import fr.orsay.lri.varna.models.rna.ModeleBackboneElement;
+import fr.orsay.lri.varna.models.rna.ModeleBackboneElement.BackboneType;
+import fr.orsay.lri.varna.models.rna.ModeleBase;
+import fr.orsay.lri.varna.models.rna.RNA;
+import fr.orsay.lri.varna.utils.RNAMLParser;
+
+/**
+ * BH JAVA FIX: mostly here we are just removing a lot of unnecessary stack traces when doing a drag-drop of a file
+ * BH JAVA FIX: making sure the file reader is closed properly
+ *  
+ */
+public class RNAFactory
+{
+
+  public enum RNAFileType
+  {
+    FILE_TYPE_STOCKHOLM, FILE_TYPE_TCOFFEE, FILE_TYPE_BPSEQ, FILE_TYPE_CT, FILE_TYPE_DBN, FILE_TYPE_RNAML, FILE_TYPE_UNKNOWN
+  }
+
+private static boolean isQuiet;
+
+  public static ArrayList<RNA> loadSecStrRNAML(Reader r)
+      throws ExceptionPermissionDenied, ExceptionLoadingFailed,
+      ExceptionFileFormatOrSyntax
+  {
+
+    ArrayList<RNA> result = new ArrayList<RNA>();
+    try
+    {
+      // System.setProperty("javax.xml.parsers.SAXParserFactory",
+      // "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
+      SAXParserFactory saxFact = javax.xml.parsers.SAXParserFactory
+          .newInstance();
+      saxFact.setValidating(false);
+      saxFact.setXIncludeAware(false);
+      saxFact.setNamespaceAware(false);
+      SAXParser sp = saxFact.newSAXParser();
+      RNAMLParser RNAMLData = new RNAMLParser();
+      sp.parse(new InputSource(r), RNAMLData);
+
+      /*
+       * XMLReader xr = XMLReaderFactory.createXMLReader(); RNAMLParser
+       * RNAMLData = new RNAMLParser(); xr.setContentHandler(RNAMLData);
+       * xr.setErrorHandler(RNAMLData); xr.setEntityResolver(RNAMLData);
+       * xr.parse(new InputSource(r));
+       */
+      for (RNAMLParser.RNATmp rnaTmp : RNAMLData.getMolecules())
+      {
+        RNA current = new RNA();
+        // Retrieving parsed data
+        List<String> seq = rnaTmp.getSequence();
+        // Creating empty structure of suitable size
+        int[] str = new int[seq.size()];
+        for (int i = 0; i < str.length; i++)
+        {
+          str[i] = -1;
+        }
+        current.setRNA(seq, str);
+        Vector<RNAMLParser.BPTemp> allbpsTmp = rnaTmp.getStructure();
+        ArrayList<ModeleBP> allbps = new ArrayList<ModeleBP>();
+        for (int i = 0; i < allbpsTmp.size(); i++)
+        {
+          RNAMLParser.BPTemp bp = allbpsTmp.get(i);
+          // System.err.println(bp);
+          int bp5 = bp.pos5;
+          int bp3 = bp.pos3;
+          ModeleBase mb = current.getBaseAt(bp5);
+          ModeleBase part = current.getBaseAt(bp3);
+          ModeleBP newStyle = bp.createBPStyle(mb, part);
+          allbps.add(newStyle);
+        }
+
+        current.applyBPs(allbps);
+        result.add(current);
+      }
+
+    }
+    catch (IOException ioe)
+    {
+      throw new ExceptionLoadingFailed(
+          "Couldn't load file due to I/O or security policy issues.", "");
+    }
+    catch (Exception ge)
+    {
+       if (!isQuiet) // BH
+      ge.printStackTrace();
+    }
+    return result;
+  }
+
+  public static int[] parseSecStr(String _secStr)
+      throws ExceptionUnmatchedClosingParentheses
+  {
+    Hashtable<Character, Stack<Integer>> stacks = new Hashtable<Character, Stack<Integer>>();
+    int[] result = new int[_secStr.length()];
+    int i = 0;
+    try
+    {
+      for (i = 0; i < _secStr.length(); i++)
+      {
+        result[i] = -1;
+        char c = _secStr.charAt(i);
+        char c2 = Character.toUpperCase(c);
+        if (!stacks.containsKey(c2))
+        {
+          stacks.put(c2, new Stack<Integer>());
+        }
+        switch (c)
+        {
+        case '<':
+        case '{':
+        case '(':
+        case '[':
+          stacks.get(c).push(i);
+          break;
+        case '>':
+        {
+          int j = stacks.get('<').pop();
+          result[i] = j;
+          result[j] = i;
+          break;
+        }
+        case '}':
+        {
+          int j = stacks.get('{').pop();
+          result[i] = j;
+          result[j] = i;
+          break;
+        }
+        case ')':
+        {
+          int j = stacks.get('(').pop();
+          result[i] = j;
+          result[j] = i;
+          break;
+        }
+        case ']':
+        {
+          int j = stacks.get('[').pop();
+          result[i] = j;
+          result[j] = i;
+          break;
+        }
+        case '.':
+          break;
+        default:
+        {
+          if (Character.isLetter(c) && Character.isUpperCase(c))
+          {
+            stacks.get(c).push(i);
+          }
+          else if (Character.isLetter(c) && Character.isLowerCase(c))
+          {
+            int j = stacks.get(Character.toUpperCase(c)).pop();
+            result[i] = j;
+            result[j] = i;
+          }
+        }
+        }
+      }
+    }
+    catch (EmptyStackException e)
+    {
+      throw new ExceptionUnmatchedClosingParentheses(i);
+    }
+    return result;
+  }
+
+  public static ArrayList<RNA> loadSecStrDBN(Reader r)
+      throws ExceptionLoadingFailed, ExceptionPermissionDenied,
+      ExceptionUnmatchedClosingParentheses, ExceptionFileFormatOrSyntax
+  {
+    boolean loadOk = false;
+    ArrayList<RNA> result = new ArrayList<RNA>();
+    RNA current = new RNA();
+    try
+    {
+      BufferedReader fr = new BufferedReader(r);
+      String line = fr.readLine();
+      String title = "";
+      String seqTmp = "";
+      String strTmp = "";
+      while ((line != null) && (strTmp.equals("")))
+      {
+        line = line.trim();
+        if (!line.startsWith(">"))
+        {
+          if (seqTmp.equals(""))
+          {
+            seqTmp = line;
+          }
+          else
+          {
+            strTmp = line;
+          }
+        }
+        else
+        {
+          title = line.substring(1).trim();
+        }
+        line = fr.readLine();
+      }
+      if (strTmp.length() != 0)
+      {
+        current.setRNA(seqTmp, strTmp);
+        current.setName(title);
+        loadOk = true;
+      }
+    }
+    catch (IOException e)
+    {
+      throw new ExceptionLoadingFailed(e.getMessage(), "");
+    }
+    if (loadOk)
+    {
+      result.add(current);
+    }
+    return result;
+  }
+
+  public static ArrayList<RNA> loadSecStr(File f)
+             throws ExceptionFileFormatOrSyntax
+         {
+           try {
+                       return loadSecStr(new BufferedReader(new FileReader(f)), RNAFileType.FILE_TYPE_UNKNOWN);
+               } catch (FileNotFoundException e) {
+                       throw new ExceptionFileFormatOrSyntax(f.toString());
+               }
+         }
+
+  public static ArrayList<RNA> loadSecStr(Reader r)
+      throws ExceptionFileFormatOrSyntax
+  {
+    return loadSecStr(new BufferedReader(r), RNAFileType.FILE_TYPE_UNKNOWN);
+  }
+
+       public static ArrayList<RNA> loadSecStr(BufferedReader r, RNAFileType fileType) throws ExceptionFileFormatOrSyntax {
+               try {
+                       switch (fileType) {
+                       case FILE_TYPE_DBN: {
+                               try {
+                                       ArrayList<RNA> result = loadSecStrDBN(r);
+                                       if (result.size() != 0)
+                                               return result;
+                               } catch (Exception e) {
+                               }
+                       }
+                               break;
+                       case FILE_TYPE_CT: {
+                               try {
+                                       ArrayList<RNA> result = loadSecStrCT(r);
+                                       if (result.size() != 0)
+                                               return result;
+                               } catch (Exception e) {
+                                       if (!isQuiet) // BH
+                                               e.printStackTrace();
+                               }
+                       }
+                               break;
+                       case FILE_TYPE_BPSEQ: {
+                               try {
+                                       ArrayList<RNA> result = loadSecStrBPSEQ(r);
+                                       if (result.size() != 0)
+                                               return result;
+                               } catch (Exception e) {
+                                       if (!isQuiet) // BH
+                                               e.printStackTrace();
+                               }
+                       }
+                               break;
+                       case FILE_TYPE_TCOFFEE: {
+                               try {
+                                       ArrayList<RNA> result = loadSecStrTCoffee(r);
+                                       if (result.size() != 0)
+                                               return result;
+                               } catch (Exception e) {
+                                       if (!isQuiet) // BH
+                                               e.printStackTrace();
+                               }
+                       }
+                               break;
+                       case FILE_TYPE_STOCKHOLM: {
+                               try {
+                                       ArrayList<RNA> result = loadSecStrStockholm(r);
+                                       if (result.size() != 0)
+                                               return result;
+                               } catch (Exception e) {
+                                       if (!isQuiet) // BH
+                                               e.printStackTrace();
+                               }
+                       }
+                               break;
+                       case FILE_TYPE_RNAML: {
+                               try {
+                                       ArrayList<RNA> result = loadSecStrRNAML(r);
+                                       if (result.size() != 0)
+                                               return result;
+                               } catch (Exception e) {
+                                       if (!isQuiet) // BH
+                                               e.printStackTrace();
+                               }
+                       }
+                               break;
+
+                       case FILE_TYPE_UNKNOWN: {
+                               try {
+                                       r.mark(1000000);
+                                       RNAFactory.RNAFileType[] types = RNAFactory.RNAFileType.values();
+                                       isQuiet = true; // BH to not report errors when
+                                                                       // drag-dropping
+                                       ArrayList<RNA> result = null;
+                                       RNAFactory.RNAFileType t = null;
+                                       for (int i = 0; i < types.length; i++) {
+                                               r.reset();
+                                               t = types[i];
+                                               if (t != RNAFactory.RNAFileType.FILE_TYPE_UNKNOWN) {
+                                                       try {
+                                                               result = loadSecStr(r, t);
+                                                               if (result.size() != 0) {
+                                                                       break;
+                                                               }
+                                                       } catch (Exception e) {
+                                                               if (!isQuiet) // BH
+                                                                       System.err.println(e.toString());
+                                                       }
+                                               }
+                                       }
+                                       System.out.println(t); // BH
+                                       isQuiet = false; // BH
+                                       return result;
+                               } catch (IOException e2) {
+                                       e2.printStackTrace();
+                               }
+                       }
+                       }
+                       throw new ExceptionFileFormatOrSyntax("Couldn't parse this file as " + fileType + ".");
+               } finally { // BH !!
+                       try {
+                               if (!isQuiet)
+                                       r.close();
+                       } catch (IOException e) {
+                               // ignore
+                       }
+               }
+       }
+
+  public static RNAFileType guessFileTypeFromExtension(String path)
+  {
+    if (path.toLowerCase().endsWith("ml"))
+    {
+      return RNAFileType.FILE_TYPE_RNAML;
+    }
+    else if (path.toLowerCase().endsWith("dbn")
+        || path.toLowerCase().endsWith("faa"))
+    {
+      return RNAFileType.FILE_TYPE_DBN;
+    }
+    else if (path.toLowerCase().endsWith("ct"))
+    {
+      return RNAFileType.FILE_TYPE_CT;
+    }
+    else if (path.toLowerCase().endsWith("bpseq"))
+    {
+      return RNAFileType.FILE_TYPE_BPSEQ;
+    }
+    else if (path.toLowerCase().endsWith("rfold"))
+    {
+      return RNAFileType.FILE_TYPE_TCOFFEE;
+    }
+    else if (path.toLowerCase().endsWith("stockholm")
+        || path.toLowerCase().endsWith("stk"))
+    {
+      return RNAFileType.FILE_TYPE_STOCKHOLM;
+    }
+
+    return RNAFileType.FILE_TYPE_UNKNOWN;
+
+  }
+
+  public static ArrayList<RNA> loadSecStr(String path)
+      throws ExceptionExportFailed, ExceptionPermissionDenied,
+      ExceptionLoadingFailed, ExceptionFileFormatOrSyntax,
+      ExceptionUnmatchedClosingParentheses, FileNotFoundException
+  {
+    FileReader fr = null;
+    try
+    {
+      fr = new FileReader(path);
+      RNAFileType type = guessFileTypeFromExtension(path);
+      return loadSecStr(new BufferedReader(fr), type);
+    }
+    catch (ExceptionFileFormatOrSyntax e)
+    {
+      if (fr != null)
+        try
+        {
+          fr.close();
+        }
+        catch (IOException e2)
+        {
+        }
+      e.setPath(path);
+      throw e;
+    }
+  }
+
+  public static ArrayList<RNA> loadSecStrStockholm(BufferedReader r)
+      throws IOException, ExceptionUnmatchedClosingParentheses
+  {
+    RNAAlignment a = StockholmIO.readAlignement(r);
+    return a.getRNAs();
+  }
+
+  public static ArrayList<RNA> loadSecStrBPSEQ(Reader r)
+      throws ExceptionPermissionDenied, ExceptionLoadingFailed,
+      ExceptionFileFormatOrSyntax
+  {
+    boolean loadOk = false;
+    ArrayList<RNA> result = new ArrayList<RNA>();
+    RNA current = new RNA();
+    try
+    {
+      BufferedReader fr = new BufferedReader(r);
+      String line = fr.readLine();
+      ArrayList<String> seqTmp = new ArrayList<String>();
+      Hashtable<Integer, Vector<Integer>> strTmp = new Hashtable<Integer, Vector<Integer>>();
+
+      int bpFrom;
+      String base;
+      int bpTo;
+      int minIndex = -1;
+      boolean noWarningYet = true;
+      String title = "";
+      String id = "";
+      String filenameStr = "Filename:";
+      String organismStr = "Organism:";
+      String ANStr = "Accession Number:";
+      while (line != null)
+      {
+        line = line.trim();
+        String[] tokens = line.split("\\s+");
+        ArrayList<Integer> numbers  = new ArrayList<Integer>(); 
+        Hashtable<Integer,Integer> numberToIndex  = new Hashtable<Integer,Integer>(); 
+        if ((tokens.length >= 3) && !tokens[0].contains("#")
+            && !line.startsWith("Organism:") && !line.startsWith("Citation")
+            && !line.startsWith("Filename:")
+            && !line.startsWith("Accession Number:"))
+        {
+          base = tokens[1];
+          seqTmp.add(base);
+          bpFrom = (Integer.parseInt(tokens[0]));
+          numbers.add(bpFrom);
+          if (minIndex < 0)
+            minIndex = bpFrom;
+
+          if (seqTmp.size() < (bpFrom - minIndex + 1))
+          {
+            if (noWarningYet)
+            {
+              noWarningYet = false;
+              /*
+               * warningEmition( "Discontinuity detected between nucleotides " +
+               * (seqTmp.size()) + " and " + (bpFrom + 1) +
+               * "!\nFilling in missing portions with unpaired unknown 'X' nucleotides ..."
+               * );
+               */
+            }
+            while (seqTmp.size() < (bpFrom - minIndex + 1))
+            {
+              // System.err.println(".");
+              seqTmp.add("X");
+            }
+          }
+          for (int i = 2; i < tokens.length; i++)
+          {
+            bpTo = (Integer.parseInt(tokens[i]));
+            if ((bpTo != 0) || (i != tokens.length - 1))
+            {
+              if (!strTmp.containsKey(bpFrom))
+                strTmp.put(bpFrom, new Vector<Integer>());
+              strTmp.get(bpFrom).add(bpTo);
+            }
+          }
+        }
+        else if (tokens[0].startsWith("#"))
+        {
+          int occur = line.indexOf("#");
+          String tmp = line.substring(occur + 1);
+          title += tmp.trim() + " ";
+        }
+        else if (tokens[0].startsWith(filenameStr))
+        {
+          int occur = line.indexOf(filenameStr);
+          String tmp = line.substring(occur + filenameStr.length());
+          title += tmp.trim();
+        }
+        else if (tokens[0].startsWith(organismStr))
+        {
+          int occur = line.indexOf(organismStr);
+          String tmp = line.substring(occur + organismStr.length());
+          if (title.length() != 0)
+          {
+            title = "/" + title;
+          }
+          title = tmp.trim() + title;
+        }
+        else if (line.contains(ANStr))
+        {
+          int occur = line.indexOf(ANStr);
+          String tmp = line.substring(occur + ANStr.length());
+          id = tmp.trim();
+        }
+        line = fr.readLine();
+      }
+      if (strTmp.size() != 0)
+      {
+        ArrayList<String> seq = seqTmp;
+        int[] str = new int[seq.size()];
+        for (int i = 0; i < seq.size(); i++)
+        {
+          str[i] = -1;
+        }
+        current.setRNA(seq, str, minIndex);
+        ArrayList<ModeleBP> allbps = new ArrayList<ModeleBP>();
+        for (int i : strTmp.keySet())
+        {
+          for (int j : strTmp.get(i))
+          {
+                 if (i<=j)
+                 {
+                   ModeleBase mb = current.getBaseAt(i - minIndex);
+                   ModeleBase part = current.getBaseAt(j - minIndex);
+                   ModeleBP newStyle = new ModeleBP(mb, part);
+                   allbps.add(newStyle);
+                 }
+          }
+        }
+        current.applyBPs(allbps);
+        current.setName(title);
+        current.setID(id);
+        loadOk = true;
+      }
+    }
+    catch (NumberFormatException e)
+    {
+       if (!isQuiet) // BH SwingJS
+      e.printStackTrace();
+    }
+    catch (IOException e)
+    {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+    catch (Exception e)
+    {
+      throw new ExceptionLoadingFailed(e.getMessage(), "");
+    }
+    if (loadOk)
+      result.add(current);
+    return result;
+  }
+
+  public static ArrayList<RNA> loadSecStrTCoffee(Reader r)
+      throws ExceptionPermissionDenied, ExceptionLoadingFailed,
+      ExceptionFileFormatOrSyntax
+  {
+    boolean loadOk = false;
+    ArrayList<RNA> result = new ArrayList<RNA>();
+    try
+    {
+      BufferedReader fr = new BufferedReader(r);
+      String line = fr.readLine();
+      ArrayList<String> seqs = new ArrayList<String>();
+      ArrayList<String> ids = new ArrayList<String>();
+      int numSeqs = -1;
+      int currSeq = -1;
+      RNA current = null;
+      while (line != null)
+      {
+        if (!line.startsWith("!"))
+        {
+          String[] tokens = line.split("\\s+");
+          // This may indicate new secondary structure
+          if (line.startsWith("#"))
+          {
+            currSeq = Integer.parseInt(tokens[0].substring(1));
+            int currSeq2 = Integer.parseInt(tokens[1]);
+            // For TCoffee, a sec str is a matching between a seq and itself
+            // => Disregard any alignment by filtering on the equality of sequence indices.
+            if (currSeq == currSeq2)
+            {
+              current = new RNA();
+              current.setName(ids.get(currSeq - 1));
+              current.setSequence(seqs.get(currSeq - 1));
+              result.add(current);
+            }
+            else
+            {
+              current = null;
+            }
+          }
+          // Beginning of the file... 
+          else if (current == null)
+          {
+            //... either this is the number of sequences...
+            if (numSeqs < 0)
+            {
+              numSeqs = Integer.parseInt(tokens[0]);
+            }
+            //... or this is a sequence definition...
+            else
+            {
+              String id = tokens[0];
+              String seq = tokens[2];
+              seqs.add(seq);
+              ids.add(id);
+            }
+          }
+          //Otherwise, this is a base-pair definition, related to the currently selected sequence
+          else if (tokens.length == 3)
+          {
+            int from = Integer.parseInt(tokens[0]) - 1;
+            int to = Integer.parseInt(tokens[1]) - 1;
+            current.addBP(from, to);
+          }
+        }
+        line = fr.readLine();
+      }
+      loadOk = true;
+    }
+    catch (NumberFormatException e)
+    {
+       if (!isQuiet) // BH SwingJS
+      e.printStackTrace();
+    }
+    catch (IOException e)
+    {
+       if (!isQuiet) // BH SwingJS
+               e.printStackTrace();
+    }
+    if (!loadOk)
+    {
+      throw new ExceptionLoadingFailed("Parse Error", "");
+    }
+    return result;
+  }
+
+  public static ArrayList<RNA> loadSecStrCT(Reader r)
+      throws ExceptionPermissionDenied, ExceptionLoadingFailed,
+      ExceptionFileFormatOrSyntax
+  {
+    boolean loadOk = false;
+    ArrayList<RNA> result = new ArrayList<RNA>();
+    RNA current = new RNA();
+    try
+    {
+      BufferedReader fr = new BufferedReader(r);
+      String line = fr.readLine();
+      ArrayList<String> seq = new ArrayList<String>();
+      ArrayList<String> lbls = new ArrayList<String>();
+      Vector<Integer> strTmp = new Vector<Integer>();
+      Vector<Integer> newStrands = new Vector<Integer>();
+      int bpFrom;
+      String base;
+      String lbl;
+      int bpTo;
+      boolean noWarningYet = true;
+      int minIndex = -1;
+      String title = "";
+      while (line != null)
+      {
+        line = line.trim();
+        String[] tokens = line.split("\\s+");
+        if (tokens.length >= 6)
+        {
+          try
+          {
+            bpFrom = (Integer.parseInt(tokens[0]));
+            bpTo = (Integer.parseInt(tokens[4]));
+            if (minIndex == -1)
+              minIndex = bpFrom;
+            bpFrom -= minIndex;
+            if (bpTo != 0)
+              bpTo -= minIndex;
+            else
+              bpTo = -1;
+            base = tokens[1];
+            lbl = tokens[5];
+            int before = Integer.parseInt(tokens[2]);
+            int after = Integer.parseInt(tokens[3]);
+            
+            if (before==0 && !seq.isEmpty())
+            {
+               newStrands.add(strTmp.size()-1);
+            }
+            if (bpFrom != seq.size())
+            {
+              if (noWarningYet)
+              {
+                noWarningYet = false;
+                /*
+                 * warningEmition( "Discontinuity detected between nucleotides "
+                 * + (seq.size()) + " and " + (bpFrom + 1) +
+                 * "!\nFilling in missing portions with unpaired unknown 'X' nucleotides ..."
+                 * );
+                 */
+              }
+              while (bpFrom > seq.size())
+              {
+                seq.add("X");
+                strTmp.add(-1);
+                lbls.add("");
+              }
+            }
+            seq.add(base);
+            strTmp.add(bpTo);
+            lbls.add(lbl);
+          }
+          catch (NumberFormatException e)
+          {
+                 if (strTmp.size()!=0)
+                         e.printStackTrace();
+          }
+        }
+        if ((line.contains("ENERGY = ")) || line.contains("dG = "))
+        {
+          String[] ntokens = line.split("\\s+");
+          if (ntokens.length >= 4)
+          {
+            String energy = ntokens[3];
+            for (int i = 4; i < ntokens.length; i++)
+            {
+              title += ntokens[i] + " ";
+            }
+            title += "(E=" + energy + " kcal/mol)";
+          }
+        }
+        line = fr.readLine();
+      }
+      if (strTmp.size() != 0)
+      {
+        int[] str = new int[strTmp.size()];
+        for (int i = 0; i < strTmp.size(); i++)
+        {
+          str[i] = strTmp.elementAt(i).intValue();
+        }
+        current.setRNA(seq, str, minIndex);
+        current.setName(title);
+        for (int i = 0; i < current.getSize(); i++)
+        {
+          current.getBaseAt(i).setLabel(lbls.get(i));
+        }
+        for (int i : newStrands)
+        {
+               current.getBackbone().addElement(new ModeleBackboneElement(i,BackboneType.DISCONTINUOUS_TYPE));
+        }
+
+        
+        loadOk = true;
+      }
+    }
+    catch (IOException e)
+    {
+       e.printStackTrace();
+      throw new ExceptionLoadingFailed(e.getMessage(), "");
+    }
+    catch (NumberFormatException e)
+    {
+       if (!isQuiet) // BH SwingJS
+       e.printStackTrace();
+      throw new ExceptionFileFormatOrSyntax(e.getMessage(), "");
+    }
+    if (loadOk)
+      result.add(current);
+    return result;
+  }
+
+}