44ce60b3d0df85679ab13a1d2ee0da0f3a175252
[jalview.git] / src / jalview / io / SequenceFeatureFetcher.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4 *\r
5 * This program is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU General Public License\r
7 * as published by the Free Software Foundation; either version 2\r
8 * of the License, or (at your option) any later version.\r
9 *\r
10 * This program is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 * GNU General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU General Public License\r
16 * along with this program; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18 */\r
19 package jalview.io;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import jalview.gui.*;\r
24 \r
25 import java.io.*;\r
26 \r
27 import java.util.*;\r
28 \r
29 import org.exolab.castor.mapping.Mapping;\r
30 \r
31 import org.exolab.castor.xml.*;\r
32 import jalview.analysis.AlignSeq;\r
33 \r
34 \r
35 \r
36 /**\r
37  * DOCUMENT ME!\r
38  *\r
39  * @author $author$\r
40  * @version $Revision$\r
41  */\r
42 public class SequenceFeatureFetcher implements Runnable\r
43 {\r
44 \r
45   AlignmentI align;\r
46   AlignmentI dataset;\r
47   AlignmentPanel ap;\r
48   ArrayList unknownSequences;\r
49   CutAndPasteTransfer output = new CutAndPasteTransfer();\r
50   StringBuffer sbuffer = new StringBuffer();\r
51 \r
52   Vector getUniprotEntries(File file)\r
53   {\r
54 \r
55     UniprotFile uni = new UniprotFile();\r
56     try\r
57     {\r
58       // 1. Load the mapping information from the file\r
59       Mapping map = new Mapping(uni.getClass().getClassLoader());\r
60       java.net.URL url = uni.getClass().getResource("/uniprot_mapping.xml");\r
61       map.loadMapping(url);\r
62 \r
63       // 2. Unmarshal the data\r
64       Unmarshaller unmar = new Unmarshaller();\r
65       unmar.setIgnoreExtraElements(true);\r
66       unmar.setMapping(map);\r
67       uni = (UniprotFile) unmar.unmarshal(new FileReader(file));\r
68 \r
69     }\r
70     catch (Exception e)\r
71     {\r
72       System.out.println("Error getUniprotEntries() "+e);\r
73     }\r
74     return uni.getUniprotEntries();\r
75   }\r
76 \r
77   /**\r
78    * Creates a new SequenceFeatureFetcher object.\r
79    *\r
80    * @param align DOCUMENT ME!\r
81    * @param ap DOCUMENT ME!\r
82    */\r
83   public SequenceFeatureFetcher(AlignmentI align, AlignmentPanel ap)\r
84   {\r
85     unknownSequences = new ArrayList();\r
86     this.align = align;\r
87     this.dataset = align.getDataset();\r
88     this.ap = ap;\r
89 \r
90     Thread thread = new Thread(this);\r
91     thread.start();\r
92   }\r
93 \r
94   /**\r
95    * DOCUMENT ME!\r
96    */\r
97   public void run()\r
98   {\r
99     try\r
100     {\r
101       int seqIndex = 0;\r
102       Vector sequences = dataset.getSequences();\r
103 \r
104       while (seqIndex < sequences.size())\r
105       {\r
106         Vector ids = new Vector();\r
107 \r
108         for (int i = 0; (seqIndex < sequences.size()) && (i < 50);\r
109              seqIndex++, i++)\r
110         {\r
111           SequenceI sequence = (SequenceI) sequences.get(seqIndex);\r
112           if(!ids.contains(sequence.getName()))\r
113           {\r
114             ids.add(sequence.getName());\r
115             unknownSequences.add(sequence.getName());\r
116           }\r
117         }\r
118 \r
119         ///////////////////////////////////\r
120         ///READ FROM EBI\r
121         if (ids.size() > 0)\r
122         {\r
123           StringBuffer remainingIds = new StringBuffer("uniprot:");\r
124           for (int i = 0; i < ids.size(); i++)\r
125            {\r
126              remainingIds.append(ids.get(i) + ";");\r
127            }\r
128           EBIFetchClient ebi = new EBIFetchClient();\r
129           File file = ebi.fetchDataAsFile(remainingIds.toString(),\r
130                                           "xml", null);\r
131 \r
132 \r
133 \r
134           if (file != null)\r
135           {\r
136             ReadUniprotFile(file, ids);\r
137           }\r
138         }\r
139       }\r
140     }\r
141     catch (Exception ex)\r
142     {\r
143       ex.printStackTrace();\r
144     }\r
145 \r
146     if (sbuffer.length() > 0)\r
147     {\r
148       output.setText(\r
149           "Your sequences have been matched to Uniprot. Some of the ids have been\n" +\r
150           "altered, most likely the start/end residue will have been updated.\n" +\r
151           "Save your alignment to maintain the updated id.\n\n" +\r
152           sbuffer.toString());\r
153       Desktop.addInternalFrame(output, "Sequence names updated ", 600, 300);\r
154       // The above is the dataset, we must now find out the index\r
155       // of the viewed sequence\r
156 \r
157     }\r
158 \r
159     if (unknownSequences.size() > 0)\r
160     {\r
161       int reply = javax.swing.JOptionPane.showInternalConfirmDialog(\r
162           Desktop.desktop, "Couldn't find a match for "+unknownSequences.size()+" sequences."\r
163               +"\nPerform blast for unknown sequences?",\r
164                   "Blast for Unidentified Sequences",\r
165                    javax.swing.JOptionPane.YES_NO_OPTION, javax.swing.JOptionPane.QUESTION_MESSAGE);\r
166 \r
167       if(reply == javax.swing.JOptionPane.YES_OPTION)\r
168        new WSWUBlastClient(ap, align, unknownSequences);\r
169     }\r
170     else\r
171        ((Alignment)dataset).featuresAdded = true;\r
172 \r
173 \r
174     ap.repaint();\r
175   }\r
176 \r
177   /**\r
178    * DOCUMENT ME!\r
179    *\r
180    * @param result DOCUMENT ME!\r
181    * @param out DOCUMENT ME!\r
182    * @param align DOCUMENT ME!\r
183    */\r
184   void ReadUniprotFile(File file, Vector ids)\r
185   {\r
186     if(!file.exists())\r
187       return;\r
188 \r
189     SequenceI sequence = null;\r
190     //       String pdb = null;\r
191 \r
192     Vector entries = getUniprotEntries(file);\r
193 \r
194     int i, iSize = entries==null?0:entries.size();\r
195     UniprotEntry entry;\r
196     for (i = 0; i < iSize; i++)\r
197     {\r
198       entry = (UniprotEntry) entries.elementAt(i);\r
199       String idmatch = entry.getAccession().elementAt(0).toString();\r
200       sequence = dataset.findName(idmatch);\r
201 \r
202       if (sequence == null)\r
203       {\r
204         //Sequence maybe Name, not Accession\r
205         idmatch = entry.getName().elementAt(0).toString();;\r
206         sequence = dataset.findName(idmatch);\r
207       }\r
208 \r
209       if (sequence == null)\r
210       {\r
211         System.out.println("not found");\r
212         continue;\r
213       }\r
214 \r
215       ids.remove(sequence.getName());\r
216       unknownSequences.remove(sequence.getName());\r
217 \r
218       String nonGapped = AlignSeq.extractGaps("-. ", sequence.getSequence());\r
219 \r
220       int absStart = entry.getUniprotSequence().getContent().indexOf(\r
221           nonGapped.toString());\r
222 \r
223       if (absStart == -1)\r
224       {\r
225         unknownSequences.add(sequence.getName());\r
226         sbuffer.append(sequence.getName() +\r
227                        " SEQUENCE NOT %100 MATCH \n");\r
228 \r
229         continue;\r
230       }\r
231 \r
232       int absEnd = absStart + nonGapped.toString().length();\r
233       absStart += 1;\r
234 \r
235       sequence.setSequenceFeatures(entry.getFeatures());\r
236       sequence.setStart(absStart);\r
237       sequence.setEnd(absEnd);\r
238 \r
239 \r
240       int n = 0;\r
241       SequenceI seq2;\r
242       while (n < align.getHeight())\r
243       {\r
244         //This loop enables multiple sequences with the same\r
245         //id to have features added and seq limits updated\r
246         seq2 = align.getSequenceAt(n);\r
247         if (seq2.getName().equals(idmatch))\r
248         {\r
249 \r
250           nonGapped = AlignSeq.extractGaps("-. ", seq2.getSequence());\r
251 \r
252           absStart = sequence.getSequence().indexOf(nonGapped);\r
253           absEnd = absStart + nonGapped.toString().length() - 1;\r
254 \r
255           // This is the Viewd alignment sequences\r
256           // No need to tell the user of the dataset updates\r
257           if ( (seq2.getStart() != absStart+sequence.getStart())\r
258              || (seq2.getEnd() != absEnd+sequence.getStart()))\r
259           {\r
260             sbuffer.append("Updated: " + seq2.getName() + " " +\r
261                            seq2.getStart() + "/" + seq2.getEnd() +\r
262                            "  to  " + (absStart + sequence.getStart()) + "/" +\r
263                            (absEnd + sequence.getStart()) + "\n");\r
264 \r
265             seq2.setStart(absStart + sequence.getStart());\r
266             seq2.setEnd(absEnd + sequence.getStart());\r
267           }\r
268         }\r
269 \r
270         n++;\r
271       }\r
272     }\r
273   }\r
274 }\r
275 \r
276 \r