* @param seqRef
* @param startRes
* @param alreadyMapped
+ * - annotation are at aligned columns
*/
public void createSequenceMapping(SequenceI seqRef, int startRes,
boolean alreadyMapped)
setFont(new Font(fontName, style, Integer.parseInt(fontSize)), true);
- alignment
- .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0));
-
+ if (Cache.getDefault("NORMALISE_GAPS", true))
+ {
+ alignment.setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(
+ 0));
+ }
// We must set conservation and consensus before setting colour,
// as Blosum and Clustal require this to be done
if (hconsensus == null && !isDataset)
df.getContentPane().setLayout(new BorderLayout());
df.getContentPane().add(
(nulserv = !nulserv) ? new RestServiceEditorPane(
- jalview.ws.rest.RestClient
+ jalview.ws.rest.clientdefs.ShmrRestClient
.makeShmmrRestClient()
.getRestDescription())
: new RestServiceEditorPane(),
public class AnnotationColourGradient extends FollowerColourScheme
{
+ /**
+ * map positional scores to transparency rather than colour
+ */
+ boolean positionToTransparency = true;
+
+ /**
+ * compute shade based on annotation row score
+ */
+ boolean perLineScore = true;
+
public static final int NO_THRESHOLD = -1;
public static final int BELOW_THRESHOLD = 0;
acg.predefinedColours = predefinedColours;
acg.seqAssociated = seqAssociated;
acg.noGradient = noGradient;
+ acg.positionToTransparency = positionToTransparency;
+ acg.perLineScore = perLineScore;
return acg;
}
// resolve the context containing all the annotation for the sequence
AnnotatedCollectionI alcontext = alignment instanceof AlignmentI ? alignment
: alignment.getContext();
- boolean f = true, rna = false;
+ boolean f = true, sf = true, rna = false;
+ long plcount = 0, ancount = 0;
for (AlignmentAnnotation alan : alcontext.findAnnotation(annotation
.getCalcId()))
{
&& (alan.label != null && annotation != null && alan.label
.equals(annotation.label)))
{
+ ancount++;
if (!rna && alan.isRNA())
{
rna = true;
aamin = alan.graphMin;
}
f = false;
+ if (alan.score == alan.score)
+ {
+ if (sf || alan.score < plmin)
+ {
+ plmin = alan.score;
+ }
+ if (sf || alan.score > plmax)
+ {
+ plmax = alan.score;
+ }
+ sf = false;
+ plcount++;
+ }
}
}
+ if (plcount > 0 && plcount == ancount)
+ {
+ perLineScore = plcount == ancount;
+ aamax=plmax;
+ }
if (rna)
{
ColourSchemeProperty.initRnaHelicesShading(1 + (int) aamax);
}
}
- float aamin = 0f, aamax = 0f;
+ /**
+ * positional annotation max/min
+ */
+ double aamin = 0.0, aamax = 0.0;
+
+ /**
+ * per line score max/min
+ */
+ double plmin = Double.NaN, plmax = Double.NaN;
public String getAnnotation()
{
*
* @return DOCUMENT ME!
*/
+ @Override
public Color findColour(char c)
{
return Color.red;
range = 0f;
}
}
-
+ // midtr sets the ceiling for bleaching out the shading
+ int trans = 0, midtr = 239;
+ if (perLineScore)
+ {
+ trans = (int) ((1f - range) * midtr);
+ range = (float) ((annotation.score - plmin) / (plmax - aamin));
+ }
int dr = (int) (rr * range + r1), dg = (int) (gg * range + g1), db = (int) (bb
* range + b1);
-
- return new Color(dr, dg, db);
-
+ if (annotation.score == annotation.score && positionToTransparency)
+ {
+ return new Color(Integer.min(dr + trans, midtr), Integer.min(dg
+ + trans, midtr), Integer.min(db + trans, midtr));
+ }
+ else
+ {
+ return new Color(dr, dg, db);
+ }
}
public boolean isPredefinedColours()
*/
public static final boolean isGap(char c)
{
- return (c == GAP_DASH || c == GAP_DOT || c == GAP_SPACE) ? true : false;
+ return (c == GAP_DASH || c == GAP_DOT || c == GAP_SPACE);
}
/**
******************************************************************************/
package jalview.util;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
return false;
}
+ /**
+ * download from given URL and return a pointer to temporary file
+ */
+ public static File fetchURLToTemp(String url) throws OutOfMemoryError,
+ IOException
+ {
+ long time = System.currentTimeMillis();
+ URL rcall = new URL(url);
+
+ InputStream is = new BufferedInputStream(rcall.openStream());
+ File outFile = null;
+ try
+ {
+ outFile = File.createTempFile("jalview", ".xml");
+ outFile.deleteOnExit();
+ if (outFile.length() == 0)
+ {
+ outFile.delete();
+ return null;
+ }
+ } catch (Exception ex)
+ {
+ }
+
+ if (outFile != null)
+ {
+ FileOutputStream fio = new FileOutputStream(outFile);
+ byte[] bb = new byte[32 * 1024];
+ int l;
+ while ((l = is.read(bb)) > 0)
+ {
+ fio.write(bb, 0, l);
+ }
+ fio.close();
+ is.close();
+ return outFile;
+ }
+ else
+ {
+ return null;
+ }
+ }
}
--- /dev/null
+package jalview.ws.ebi;
+
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.FileParse;
+import jalview.viewmodel.AlignmentViewport;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+
+public class HmmerJSONProcessor
+{
+ /**
+ * result to be annotated. may not be null
+ */
+ AlignmentI resultAl;
+
+ /**
+ * viewport on the alignment. may be null at construction time
+ */
+ AlignmentViewport viewAl = null;
+
+ public HmmerJSONProcessor(AlignmentI searchResult)
+ {
+ resultAl = searchResult;
+ }
+
+ public void parseFrom(FileParse jsonsource) throws IOException,
+ OutOfMemoryError
+ {
+ JSONParser hmmerResultParser = new JSONParser();
+ Object jsonResults = null;
+ try
+ {
+ jsonResults = hmmerResultParser.parse(jsonsource.getReader());
+ } catch (Exception p)
+ {
+ throw new IOException("While parsing from " + jsonsource.getInFile(),
+ p);
+ }
+ if (jsonResults == null)
+ {
+ throw new IOException("No data at" + jsonsource.getInFile());
+ }
+ if (!(jsonResults instanceof JSONObject))
+ {
+ throw new IOException("Unexpected JSON model at "
+ + jsonsource.getInFile());
+ }
+ try
+ {
+ JSONObject hmmsearchr = (JSONObject) ((JSONObject) jsonResults)
+ .get("results");
+ // now process the hits
+ addStatistics((JSONObject) hmmsearchr.get("stats"));
+ JSONArray jsonArray = (JSONArray) hmmsearchr.get("hits");
+ long p = 1;
+ for (Object hit : jsonArray)
+ {
+ JSONObject hmmhit = (JSONObject) hit;
+ addHit(hmmhit, p++);
+ }
+ } catch (ClassCastException q)
+ {
+ throw new IOException("Unexpected JSON model content at "
+ + jsonsource.getInFile(), q);
+ }
+ }
+
+ /**
+ *
+ * @param object
+ * - actually a JSONObject key value set of search statistics.
+ */
+ public void addStatistics(JSONObject stats)
+ {
+ for (Object stat : stats.keySet())
+ {
+ String key = (String) stat;
+ Object val = stats.get(key);
+ resultAl.setProperty(key, "" + val);
+ }
+ }
+
+ // encodings for JSON keys
+ /**
+ * score becomes sequence associated AlignmentAnnotation
+ */
+ private String[] score = { "aliId", "ali_IdCount", "bitscore", "ievalue",
+ "aliSim", "aliSimCount", "aliL", "aliSim", "ievalue", "cevalue" };
+
+ /**
+ * attrib becomes numeric or binary attribute for sequence with respect to
+ * this hmmsearch run
+ */
+ private String[] attrib = { "bias", "oasc", "is_included", "is_reported" };
+
+ /**
+ * name of the hmmsearch query
+ */
+ private String[] label = { "alihmmname" // (query label?)},
+ };
+
+ /**
+ * integer attributes for each
+ */
+ private String[] ipos = { "alihmmfrom", "alihmmto" }, pos_l = {
+ "alimline", "alimodel", "alirfline" };
+
+ /**
+ * positional quantitative annotation encoded as strings.
+ */
+ private String[] pos_nscore = { "alippline" };
+
+ //
+ // mapping of keys to types of property on sequence
+ //
+ public void addHit(JSONObject hmmrhit, long p)
+ {
+ String sname = (String) hmmrhit.get("name");
+ SequenceI[] hits = resultAl.findSequenceMatch(sname);
+ if (hits == null)
+ {
+ System.err.println("No seq for " + sname);
+ }
+ double pvalue = (Double) hmmrhit.get("pvalue");
+
+ double evalue = Double.valueOf("" + hmmrhit.get("evalue"));
+ for (Object domainhit : ((JSONArray) hmmrhit.get("domains")))
+ {
+ JSONObject dhit = (JSONObject) domainhit;
+ // dhit.get(key)
+
+ // alihmmfrom,alihmmto alimodel
+ long alihmmfrom = (long) dhit.get("alihmmfrom"), alihmmto = (long) dhit
+ .get("alihmmto"), alisqfrom = (long) dhit.get("alisqfrom"), alisqto = (long) dhit
+ .get("alisqto");
+
+ // alisqfrom,alisqto,aliaseq
+
+ // alippline
+ String aliaseq = (String) dhit.get("aliaseq"), alimodel = (String) dhit
+ .get("alimodel"), ppline = (String) dhit.get("alippline");
+ //
+ int found = 0;
+ SequenceI firsthit = null;
+ for (SequenceI hitseq : hits)
+ {
+ // match alisqfrom,alisqto,seq
+ if (hitseq.getStart() == alisqfrom && hitseq.getEnd() == alisqto)
+ {
+ if (found == 0)
+ {
+ firsthit = hitseq;
+ }
+ found++; // annotated a sequence
+ AlignmentAnnotation alipp = parsePosteriorProb(ppline);
+ AlignmentAnnotation pval = new AlignmentAnnotation("p-value",
+ "hmmer3 pvalue", pvalue);
+ AlignmentAnnotation eval = new AlignmentAnnotation("e-value",
+ "hmmer3 evalue", evalue);
+ pval.setCalcId("HMMER3");
+ eval.setCalcId("HMMER3");
+ alipp.setCalcId("HMMER3");
+ hitseq.addAlignmentAnnotation(pval);
+ hitseq.addAlignmentAnnotation(eval);
+ alipp.createSequenceMapping(hitseq, hitseq.getStart(), false);
+ hitseq.addAlignmentAnnotation(alipp);
+ String arch;
+ hitseq.addSequenceFeature(new SequenceFeature(
+ "Pfam Domain Architecture", (hmmrhit.get("archindex"))
+ + " " + (arch = (String) hmmrhit.get("arch")), 0,
+ 0, Integer.valueOf((String) hmmrhit.get("archScore")),
+ "HMMER3"));
+ addArchGroup(hitseq, arch);
+ alipp.setScore(Double.valueOf("" + dhit.get("bitscore")));
+ alipp.adjustForAlignment();
+ resultAl.addAnnotation(pval);
+ resultAl.addAnnotation(eval);
+ resultAl.addAnnotation(alipp);
+ alipp.validateRangeAndDisplay();
+ }
+ }
+ // look for other sequences represented by this hit and create rep groups
+ // could be in "pdbs", or ..
+ addRedundantSeqGroup(firsthit, alisqfrom, alisqto,
+ (JSONArray) hmmrhit.get("seqs"), true);
+ }
+ }
+
+ /**
+ * series of operations to perform for the viewpanel associated with the
+ * alignment
+ */
+ private List<Runnable> viewOps = new ArrayList<Runnable>();
+
+ public void updateView(AlignmentViewport view)
+ {
+ viewAl = view;
+ for (Runnable op : viewOps)
+ {
+ op.run();
+ }
+ }
+
+ private void addRedundantSeqGroup(final SequenceI firsthit,
+ long alisqfrom, long alisqto, JSONArray others, boolean justDelete)
+ {
+ if (others != null)
+ {
+ final SequenceGroup repgroup = new SequenceGroup();
+ repgroup.setSeqrep(firsthit);
+ repgroup.addOrRemove(firsthit, false);
+ repgroup.setStartRes(0);
+ repgroup.setEndRes(resultAl.getWidth() - 1);
+ for (Object otherseq : others.toArray(new JSONObject[0]))
+ {
+ String repseq = (String) ((JSONObject) otherseq).get("dn");
+ SequenceI[] other = resultAl.findSequenceMatch(repseq);
+ if (other != null && other.length > 0)
+ {
+ if (justDelete)
+ {
+ for (SequenceI oth : other)
+ {
+ resultAl.deleteSequence(oth);
+ }
+ ;
+ }
+ else
+ {
+ int ofound = 0;
+ for (SequenceI oth : other)
+ {
+ if (oth.getStart() == alisqfrom && oth.getEnd() == alisqto)
+ {
+ ofound++;
+ repgroup.addSequence(oth, false);
+ }
+ }
+ if (ofound == 0)
+ {
+ System.err.println("Warn - no match for redundant hit "
+ + repseq + "/" + alisqfrom + "-" + alisqto);
+ }
+ if (ofound > 1)
+ {
+ System.err
+ .println("Warn - multiple matches for redundant hit "
+ + repseq + "/" + alisqfrom + "-" + alisqto);
+ }
+ }
+ }
+ }
+ if (repgroup.getSequences().size() > 1)
+ {
+ // queue a hide operation
+ final HmmerJSONProcessor me = this;
+ viewOps.add(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ me.viewAl.hideRepSequences(firsthit, repgroup);
+ }
+ });
+ }
+ }
+ }
+
+ Map<String, SequenceGroup> groups = new HashMap<String, SequenceGroup>();
+
+ private void addArchGroup(SequenceI seqToAdd, String groupNam)
+ {
+ SequenceGroup sg = groups.get(groupNam);
+ if (sg == null)
+ {
+ sg = new SequenceGroup();
+ sg.setName(groupNam);
+ sg.addSequence(seqToAdd, false);
+ sg.setStartRes(0);
+ sg.setEndRes(resultAl.getWidth() - 1);
+ groups.put(groupNam, sg);
+ resultAl.addGroup(sg);
+ }
+ else
+ {
+ sg.addSequence(seqToAdd, false);
+ }
+ }
+
+ private AlignmentAnnotation parsePosteriorProb(String ppline)
+ {
+ Annotation[] ae = new Annotation[ppline.length()];
+ int spos = 0;
+ for (int i = 0, iSize = ppline.length(); i < iSize; i++)
+ {
+ char pp = ppline.charAt(i);
+ if (pp == '*')
+ {
+ ae[spos++] = new Annotation(10f);
+ }
+ else
+ {
+ if (pp >= '0' && pp <= '9')
+ {
+ ae[spos++] = new Annotation(Integer.valueOf("" + pp));
+ }
+ }
+ }
+ AlignmentAnnotation pprob = new AlignmentAnnotation(
+ "Posterior Probability",
+ "Likelihood of HMM fit at each hit position.", ae);
+ pprob.graph = AlignmentAnnotation.BAR_GRAPH;
+ pprob.visible = false;
+ return pprob;
+ }
+}
--- /dev/null
+package jalview.ws.ebi;
+
+import jalview.datamodel.AlignmentI;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.FileParse;
+import jalview.io.FormatAdapter;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.regex.Matcher;
+
+import org.apache.axis.transport.http.HTTPConstants;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import compbio.util.FileUtil;
+
+public class hmmerClient
+{
+ /**
+ * URLs for ebi api
+ */
+ static String baseUrl = "http://www.ebi.ac.uk/Tools/hmmer",
+ jackH = "/search/jackhmmer", phmmer = "/search/phmmer",
+ hmmscan = "/search/hmmscan", hmmsearch = "/search/hmmsearch";
+
+ static String edseq = ">2abl_A mol:protein length:163 ABL TYROSINE KINASE\nMGPSENDPNLFVALYDFVASGDNTLSITKGEKLRVLGYNHNGEWCEAQTKNGQGWVPSNYITPVNSLEKHS\nWYHGPVSRNAAEYLLSSGINGSFLVRESESSPGQRSISLRYEGRVYHYRINTASDGKLYVSSESRFNTLAE\nLVHHHSTVADGLITTLHYPAP";
+
+ public static void main(String[] args)
+ {
+ String instr = edseq;
+ if (args.length > 0)
+ {
+ try
+ {
+ instr = FileUtil.readFileToString(new File(args[0]));
+ } catch (Exception f)
+ {
+ f.printStackTrace();
+ return;
+ }
+ }
+ String res = new hmmerClient().submitJackhmmerSearch(instr,
+ "jackhmmer", "pdb", 5);
+ if (res == null)
+ {
+ throw new Error("Failed.");
+ }
+ System.out.println("Result\n" + res);
+ return;
+ }
+
+ /**
+ *
+ * @param input
+ * - fasta or other formatted sequence or alignment
+ * @param algo
+ * - jackhmmer
+ * @param db
+ * - pdb, uniprot, etc.
+ * @param niter
+ * number of iterations
+ * @return job id
+ */
+ String submitJackhmmerSearch(String input, String algo, String db,
+ int niter)
+ {
+ JSONObject inparam = new JSONObject();
+ HttpPost jackhp = new HttpPost(baseUrl + jackH);
+ String lastiter = null;
+ try
+ {
+ inparam.put("algo", algo);
+ inparam.put("seq", input);
+ inparam.put("seqdb", db);
+ inparam.put("iterations", niter);
+ // #Now POST the request and generate the search job.
+ // dumb json post service
+ jackhp.setHeader("content-type", "application/json");
+ jackhp.setEntity(new StringEntity(inparam.toString()));
+ } catch (Exception f)
+ {
+ f.printStackTrace();
+ return null;
+ }
+ HttpResponse r = null;
+ try
+ {
+ DefaultHttpClient httpCl = new DefaultHttpClient();
+
+ r = httpCl.execute(jackhp);
+
+ } catch (Exception x)
+ {
+ System.err.println("Submit failed.");
+ x.printStackTrace();
+ }
+ if (r.getStatusLine().getStatusCode() != 201)
+ {
+ throw new Error(r.toString());
+ }
+ // get uid for job
+ String jobid = null, redir = null;
+ try
+ {
+ JSONObject res = new JSONObject(EntityUtils.toString(r.getEntity()));
+ jobid = res.getString("job_id");
+
+ Header[] loc;
+ if ((loc = r.getHeaders(HTTPConstants.HEADER_LOCATION)) != null
+ && loc.length > 0)
+ {
+ if (loc.length > 1)
+ {
+ System.err
+ .println("Ignoring additional "
+ + (loc.length - 1)
+ + " location(s) provided in response header ( next one is '"
+ + loc[1].getValue() + "' )");
+ }
+ redir = loc[0].getValue();
+ }
+ } catch (Exception x)
+ {
+ System.err.println("job id extraction failed.");
+ x.printStackTrace();
+ }
+ int tries = 0;
+ boolean finished = false;
+ JSONObject jobstate = null;
+ do
+ {
+ try
+ {
+ DefaultHttpClient httpCl = new DefaultHttpClient();
+
+ HttpGet jackcheck = new HttpGet(redir);
+ jackcheck.setHeader("content-type", "application/json");
+ r = httpCl.execute(jackcheck);
+ switch (r.getStatusLine().getStatusCode())
+ {
+ case 200:
+ jobstate = new JSONObject(EntityUtils.toString(r.getEntity()));
+ String st = jobstate.getString("status");
+ if ("DONE".equals(st))
+ {
+ finished = true;
+ }
+ if ("ERROR".equals(st))
+ {
+ System.err.println("Error");
+ finished = true;
+ }
+ if ("PEND".equals(st) || "RUN".equals("st"))
+ {
+ JSONArray iters = jobstate.getJSONArray("result");
+ lastiter = iters.getJSONObject(iters.length() - 1).getString(
+ "uuid");
+ if (lastiter.length() > 0)
+ {
+ java.util.regex.Pattern p = java.util.regex.Pattern
+ .compile(".+(\\d+)");
+ Matcher m = p.matcher(lastiter);
+ if (m.matches())
+ {
+ System.out.println("On iteration " + m.group(1));
+ }
+ }
+ }
+ break;
+
+ default:
+ tries++;
+ Thread.sleep(2000);
+ }
+ } catch (Exception q)
+ {
+ q.printStackTrace();
+ return null;
+ }
+ } while (!finished && tries < 50);
+
+ if (!finished)
+ {
+ System.err.println("Giving up with job " + jobid + " at " + redir);
+ return null;
+ }
+ // get results
+ // http://www.ebi.ac.uk/Tools/hmmer/download/60048B38-7CEC-11E5-A230-CED6D26C98AD.5/score?format=csv
+ // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 1 2 4.4e-46 2.1e-43
+ // 151.758316040039 0.04 11 151 3 139 1 150 0.94 GROWTH FACTOR BOUND PROTEIN
+ // 2 1cj1_J 1gri_B
+ // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 2 2 1.6e-17 7.9e-15
+ // 58.8796501159668 0.01 7 66 157 215 153 216 0.95 GROWTH FACTOR BOUND
+ // PROTEIN 2 1cj1_J 1gri_B
+ // 4h1o_A 4h1o_A 560 jackhmmer - 163 2.1e-57 197.3 0.0 1 2 7.5e-28 3.6e-25
+ // 92.4921493530273 0.00 65 161 20 122 17 124 0.95 Tyrosine-protein
+ // phosphatase non-receptor typ 4h1o_A
+ //
+ // 4h1o_A 4h1o_A 560 jackhmmer - 163 2.1e-57 197.3 0.0 2 2 7.6e-31 3.7e-28
+ // 102.219146728516 0.03 66 161 127 236 124 238 0.94 Tyrosine-protein
+ // phosphatase non-receptor typ 4h1o_A
+ //
+ // $ua->get( $rootUrl."/results/".$lastIteration->{uuid} . "/score"
+ return lastiter;
+ /*
+ * * #Job should have finished, but we may have converged, so get the last
+ * job. my $results = $json->decode( $response->content ); my $lastIteration
+ * = pop( @{ $results->{result} } ); #Now fetch the results of the last
+ * iteration my $searchResult = $ua->get( $rootUrl."/results/" .
+ * $lastIteration->{uuid} . "/score", 'Accept' => 'application/json' );
+ * unless( $searchResult->status_line eq "200 OK"){ die
+ * "Failed to get search results\n"; }
+ *
+ * #Decode the content of the full set of results $results = $json->decode(
+ * $searchResult->content ); print
+ * "Matched ".$results->{'results'}->{'stats'}->{'nincluded'}." sequences
+ * ($lastIteration->{uuid})!\n"; #Now do something more interesting with the
+ * results......
+ */
+ }
+
+ /**
+ * retrieve an alignment annotated with scores from JackHmmer
+ *
+ * @param jobid
+ * @param dataset
+ * @return
+ */
+ AlignmentI retrieveJackhmmerResult(String jobid, AlignmentI dataset)
+ throws OutOfMemoryError, IOException
+ {
+ AlignmentI searchResult = null;
+
+ // get results
+
+ searchResult = new AppletFormatAdapter().readFile(baseUrl
+ + "/download/" + jobid + "/score?format=afa&t=.gz",
+ FormatAdapter.URL, "FASTA");
+
+ // TODO extract gapped columns as '.' - inserts to query profile
+
+ // TODO match up jackhammer results to dataset.
+
+ // do scores
+ FileParse jsonsource = new FileParse(baseUrl + "/download/" + jobid
+ + "/score?format=json", FormatAdapter.URL);
+ if (!jsonsource.isValid())
+ {
+ throw new IOException("Couldn't access scores for Jackhammer results");
+ }
+ readJackhmmerScores(searchResult, jsonsource);
+ return searchResult;
+ }
+
+ /**
+ * // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 1 2 4.4e-46 2.1e-43
+ *
+ * // 151.758316040039 0.04 11 151 3 139 1 150 0.94 GROWTH FACTOR BOUND
+ * PROTEIN // 2 1cj1_J 1gri_B // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62
+ * 212.4 0.1 2 2 1.6e-17 7.9e-15 // 58.8796501159668 0.01 7 66 157 215 153 216
+ * 0.95 GROWTH FACTOR BOUND // PROTEIN 2 1cj1_J 1gri_B // 4h1o_A 4h1o_A 560
+ * jackhmmer - 163 2.1e-57 197.3 0.0 1 2 7.5e-28 3.6e-25 // 92.4921493530273
+ * 0.00 65 161 20 122 17 124 0.95 Tyrosine-protein // phosphatase non-receptor
+ * typ 4h1o_A
+ */
+ private static String[] _hmmsearchcols = new String[] { "acc", "name", "" };
+
+ private void readJackhmmerScores(AlignmentI searchResult,
+ FileParse jsonsource) throws IOException, OutOfMemoryError
+ {
+ HmmerJSONProcessor hjp = new HmmerJSONProcessor(searchResult);
+ hjp.parseFrom(jsonsource);
+
+ // http://www.ebi.ac.uk/Tools/hmmer/download/60048B38-7CEC-11E5-A230-CED6D26C98AD.5/score?format=csv
+ // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 1 2 4.4e-46 2.1e-43
+ // 151.758316040039 0.04 11 151 3 139 1 150 0.94 GROWTH FACTOR BOUND PROTEIN
+ // 2 1cj1_J 1gri_B
+ // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 2 2 1.6e-17 7.9e-15
+ // 58.8796501159668 0.01 7 66 157 215 153 216 0.95 GROWTH FACTOR BOUND
+ // PROTEIN 2 1cj1_J 1gri_B
+ // 4h1o_A 4h1o_A 560 jackhmmer - 163 2.1e-57 197.3 0.0 1 2 7.5e-28 3.6e-25
+ // 92.4921493530273 0.00 65 161 20 122 17 124 0.95 Tyrosine-protein
+ // phosphatase non-receptor typ 4h1o_A
+ // each line scores a fragment
+ // so for a combined score ?
+
+ /**
+ * for a sequence q sort any t against q according to overallScore(q,t)
+ * maxFragment(q,t) in sequence features parlance: for alignment
+ * s.getFeature("overallScore",q) -> range on q and range on s
+ *
+ *
+ */
+
+ // 151.758316040039 0.04 11 151 3 139 1 150 0.94 GROWTH FACTOR BOUND PROTEIN
+ // 2 1cj1_J 1gri_B
+ // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 2 2 1.6e-17 7.9e-15
+ // 58.8796501159668 0.01 7 66 157 215 153 216 0.95 GROWTH FACTOR BOUND
+ // PROTEIN 2 1cj1_J 1gri_B
+ // 4h1o_A 4h1o_A 560 jackhmmer - 163 2.1e-57 197.3 0.0 1 2 7.5e-28 3.6e-25
+ // 92.4921493530273 0.00 65 161 20 122 17 124 0.95 Tyrosine-protein
+ // phosphatase non-receptor typ 4h1o_A
+ //
+ // 4h1o_A 4h1o_A 560 jackhmmer - 163 2.1e-57 197.3 0.0 2 2 7.6e-31 3.7e-28
+ // 102.219146728516 0.03 66 161 127 236 124 238 0.94 Tyrosine-protein
+ // phosphatase non-receptor typ 4h1o_A
+
+ }
+
+}
import jalview.gui.AlignmentPanel;
import jalview.gui.Desktop;
import jalview.gui.WebserviceInfo;
-import jalview.io.packed.DataProvider.JvDataType;
import jalview.util.MessageManager;
import jalview.ws.WSClient;
import jalview.ws.WSClientI;
import jalview.ws.WSMenuEntryProviderI;
+import jalview.ws.rest.clientdefs.ShmrRestClient;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.Hashtable;
import java.util.Vector;
import javax.swing.JMenu;
}
}
- public static RestClient makeShmmrRestClient()
- {
- String action = "Analysis", description = "Sequence Harmony and Multi-Relief (Brandt et al. 2010)", name = MessageManager
- .getString("label.multiharmony");
- Hashtable<String, InputType> iparams = new Hashtable<String, InputType>();
- jalview.ws.rest.params.JobConstant toolp;
- // toolp = new jalview.ws.rest.JobConstant("tool","jalview");
- // iparams.put(toolp.token, toolp);
- // toolp = new jalview.ws.rest.params.JobConstant("mbjob[method]","shmr");
- // iparams.put(toolp.token, toolp);
- // toolp = new
- // jalview.ws.rest.params.JobConstant("mbjob[description]","step 1");
- // iparams.put(toolp.token, toolp);
- // toolp = new jalview.ws.rest.params.JobConstant("start_search","1");
- // iparams.put(toolp.token, toolp);
- // toolp = new jalview.ws.rest.params.JobConstant("blast","0");
- // iparams.put(toolp.token, toolp);
-
- jalview.ws.rest.params.Alignment aliinput = new jalview.ws.rest.params.Alignment();
- // SHMR server has a 65K limit for content pasted into the 'ali' parameter,
- // so we always upload our files.
- aliinput.token = "ali_file";
- aliinput.writeAsFile = true;
- iparams.put(aliinput.token, aliinput);
- jalview.ws.rest.params.SeqGroupIndexVector sgroups = new jalview.ws.rest.params.SeqGroupIndexVector();
- sgroups.setMinsize(2);
- sgroups.min = 2;// need at least two group defined to make a partition
- iparams.put("groups", sgroups);
- sgroups.token = "groups";
- sgroups.sep = " ";
- RestServiceDescription shmrService = new RestServiceDescription(
- action,
- description,
- name,
- "http://zeus.few.vu.nl/programs/shmrwww/index.php?tool=jalview",// ?tool=jalview&mbjob[method]=shmr&mbjob[description]=step1",
- "?tool=jalview", iparams, true, false, '-');
- // a priori knowledge of the data returned from the service
- shmrService.addResultDatatype(JvDataType.ANNOTATION);
- return new RestClient(shmrService);
- }
-
public AlignmentPanel recoverAlignPanelForView()
{
AlignmentPanel[] aps = Desktop
for (RestServiceDescription descr : RestServiceDescription
.parseDescriptions(jalview.bin.Cache.getDefault(
RSBS_SERVICES,
- makeShmmrRestClient().service.toString())))
+ ShmrRestClient.makeShmmrRestClient().service.toString())))
{
services.add(descr.toString());
}
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
public class RestJobThread extends AWSThread
private String getStage(Stage stg)
{
if (stg == Stage.SUBMIT)
+ {
return "submitting ";
+ }
if (stg == Stage.POLL)
+ {
return "checking status of ";
+ }
return (" being confused about ");
}
protected void doHttpReq(Stage stg, RestJob rj, String postUrl)
throws Exception
{
- StringBuffer respText = new StringBuffer();
- // con.setContentHandlerFactory(new
- // jalview.ws.io.mime.HttpContentHandler());
HttpRequestBase request = null;
String messages = "";
if (stg == Stage.SUBMIT)
{
DefaultHttpClient httpclient = new DefaultHttpClient();
- HttpContext localContext = new BasicHttpContext();
HttpResponse response = null;
try
{
Cache.log.debug("Processing result set.");
processResultSet(rj, response, request);
break;
+
case 202:
- rj.statMessage = "<br>Job submitted successfully. Results available at this URL:\n"
- + "<a href="
- + rj.getJobId()
- + "\">"
- + rj.getJobId()
- + "</a><br>";
- rj.running = true;
+ markJobAsRunning(rj);
break;
+
+ case 201:
+ // Created - redirect may be present. Fallthrough to 302
case 302:
- Header[] loc;
- if (!rj.isSubmitted()
- && (loc = response
- .getHeaders(HTTPConstants.HEADER_LOCATION)) != null
- && loc.length > 0)
- {
- if (loc.length > 1)
- {
- Cache.log
- .warn("Ignoring additional "
- + (loc.length - 1)
- + " location(s) provided in response header ( next one is '"
- + loc[1].getValue() + "' )");
- }
- rj.setJobId(loc[0].getValue());
- rj.setSubmitted(true);
- }
+ extractJobId(rj, response);
completeStatus(rj, response);
break;
case 500:
- // Failed.
- rj.setSubmitted(true);
- rj.setAllowedServerExceptions(0);
- rj.setSubjobComplete(true);
- rj.error = true;
- rj.running = false;
+ markAsFailed(rj, response);
completeStatus(rj, response, "" + getStage(stg)
+ "failed. Reason below:\n");
+
break;
default:
// Some other response. Probably need to pop up the content in a window.
}
}
+ private void markAsFailed(RestJob rj, HttpResponse response)
+ {
+ // Failed.
+ rj.setSubmitted(true);
+ rj.setAllowedServerExceptions(0);
+ rj.setSubjobComplete(true);
+ rj.error = true;
+ rj.running = false;
+ }
+
+ /**
+ * set the jobRunning flag and post a link to the physical result page encoded
+ * in rj.getJobId()
+ *
+ * @param rj
+ */
+ private void markJobAsRunning(RestJob rj)
+ {
+ rj.statMessage = "<br>Job submitted successfully. Results available at this URL:\n"
+ + "<a href="
+ + rj.getJobId()
+ + "\">"
+ + rj.getJobId()
+ + "</a><br>";
+ rj.running = true;
+ }
+
+ /**
+ * extract the job ID URL from the redirect page. Does nothing if job is
+ * already running.
+ *
+ * @param rj
+ * @param response
+ */
+ private void extractJobId(RestJob rj, HttpResponse response)
+ {
+ Header[] loc;
+ if (!rj.isSubmitted())
+ {
+
+ // redirect URL - typical for IBIVU type jobs.
+ if ((loc = response.getHeaders(HTTPConstants.HEADER_LOCATION)) != null
+ && loc.length > 0)
+ {
+ if (loc.length > 1)
+ {
+ Cache.log
+ .warn("Ignoring additional "
+ + (loc.length - 1)
+ + " location(s) provided in response header ( next one is '"
+ + loc[1].getValue() + "' )");
+ }
+ rj.setJobId(loc[0].getValue());
+ rj.setSubmitted(true);
+ }
+ }
+ }
+
/**
* job has completed. Something valid should be available from con
*
--- /dev/null
+package jalview.ws.rest.clientdefs;
+
+import jalview.io.packed.DataProvider.JvDataType;
+import jalview.util.MessageManager;
+import jalview.ws.rest.InputType;
+import jalview.ws.rest.RestClient;
+import jalview.ws.rest.RestServiceDescription;
+import jalview.ws.rest.params.Alignment;
+import jalview.ws.rest.params.JobConstant;
+import jalview.ws.rest.params.SeqGroupIndexVector;
+
+import java.util.Hashtable;
+
+public class ShmrRestClient
+{
+
+ public static RestClient makeShmmrRestClient()
+ {
+ String action = "Analysis", description = "Sequence Harmony and Multi-Relief (Brandt et al. 2010)", name = MessageManager
+ .getString("label.multiharmony");
+ Hashtable<String, InputType> iparams = new Hashtable<String, InputType>();
+ jalview.ws.rest.params.JobConstant toolp;
+ // toolp = new jalview.ws.rest.JobConstant("tool","jalview");
+ // iparams.put(toolp.token, toolp);
+ // toolp = new jalview.ws.rest.params.JobConstant("mbjob[method]","shmr");
+ // iparams.put(toolp.token, toolp);
+ // toolp = new
+ // jalview.ws.rest.params.JobConstant("mbjob[description]","step 1");
+ // iparams.put(toolp.token, toolp);
+ // toolp = new jalview.ws.rest.params.JobConstant("start_search","1");
+ // iparams.put(toolp.token, toolp);
+ // toolp = new jalview.ws.rest.params.JobConstant("blast","0");
+ // iparams.put(toolp.token, toolp);
+
+ jalview.ws.rest.params.Alignment aliinput = new jalview.ws.rest.params.Alignment();
+ // SHMR server has a 65K limit for content pasted into the 'ali' parameter,
+ // so we always upload our files.
+ aliinput.token = "ali_file";
+ aliinput.writeAsFile = true;
+ iparams.put(aliinput.token, aliinput);
+ jalview.ws.rest.params.SeqGroupIndexVector sgroups = new jalview.ws.rest.params.SeqGroupIndexVector();
+ sgroups.setMinsize(2);
+ sgroups.min = 2;// need at least two group defined to make a partition
+ iparams.put("groups", sgroups);
+ sgroups.token = "groups";
+ sgroups.sep = " ";
+ RestServiceDescription shmrService = new RestServiceDescription(
+ action,
+ description,
+ name,
+ "http://zeus.few.vu.nl/programs/shmrwww/index.php?tool=jalview",// ?tool=jalview&mbjob[method]=shmr&mbjob[description]=step1",
+ "?tool=jalview", iparams, true, false, '-');
+ // a priori knowledge of the data returned from the service
+ shmrService.addResultDatatype(JvDataType.ANNOTATION);
+ return new RestClient(shmrService);
+ }
+
+}
--- /dev/null
+package jalview.ws.ebi;
+
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.io.FileParse;
+import jalview.io.FormatAdapter;
+
+import java.io.File;
+
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class HmmerJSONProcessTest {
+ public static File alignmentFragFile = new File(
+ "examples/testdata/hmmer3/alignment_frag.fa.gz");
+
+ private AlignmentI getSearchResultFragmentAlignment() throws Exception
+ {
+ AlignmentI alf = new FormatAdapter().readFile(
+ alignmentFragFile.getAbsolutePath(), FormatAdapter.FILE,
+ "FASTA");
+
+ return alf;
+ }
+
+ public static File alignmentResultFile = new File(
+ "examples/testdata/hmmer3/alignment_res.fa.gz");
+
+ private AlignmentI getSearchResultAlignment() throws Exception
+ {
+ AlignmentI alf = new FormatAdapter().readFile(
+ alignmentResultFile.getAbsolutePath(), FormatAdapter.FILE,
+ "FASTA");
+
+ return alf;
+ }
+
+ public static String hitTestFile = "examples/testdata/hmmer3/hit_fragment.json.gz",
+ hmmerResultFile = "examples/testdata/hmmer3/hmmeresult.json.gz";
+
+
+ @Test(groups = { "Functional" })
+ public void parseHitTest() throws Exception
+ {
+
+ Assert.assertTrue(new File(hitTestFile).exists(),
+ "Can't find test data.\n"
+ + hitTestFile);
+ JSONParser jp = new JSONParser();
+ // read JSON in same way - via fileparse
+ Object hitfragment = jp.parse(new FileParse(hitTestFile,
+ FormatAdapter.FILE).getReader());
+ Assert.assertTrue((hitfragment instanceof JSONObject),
+ "Didn't find a JSON object map in " + hitTestFile);
+ AlignmentI searchResult = getSearchResultFragmentAlignment();
+
+ Assert.assertTrue(searchResult != null && searchResult.getHeight() > 0,
+ "Didn't read search result alignment from " + alignmentFragFile);
+
+ HmmerJSONProcessor hjsp = new HmmerJSONProcessor(searchResult);
+ hjsp.addHit((JSONObject) hitfragment, 1);
+ // check that
+ // scores, posterior probabilities and stuff exist.
+ }
+
+ @Test(groups = { "Functional" })
+ public void parseJsonResultTest() throws Exception
+ {
+
+ Assert.assertTrue(new File(hmmerResultFile).exists(),
+ "Can't find test data.\n" + hmmerResultFile);
+
+ AlignmentI searchResult = getSearchResultAlignment();
+
+ Assert.assertTrue(searchResult != null && searchResult.getHeight() > 0,
+ "Didn't read search result alignment from " + alignmentFragFile);
+
+ HmmerJSONProcessor hjsp = new HmmerJSONProcessor(searchResult);
+ hjsp.parseFrom(new FileParse(hmmerResultFile, FormatAdapter.FILE));
+ AlignmentAnnotation[] aa = searchResult.getSequenceAt(5)
+ .getAnnotation();
+ Assert.assertNotNull(aa);
+ Assert.assertEquals(aa.length, 3,
+ "didn't get expected set of annotation.\n");
+ // DPTSERWFHGHLSGKEAEKLLTeKGKHGSFLVRESQSHPGDFVLSVRTgddkgesndgKSKVTHVMIR-CQELKYDVGGGERFDSLTDLVEHYKKNPmvet
+ // LGTVLQLKQP
+ // 5789*****************9799***********************999998888888********.99**************************9999
+ // 899999*999
+ // AlignmentAnnotation
+ // 101 == 8
+ String seq = "tLGT";
+ SequenceI s5 = searchResult.getSequenceAt(5);
+ Assert.assertEquals(
+ s5.getSubSequence(s5.findIndex(225), s5.findIndex(229))
+ .getSequenceAsString(),
+ seq);
+ int pos = s5.findIndex(226);
+ for (AlignmentAnnotation an : aa)
+ {
+ if (an.label.startsWith("Posterior"))
+ {
+ Assert.assertEquals(an.annotations[pos].value, 8f);
+
+ }
+ }
+ ;
+ // check that
+ // scores, posterior probabilities and stuff exist.
+ }
+ // Groovy test
+ // def al = Jalview.getAlignFrames()[0].getViewport().getAlignment()
+ // def jproc = new jalview.ws.ebi.HmmerJSONProcessor(al)
+ // jproc.parseFrom(new
+ // jalview.io.FileParse("examples/testdata/hmmer3/hmmeresult.json.gz","File"))
+ // jproc.updateView(Jalview.getAlignFrames()[0].getViewport())
+
+}
import static org.testng.AssertJUnit.assertTrue;
import jalview.gui.AlignFrame;
+import jalview.ws.rest.clientdefs.ShmrRestClient;
import java.util.Map;
assertTrue(
"Test Rsd Exchange using using default Shmmr service failed.",
testRsdExchange("Test using default Shmmr service",
- RestClient.makeShmmrRestClient().service));
+ ShmrRestClient.makeShmmrRestClient().service));
}
@Test(groups = { "Functional" })
public void testShmmrServiceDataprep() throws Exception
{
- RestClient _rc = RestClient.makeShmmrRestClient();
+ RestClient _rc = ShmrRestClient.makeShmmrRestClient();
assertNotNull(_rc);
AlignFrame alf = new jalview.io.FileLoader(false)
.LoadFileWaitTillLoaded("examples/testdata/smad.fa",