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,
184 0, Integer.valueOf((String) hmmrhit.get("archScore")),
186 addArchGroup(hitseq, arch);
187 alipp.setScore(Double.valueOf("" + dhit.get("bitscore")));
188 alipp.adjustForAlignment();
189 resultAl.addAnnotation(pval);
190 resultAl.addAnnotation(eval);
191 resultAl.addAnnotation(alipp);
192 alipp.validateRangeAndDisplay();
195 // look for other sequences represented by this hit and create rep groups
196 // could be in "pdbs", or ..
197 addRedundantSeqGroup(firsthit, alisqfrom, alisqto,
198 (JSONArray) hmmrhit.get("seqs"), true);
203 * series of operations to perform for the viewpanel associated with the
206 private List<Runnable> viewOps = new ArrayList<Runnable>();
208 public void updateView(AlignmentViewport view)
211 for (Runnable op : viewOps)
217 private void addRedundantSeqGroup(final SequenceI firsthit,
218 long alisqfrom, long alisqto, JSONArray others, boolean justDelete)
222 final SequenceGroup repgroup = new SequenceGroup();
223 repgroup.setSeqrep(firsthit);
224 repgroup.addOrRemove(firsthit, false);
225 repgroup.setStartRes(0);
226 repgroup.setEndRes(resultAl.getWidth() - 1);
227 for (Object otherseq : others.toArray(new JSONObject[0]))
229 String repseq = (String) ((JSONObject) otherseq).get("dn");
230 SequenceI[] other = resultAl.findSequenceMatch(repseq);
231 if (other != null && other.length > 0)
235 for (SequenceI oth : other)
237 resultAl.deleteSequence(oth);
244 for (SequenceI oth : other)
246 if (oth.getStart() == alisqfrom && oth.getEnd() == alisqto)
249 repgroup.addSequence(oth, false);
254 System.err.println("Warn - no match for redundant hit "
255 + repseq + "/" + alisqfrom + "-" + alisqto);
260 .println("Warn - multiple matches for redundant hit "
261 + repseq + "/" + alisqfrom + "-" + alisqto);
266 if (repgroup.getSequences().size() > 1)
268 // queue a hide operation
269 final HmmerJSONProcessor me = this;
270 viewOps.add(new Runnable()
275 me.viewAl.hideRepSequences(firsthit, repgroup);
282 Map<String, SequenceGroup> groups = new HashMap<String, SequenceGroup>();
284 private void addArchGroup(SequenceI seqToAdd, String groupNam)
286 SequenceGroup sg = groups.get(groupNam);
289 sg = new SequenceGroup();
290 sg.setName(groupNam);
291 sg.addSequence(seqToAdd, false);
293 sg.setEndRes(resultAl.getWidth() - 1);
294 groups.put(groupNam, sg);
295 resultAl.addGroup(sg);
299 sg.addSequence(seqToAdd, false);
303 private AlignmentAnnotation parsePosteriorProb(String ppline)
305 Annotation[] ae = new Annotation[ppline.length()];
307 for (int i = 0, iSize = ppline.length(); i < iSize; i++)
309 char pp = ppline.charAt(i);
312 ae[spos++] = new Annotation(10f);
316 if (pp >= '0' && pp <= '9')
318 ae[spos++] = new Annotation(Integer.valueOf("" + pp));
322 AlignmentAnnotation pprob = new AlignmentAnnotation(
323 "Posterior Probability",
324 "Likelihood of HMM fit at each hit position.", ae);
325 pprob.graph = AlignmentAnnotation.BAR_GRAPH;
326 pprob.visible = false;