1 /* 2 * Jalview - A Sequence Alignment Editor and Viewer (2.11.1.4) 3 * Copyright (C) 2021 The Jalview Authors 4 * 5 * This file is part of Jalview. 6 * 7 * Jalview is free software: you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation, either version 3 10 * of the License, or (at your option) any later version. 11 * 12 * Jalview is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty 14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 15 * PURPOSE. See the GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>. 19 * The Jalview Authors are detailed in the 'AUTHORS' file. 20 */ 21 package jalview.io; 22 23 import jalview.analysis.AlignSeq; 24 import jalview.datamodel.AlignmentI; 25 import jalview.datamodel.DBRefEntry; 26 import jalview.datamodel.Sequence; 27 import jalview.gui.AlignmentPanel; 28 import jalview.gui.CutAndPasteTransfer; 29 import jalview.gui.Desktop; 30 import jalview.gui.JvOptionPane; 31 import jalview.util.MessageManager; 32 33 import java.util.ArrayList; 34 import java.util.Enumeration; 35 import java.util.StringTokenizer; 36 import java.util.Vector; 37 38 import javax.swing.ImageIcon; 39 40 import uk.ac.ebi.www.Data; 41 import uk.ac.ebi.www.InputParams; 42 import uk.ac.ebi.www.WSFile; 43 import uk.ac.ebi.www.WSWUBlast; 44 import uk.ac.ebi.www.WSWUBlastService; 45 import uk.ac.ebi.www.WSWUBlastServiceLocator; 46 47 /** 48 * DOCUMENT ME! 49 * 50 * @author $author$ 51 * @version $Revision$ 52 */ 53 public class WSWUBlastClient 54 { 55 AlignmentPanel ap; 56 57 AlignmentI al; 58 59 CutAndPasteTransfer output = new CutAndPasteTransfer(); 60 61 int jobsRunning = 0; 62 63 Vector suggestedIds = new Vector(); 64 65 /** 66 * Creates a new WSWUBlastClient object. 67 * 68 * @param al 69 * DOCUMENT ME! 70 * @param ids 71 * DOCUMENT ME! 72 */ WSWUBlastClient(AlignmentPanel ap, AlignmentI al, ArrayList ids)73 public WSWUBlastClient(AlignmentPanel ap, AlignmentI al, ArrayList ids) 74 { 75 this.ap = ap; 76 this.al = al; 77 output.setText( 78 MessageManager.getString("label.wswublast_client_credits")); 79 80 Desktop.addInternalFrame(output, MessageManager.getString( 81 "label.blasting_for_unidentified_sequence"), 800, 300); 82 83 for (int i = 0; i < ids.size(); i++) 84 { 85 Sequence sequence = (Sequence) ids.get(i); 86 System.out.println(sequence.getName()); 87 88 BlastThread thread = new BlastThread(sequence); 89 thread.start(); 90 jobsRunning++; 91 } 92 93 ImageTwirler thread = new ImageTwirler(); 94 thread.start(); 95 } 96 97 /** 98 * DOCUMENT ME! 99 * 100 * @param id1 101 * DOCUMENT ME! 102 * @param res 103 * DOCUMENT ME! 104 */ parseResult(Sequence seq, String res)105 void parseResult(Sequence seq, String res) 106 { 107 StringTokenizer st = new StringTokenizer(res, "\n"); 108 String data; 109 String id2; 110 int maxFound = 90; 111 StringBuffer buffer = new StringBuffer("\n\n" + seq.getName() + " :"); 112 113 while (st.hasMoreTokens()) 114 { 115 data = st.nextToken(); 116 117 if (data.indexOf(">UNIPROT") > -1) 118 { 119 int index = data.indexOf(">UNIPROT") + 9; 120 id2 = data.substring(index, data.indexOf(" ", index)); 121 122 boolean identitiesFound = false; 123 while (!identitiesFound) 124 { 125 data = st.nextToken(); 126 127 if (data.indexOf("Identities") > -1) 128 { 129 identitiesFound = true; 130 131 int value = Integer.parseInt(data 132 .substring(data.indexOf("(") + 1, data.indexOf("%"))); 133 134 if (value >= maxFound) 135 { 136 maxFound = value; 137 buffer.append(" " + id2 + " " + value + "%; "); 138 suggestedIds.addElement(new Object[] { seq, id2 }); 139 } 140 } 141 } 142 } 143 } 144 145 output.appendText(buffer.toString()); 146 } 147 updateIds()148 void updateIds() 149 { 150 // This must be outside the run() body as java 1.5 151 // will not return any value from the OptionPane to the expired thread. 152 int reply = JvOptionPane.showConfirmDialog(Desktop.desktop, 153 "Automatically update suggested ids?", 154 "Auto replace sequence ids", JvOptionPane.YES_NO_OPTION); 155 156 if (reply == JvOptionPane.YES_OPTION) 157 { 158 Enumeration keys = suggestedIds.elements(); 159 while (keys.hasMoreElements()) 160 { 161 Object[] object = (Object[]) keys.nextElement(); 162 163 Sequence oldseq = (Sequence) object[0]; 164 165 oldseq.setName(object[1].toString()); 166 167 // Oldseq is actually in the dataset, we must find the 168 // Visible seq and change its name also. 169 for (int i = 0; i < al.getHeight(); i++) 170 { 171 if (al.getSequenceAt(i).getDatasetSequence() == oldseq) 172 { 173 al.getSequenceAt(i).setName(oldseq.getName()); 174 break; 175 } 176 } 177 178 DBRefEntry[] entries = oldseq.getDBRefs(); 179 if (entries != null) 180 { 181 oldseq.addDBRef(new jalview.datamodel.DBRefEntry( 182 jalview.datamodel.DBRefSource.UNIPROT, "0", 183 entries[0].getAccessionId())); 184 } 185 } 186 } 187 ap.paintAlignment(true, false); 188 189 } 190 191 class ImageTwirler extends Thread 192 { 193 ImageIcon[] imageIcon; 194 195 int imageIndex = 0; 196 ImageTwirler()197 public ImageTwirler() 198 { 199 imageIcon = new ImageIcon[9]; 200 201 for (int i = 0; i < 9; i++) 202 { 203 java.net.URL url = getClass() 204 .getResource("/images/dna" + (i + 1) + ".gif"); 205 206 if (url != null) 207 { 208 imageIcon[i] = new ImageIcon(url); 209 } 210 } 211 } 212 213 @Override run()214 public void run() 215 { 216 while (jobsRunning > 0) 217 { 218 try 219 { 220 Thread.sleep(100); 221 imageIndex++; 222 imageIndex %= 9; 223 output.setFrameIcon(imageIcon[imageIndex]); 224 output.setTitle(MessageManager.formatMessage( 225 "label.blasting_for_unidentified_sequence_jobs_running", 226 new String[] 227 { Integer.valueOf(jobsRunning).toString() })); 228 } catch (Exception ex) 229 { 230 } 231 } 232 233 if (jobsRunning == 0) 234 { 235 updateIds(); 236 } 237 } 238 } 239 240 class BlastThread extends Thread 241 { 242 Sequence sequence; 243 244 String jobid; 245 246 boolean jobComplete = false; 247 BlastThread(Sequence sequence)248 BlastThread(Sequence sequence) 249 { 250 System.out.println("blasting for: " + sequence.getName()); 251 this.sequence = sequence; 252 } 253 254 @Override run()255 public void run() 256 { 257 StartJob(); 258 259 while (!jobComplete) 260 { 261 try 262 { 263 WSWUBlastService service = new WSWUBlastServiceLocator(); 264 WSWUBlast wublast = service.getWSWUBlast(); 265 WSFile[] results = wublast.getResults(jobid); 266 267 if (results != null) 268 { 269 String result = new String(wublast.poll(jobid, "tooloutput")); 270 parseResult(sequence, result); 271 jobComplete = true; 272 jobsRunning--; 273 } 274 else 275 { 276 Thread.sleep(10000); 277 System.out.println("WSWuBlastClient: I'm alive " 278 + sequence.getName() + " " + jobid); // log.debug 279 } 280 } catch (Exception ex) 281 { 282 } 283 } 284 } 285 StartJob()286 void StartJob() 287 { 288 InputParams params = new InputParams(); 289 290 params.setProgram("blastp"); 291 params.setDatabase("uniprot"); 292 params.setMatrix("pam10"); 293 294 params.setNumal(5); 295 params.setSensitivity("low"); 296 params.setSort("totalscore"); 297 params.setOutformat("txt"); 298 params.setAsync(true); 299 300 try 301 { 302 Data inputs[] = new Data[1]; 303 Data input = new Data(); 304 input.setType("sequence"); 305 input.setContent(AlignSeq.extractGaps("-. ", 306 sequence.getSequenceAsString())); 307 inputs[0] = input; 308 309 WSWUBlastService service = new WSWUBlastServiceLocator(); 310 WSWUBlast wublast = service.getWSWUBlast(); 311 jobid = wublast.runWUBlast(params, inputs); 312 } catch (Exception exp) 313 { 314 jobComplete = true; 315 jobsRunning--; 316 System.err.println("WSWUBlastClient error:\n" + exp.toString()); 317 exp.printStackTrace(); 318 } 319 } 320 } 321 } 322