in progress
[jalview.git] / forester / java / src / org / forester / archaeopteryx / tools / Blast.java
1 // $Id:
2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
4 //
5 // Copyright (C) 2008-2009 Christian M. Zmasek
6 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
7 // All rights reserved
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 //
23 // Contact: phylosoft @ gmail . com
24 // WWW: www.phylosoft.org/forester
25
26 package org.forester.archaeopteryx.tools;
27
28
29 import java.io.IOException;
30 import java.net.URI;
31 import java.net.URISyntaxException;
32 import java.util.Arrays;
33 import java.util.Enumeration;
34 import java.util.Hashtable;
35 import java.util.Vector;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38
39 import javax.swing.JApplet;
40
41 import org.forester.archaeopteryx.AptxUtil;
42 import org.forester.archaeopteryx.TreePanel;
43 import org.forester.phylogeny.PhylogenyNode;
44 import org.forester.util.ForesterUtil;
45 import org.forester.ws.wabi.RestUtil;
46
47 public class Blast {
48
49     final static Pattern identifier_pattern_1 = Pattern.compile ("^([A-Za-z]{2,5})[|=:]([0-9A-Za-z\\.]{4,40})\\s*$");
50     final static Pattern identifier_pattern_2 = Pattern.compile ("^([A-Za-z]{2,5})[|=:]([0-9A-Za-z\\.]{4,40})[|,; ].*$");
51     
52     public Blast() {
53     }
54
55
56     public static void NcbiBlastWeb( String query, JApplet applet, TreePanel p ) {
57
58       //http://www.ncbi.nlm.nih.gov/blast/Blast.cgi?CMD=Web&PAGE=Proteins&DATABASE=swissprot&QUERY=gi|163848401
59         
60         
61         StringBuilder uri_str = new StringBuilder();
62         uri_str.append( "http://www.ncbi.nlm.nih.gov/blast/Blast.cgi?CMD=Web&DATABASE=nr&PAGE=Proteins&QUERY=" );
63         uri_str.append( query );
64         try {
65
66             AptxUtil.launchWebBrowser( new URI( uri_str.toString() ), applet != null, applet, "_aptx_blast" );
67         }
68         catch ( final IOException e ) {
69             AptxUtil.showErrorMessage( p, e.toString() );
70             e.printStackTrace();
71         }
72         catch ( final URISyntaxException e ) {
73             AptxUtil.showErrorMessage( p, e.toString() );
74             e.printStackTrace();
75         }
76
77     }
78     public static String obtainQueryForBlast( final PhylogenyNode node ) {
79         String query = "";
80         if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) {
81             query = node.getNodeData().getSequence().getMolecularSequence();
82         }
83         else if ( node.getNodeData().getSequence().getAccession() != null && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().getValue() ) ) {
84             if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().getSource() ) ) {
85                 query = node.getNodeData().getSequence().getAccession().getSource() + "%7C";
86             }
87             query += node.getNodeData().getSequence().getAccession().getValue();
88         }
89         else if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) {
90             String name = node.getNodeData().getSequence().getName();
91             final Matcher matcher1 = identifier_pattern_1.matcher( name );
92             final Matcher matcher2 = identifier_pattern_2.matcher( name );
93             String group1 = "";
94             String group2 = "";
95             
96             if ( matcher1.matches() ) {
97                 group1 =  matcher1.group( 1 );
98                 group2 =  matcher1.group( 2 );
99                 System.out.println( "1 1=" + group1 );
100
101                 System.out.println( "1 2=" + group2 );
102             }
103             if ( matcher2.matches() ) {
104                 group1 =  matcher2.group( 1 );
105                 group2 =  matcher2.group( 2 );
106                 System.out.println( "2 1=" + group1 );
107
108                 System.out.println( "2 2=" + group2 );
109             }
110             if (!ForesterUtil.isEmpty( group1 ) && !ForesterUtil.isEmpty( group2 )) {
111                 query = group1  + "%7C" + group2;
112             }
113
114         }
115        
116         
117         System.out.println( query );
118
119         return query;
120     }
121
122
123     public void ddbjBlast( final String geneName ) {
124         // Retrieve accession number list which has specified gene name from searchByXMLPath of ARSA. Please click here for details of ARSA.
125         /*target: Sequence length is between 300bp and 1000bp.
126         Feature key is CDS.
127         Gene qualifire is same as specified gene name.*/
128         String queryPath = "/ENTRY/DDBJ/division=='HUM' AND (/ENTRY/DDBJ/length>=300 AND "
129             + "/ENTRY/DDBJ/length<=1000) ";
130         queryPath += "AND (/ENTRY/DDBJ/feature-table/feature{/f_key = 'CDS' AND ";
131         queryPath += "/f_quals/qualifier{/q_name = 'gene' AND /q_value=='" + geneName + "'}})";
132         String query = "service=ARSA&method=searchByXMLPath&queryPath=" + queryPath
133         + "&returnPath=/ENTRY/DDBJ/primary-accession&offset=1&count=100";
134         //Execute ARSA
135         String arsaResult = null;
136         try {
137             arsaResult = RestUtil.getResult( query );
138         }
139         catch ( final IOException e ) {
140             // TODO Auto-generated catch block
141             e.printStackTrace();
142         }
143         final String[] arsaResultLines = arsaResult.split( "\n" );
144         //Get hit count
145         final int arsaResultNum = Integer.parseInt( arsaResultLines[ 0 ].replaceAll( "hitscount       =", "" ).trim() );
146         //If there is no hit, print a message and exit
147         if ( arsaResultNum == 0 ) {
148             System.out.println( "There is no entry for gene:" + geneName );
149             return;
150         }
151         //Retrieve DNA sequence of top hit entry by using getFASTA_DDBJEntry of GetEntry.
152         //Retrieve DNA sequence of first fit.
153         final String repAccession = arsaResultLines[ 2 ];
154         query = "service=GetEntry&method=getFASTA_DDBJEntry&accession=" + repAccession;
155         String dnaSeq = null;
156         try {
157             dnaSeq = RestUtil.getResult( query );
158         }
159         catch ( final IOException e ) {
160             // TODO Auto-generated catch block
161             e.printStackTrace();
162         }
163         System.out.println( "Retrieved DNA sequence is: " + dnaSeq );
164         //Execute blastn by using searchParam of Blast with step2's sequence. Specified option is -e 0.0001 -m 8 -b 50 -v 50. It means "Extract top 50 hit which E-value is more than 0.0001.". The reference databases are specified as follows. ddbjpri(primates) ddbjrod(rodents) ddbjmam(mammals) ddbjvrt(vertebrates ) ddbjinv(invertebrates).
165         //Execute blastn with step3's sequence
166         query = "service=Blast&method=searchParam&program=blastn&database=ddbjpri ddbjrod ddbjmam ddbjvrt "
167             + "ddbjinv&query=" + dnaSeq + "&param=-m 8 -b 50 -v 50 -e 0.0001";
168         String blastResult = null;
169         try {
170             blastResult = RestUtil.getResult( query );
171         }
172         catch ( final IOException e ) {
173             // TODO Auto-generated catch block
174             e.printStackTrace();
175         }
176         // Extract both accession number and similarity score from BLAST result.
177         // This step does not use Web API and extract the part of result or edit the result. Please click here to see the details of each column in the BLAST tab delimited format which is generated by -m 8 option.
178         final String blastResultLines[] = blastResult.split( "\n" );
179         final Vector<String[]> parsedBlastResult = new Vector<String[]>();
180         for( final String blastResultLine : blastResultLines ) {
181             final String cols[] = blastResultLine.split( "\t" );
182             final String accession = cols[ 1 ].substring( 0, cols[ 1 ].indexOf( "|" ) );
183             final String[] result = { accession, cols[ 2 ] };
184             parsedBlastResult.add( result );
185         }
186         // Retrieve species name by using searchByXMLPath of ARSA. If the plural subjects whose species
187         // name are same are in the result, the highest similarity score is used.
188         //Retrieve species from accession number.
189         final Hashtable<String, String> organismAccession = new Hashtable<String, String>();
190         for( int i = 0; i < parsedBlastResult.size(); i++ ) {
191             final String[] parsed = parsedBlastResult.elementAt( i );
192             query = "service=ARSA&method=searchByXMLPath&queryPath=/ENTRY/DDBJ/primary-accession=='" + parsed[ 0 ]
193                                                                                                                + "'&returnPath=/ENTRY/DDBJ/organism&offset=1&count=100";
194             String organism = null;
195             try {
196                 organism = RestUtil.getResult( query );
197             }
198             catch ( final IOException e ) {
199                 // TODO Auto-generated catch block
200                 e.printStackTrace();
201             }
202             final String[] organismLines = organism.split( "\n" );
203             organism = organismLines[ 2 ];
204             //If same organism name hits, use first hit.
205             if ( !organismAccession.containsKey( organism ) ) {
206                 organismAccession.put( organism, parsed[ 0 ] + "\t" + parsed[ 1 ] );
207             }
208         }
209         // Print result.
210         // Print Result
211         System.out.println( "DDBJ entries: " + arsaResultNum );
212         System.out.println( "Representative accession: " + repAccession );
213         System.out.println( "Organism name\tDDBJ accession number\tSequence similarity" );
214         final String[] keys = new String[ organismAccession.size() ];
215         final Enumeration<String> enu = organismAccession.keys();
216         int count = 0;
217         while ( enu.hasMoreElements() ) {
218             keys[ count ] = enu.nextElement();
219             ++count;
220         }
221         Arrays.sort( keys );
222         for( final String key : keys ) {
223             System.out.println( key + "\t" + organismAccession.get( key ) );
224         }
225     }
226 }