more robust parsing for DBset/DBname|id1|id2 type ids
[jalview.git] / src / jalview / io / FastaFile.java
1 package jalview.io;\r
2 \r
3 import jalview.datamodel.*;\r
4 import jalview.analysis.*;\r
5 \r
6 import java.io.*;\r
7 import java.util.*;\r
8 \r
9 public class FastaFile extends AlignFile {\r
10 \r
11   public FastaFile()\r
12   {}\r
13 \r
14   public FastaFile(String inStr) {\r
15     super(inStr);\r
16   }\r
17 \r
18   public FastaFile(String inFile, String type) throws IOException {\r
19     super(inFile,type);\r
20   }\r
21 \r
22   public void parse() throws IOException\r
23   {\r
24 \r
25     String       id    = "";\r
26     StringBuffer seq   = new StringBuffer();\r
27     int          count = 0;\r
28     boolean      flag  = false;\r
29 \r
30     int          sstart = 0;\r
31     int          send   = 0;\r
32 \r
33     String line;\r
34 \r
35       while ((line = nextLine()) != null) {\r
36 \r
37         if (line.length() > 0) {\r
38 \r
39           // Do we have an id line?\r
40 \r
41           if (line.substring(0,1).equals(">")) {\r
42 \r
43             if (count != 0) {\r
44               if (sstart != 0) {\r
45                 seqs.addElement(new Sequence(id,seq.toString().toUpperCase(),sstart,send));\r
46               } else {\r
47                 seqs.addElement(new Sequence(id,seq.toString().toUpperCase(),1,seq.length()));\r
48               }\r
49             }\r
50 \r
51             count++;\r
52 \r
53             StringTokenizer str = new StringTokenizer(line," ");\r
54 \r
55             id = str.nextToken();\r
56             id = id.substring(1);\r
57             com.stevesoft.pat.Regex dbId = new com.stevesoft.pat.Regex("[A-Za-z-]+/[A-Za-z-]+\\|(\\w+)\\|(.+)");\r
58             if (dbId.search(id))\r
59                {\r
60                  String dbid = dbId.stringMatched(1);\r
61                  String idname = dbId.stringMatched(2);\r
62                  if (idname.length()>0 && idname.indexOf("_") > -1)\r
63                  {\r
64                    id = idname; // just use friendly name // JBPNote: we may lose uniprot standardised ID here.\r
65                  }\r
66                  else\r
67                  {\r
68                    id = dbid; // use dbid to ensure sensible queries\r
69                  }\r
70 \r
71                }\r
72             if (id.indexOf("/") > 0 ) {\r
73 \r
74               StringTokenizer st = new StringTokenizer(id,"/");\r
75               if (st.countTokens() == 2) {\r
76                 id = st.nextToken();\r
77                 String tmp = st.nextToken();\r
78 \r
79                 st = new StringTokenizer(tmp,"-");\r
80 \r
81                 if (st.countTokens() == 2) {\r
82                   sstart = Integer.valueOf(st.nextToken()).intValue();\r
83                   send   = Integer.valueOf(st.nextToken()).intValue();\r
84                 }\r
85               }\r
86             }\r
87 \r
88             seq = new StringBuffer();\r
89 \r
90           } else {\r
91             seq = seq.append(line);\r
92           }\r
93         }\r
94       }\r
95       if (count > 0) {\r
96 \r
97         if(!isValidProteinSequence(seq.toString().toUpperCase()))\r
98           throw new IOException("Invalid protein sequence");\r
99 \r
100         if (sstart != 0) {\r
101           seqs.addElement(new Sequence(id,seq.toString().toUpperCase(),sstart,send));\r
102         } else {\r
103           seqs.addElement(new Sequence(id,seq.toString().toUpperCase(),1,seq.length()));\r
104         }\r
105       }\r
106 \r
107   }\r
108 \r
109   public static String print(SequenceI[] s) {\r
110     return print(s,72);\r
111   }\r
112   public static String print(SequenceI[] s, int len) {\r
113     return print(s,len,true);\r
114   }\r
115 \r
116   public static String print(SequenceI[] s, int len,boolean gaps) {\r
117     return print(s,len,gaps,true);\r
118   }\r
119 \r
120   public static String print(SequenceI[] s, int len,boolean gaps, boolean displayId) {\r
121     StringBuffer out = new StringBuffer();\r
122     int i = 0;\r
123     while (i < s.length && s[i] != null) {\r
124       String seq = "";\r
125       if (gaps) {\r
126         seq = s[i].getSequence();\r
127       } else {\r
128         seq = AlignSeq.extractGaps("-. ",s[i].getSequence());\r
129       }\r
130       // used to always put this here: + "/" + s[i].getStart() + "-" + s[i].getEnd() +\r
131       out.append(">" + ((displayId) ? s[i].getDisplayId() : s[i].getName())+"\n");\r
132 \r
133       int nochunks = seq.length() / len + 1;\r
134 \r
135       for (int j = 0; j < nochunks; j++) {\r
136         int start = j*len;\r
137         int end = start + len;\r
138 \r
139         if (end < seq.length()) {\r
140           out.append(seq.substring(start,end) + "\n");\r
141         } else if (start < seq.length()) {\r
142           out.append(seq.substring(start) + "\n");\r
143         }\r
144       }\r
145       i++;\r
146     }\r
147     return out.toString();\r
148   }\r
149 \r
150   public String print() {\r
151     return print(getSeqsAsArray());\r
152   }\r
153 }\r
154 \r
155 \r
156 \r