1 package jalview.ws.ebi;
3 import jalview.datamodel.AlignmentAnnotation;
4 import jalview.datamodel.AlignmentI;
5 import jalview.datamodel.Annotation;
6 import jalview.datamodel.SequenceFeature;
7 import jalview.datamodel.SequenceGroup;
8 import jalview.datamodel.SequenceI;
9 import jalview.io.FileParse;
10 import jalview.viewmodel.AlignmentViewport;
12 import java.io.IOException;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.List;
18 import org.json.simple.JSONArray;
19 import org.json.simple.JSONObject;
20 import org.json.simple.parser.JSONParser;
22 public class HmmerJSONProcessor
25 * result to be annotated. may not be null
30 * viewport on the alignment. may be null at construction time
32 AlignmentViewport viewAl = null;
34 public HmmerJSONProcessor(AlignmentI searchResult)
36 resultAl = searchResult;
39 public void parseFrom(FileParse jsonsource) throws IOException,
42 JSONParser hmmerResultParser = new JSONParser();
43 Object jsonResults = null;
46 jsonResults = hmmerResultParser.parse(jsonsource.getReader());
49 throw new IOException("While parsing from " + jsonsource.getInFile(),
52 if (jsonResults == null)
54 throw new IOException("No data at" + jsonsource.getInFile());
56 if (!(jsonResults instanceof JSONObject))
58 throw new IOException("Unexpected JSON model at "
59 + jsonsource.getInFile());
63 JSONObject hmmsearchr = (JSONObject) ((JSONObject) jsonResults)
65 // now process the hits
66 addStatistics((JSONObject) hmmsearchr.get("stats"));
67 JSONArray jsonArray = (JSONArray) hmmsearchr.get("hits");
69 for (Object hit : jsonArray)
71 JSONObject hmmhit = (JSONObject) hit;
74 } catch (ClassCastException q)
76 throw new IOException("Unexpected JSON model content at "
77 + jsonsource.getInFile(), q);
84 * - actually a JSONObject key value set of search statistics.
86 public void addStatistics(JSONObject stats)
88 for (Object stat : stats.keySet())
90 String key = (String) stat;
91 Object val = stats.get(key);
92 resultAl.setProperty(key, "" + val);
96 // encodings for JSON keys
98 * score becomes sequence associated AlignmentAnnotation
100 private String[] score = { "aliId", "ali_IdCount", "bitscore", "ievalue",
101 "aliSim", "aliSimCount", "aliL", "aliSim", "ievalue", "cevalue" };
104 * attrib becomes numeric or binary attribute for sequence with respect to
107 private String[] attrib = { "bias", "oasc", "is_included", "is_reported" };
110 * name of the hmmsearch query
112 private String[] label = { "alihmmname" // (query label?)},
116 * integer attributes for each
118 private String[] ipos = { "alihmmfrom", "alihmmto" }, pos_l = {
119 "alimline", "alimodel", "alirfline" };
122 * positional quantitative annotation encoded as strings.
124 private String[] pos_nscore = { "alippline" };
127 // mapping of keys to types of property on sequence
129 public void addHit(JSONObject hmmrhit, long p)
131 String sname = (String) hmmrhit.get("name");
132 SequenceI[] hits = resultAl.findSequenceMatch(sname);
135 System.err.println("No seq for " + sname);
137 double pvalue = (Double) hmmrhit.get("pvalue");
139 double evalue = Double.valueOf("" + hmmrhit.get("evalue"));
140 for (Object domainhit : ((JSONArray) hmmrhit.get("domains")))
142 JSONObject dhit = (JSONObject) domainhit;
145 // alihmmfrom,alihmmto alimodel
146 long alihmmfrom = (long) dhit.get("alihmmfrom"), alihmmto = (long) dhit
147 .get("alihmmto"), alisqfrom = (long) dhit.get("alisqfrom"), alisqto = (long) dhit
150 // alisqfrom,alisqto,aliaseq
153 String aliaseq = (String) dhit.get("aliaseq"), alimodel = (String) dhit
154 .get("alimodel"), ppline = (String) dhit.get("alippline");
157 SequenceI firsthit = null;
158 for (SequenceI hitseq : hits)
160 // match alisqfrom,alisqto,seq
161 if (hitseq.getStart() == alisqfrom && hitseq.getEnd() == alisqto)
167 found++; // annotated a sequence
168 AlignmentAnnotation alipp = parsePosteriorProb(ppline);
169 AlignmentAnnotation pval = new AlignmentAnnotation("p-value",
170 "hmmer3 pvalue", pvalue);
171 AlignmentAnnotation eval = new AlignmentAnnotation("e-value",
172 "hmmer3 evalue", evalue);
173 pval.setCalcId("HMMER3");
174 eval.setCalcId("HMMER3");
175 alipp.setCalcId("HMMER3");
176 hitseq.addAlignmentAnnotation(pval);
177 hitseq.addAlignmentAnnotation(eval);
178 alipp.createSequenceMapping(hitseq, hitseq.getStart(), false);
179 hitseq.addAlignmentAnnotation(alipp);
181 hitseq.addSequenceFeature(new SequenceFeature(
182 "Pfam Domain Architecture", (hmmrhit.get("archindex"))
183 + " " + (arch = (String) hmmrhit.get("arch")), 0,
185 (hmmrhit.get("archScore") != null ? Integer
186 .valueOf((String) hmmrhit.get("archScore")) : 0f),
188 addArchGroup(hitseq, arch);
189 alipp.setScore(Double.valueOf("" + dhit.get("bitscore")));
190 alipp.adjustForAlignment();
191 resultAl.addAnnotation(pval);
192 resultAl.addAnnotation(eval);
193 resultAl.addAnnotation(alipp);
194 alipp.validateRangeAndDisplay();
197 // look for other sequences represented by this hit and create rep groups
198 // could be in "pdbs", or ..
199 addRedundantSeqGroup(firsthit, alisqfrom, alisqto,
200 (JSONArray) hmmrhit.get("seqs"), true);
205 * series of operations to perform for the viewpanel associated with the
208 private List<Runnable> viewOps = new ArrayList<Runnable>();
210 public void updateView(AlignmentViewport view)
213 for (Runnable op : viewOps)
219 private void addRedundantSeqGroup(final SequenceI firsthit,
220 long alisqfrom, long alisqto, JSONArray others, boolean justDelete)
224 final SequenceGroup repgroup = new SequenceGroup();
225 repgroup.setSeqrep(firsthit);
226 repgroup.addOrRemove(firsthit, false);
227 repgroup.setStartRes(0);
228 repgroup.setEndRes(resultAl.getWidth() - 1);
229 for (Object otherseq : others.toArray(new JSONObject[0]))
231 String repseq = (String) ((JSONObject) otherseq).get("dn");
232 SequenceI[] other = resultAl.findSequenceMatch(repseq);
233 if (other != null && other.length > 0)
237 for (SequenceI oth : other)
239 resultAl.deleteSequence(oth);
246 for (SequenceI oth : other)
248 if (oth.getStart() == alisqfrom && oth.getEnd() == alisqto)
251 repgroup.addSequence(oth, false);
256 System.err.println("Warn - no match for redundant hit "
257 + repseq + "/" + alisqfrom + "-" + alisqto);
262 .println("Warn - multiple matches for redundant hit "
263 + repseq + "/" + alisqfrom + "-" + alisqto);
268 if (repgroup.getSequences().size() > 1)
270 // queue a hide operation
271 final HmmerJSONProcessor me = this;
272 viewOps.add(new Runnable()
277 me.viewAl.hideRepSequences(firsthit, repgroup);
284 Map<String, SequenceGroup> groups = new HashMap<String, SequenceGroup>();
286 private void addArchGroup(SequenceI seqToAdd, String groupNam)
288 SequenceGroup sg = groups.get(groupNam);
291 sg = new SequenceGroup();
292 sg.setName(groupNam);
293 sg.addSequence(seqToAdd, false);
295 sg.setEndRes(resultAl.getWidth() - 1);
296 groups.put(groupNam, sg);
297 resultAl.addGroup(sg);
301 sg.addSequence(seqToAdd, false);
305 private AlignmentAnnotation parsePosteriorProb(String ppline)
307 Annotation[] ae = new Annotation[ppline.length()];
309 for (int i = 0, iSize = ppline.length(); i < iSize; i++)
311 char pp = ppline.charAt(i);
314 ae[spos++] = new Annotation(10f);
318 if (pp >= '0' && pp <= '9')
320 ae[spos++] = new Annotation(Integer.valueOf("" + pp));
324 AlignmentAnnotation pprob = new AlignmentAnnotation(
325 "Posterior Probability",
326 "Likelihood of HMM fit at each hit position.", ae);
327 pprob.graph = AlignmentAnnotation.BAR_GRAPH;
328 pprob.visible = false;