From: Daniel Barton Date: Wed, 28 Aug 2013 21:23:50 +0000 (+0100) Subject: RNAalifoldClient updated to be more like AAConClient and now (attempts) to support... X-Git-Tag: Jalview_2_9~200^2~21^2~18 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=f8164ef6f241c5eb111c413fb8594e67b49ce671;p=jalview.git RNAalifoldClient updated to be more like AAConClient and now (attempts) to support all the output from RNAalifold --- diff --git a/.classpath b/.classpath index 8f6f94c..20610cc 100644 --- a/.classpath +++ b/.classpath @@ -45,8 +45,8 @@ + - diff --git a/lib/min-jabaws-client-3.0.0.jar b/lib/min-jabaws-client-3.0.0.jar index c70a615..24d2165 100644 Binary files a/lib/min-jabaws-client-3.0.0.jar and b/lib/min-jabaws-client-3.0.0.jar differ diff --git a/src/jalview/ws/jws2/JabaWsServerQuery.java b/src/jalview/ws/jws2/JabaWsServerQuery.java index 73d5654..8bf8a94 100644 --- a/src/jalview/ws/jws2/JabaWsServerQuery.java +++ b/src/jalview/ws/jws2/JabaWsServerQuery.java @@ -75,7 +75,7 @@ public class JabaWsServerQuery implements Runnable { Services.ClustalWS, Services.MuscleWS, Services.MafftWS, Services.ProbconsWS, Services.TcoffeeWS, Services.AAConWS, Services.DisemblWS, Services.GlobPlotWS, Services.IUPredWS, - Services.JronnWS }; + Services.JronnWS, Services.RNAalifoldWS }; /* * (non-Javadoc) @@ -115,7 +115,14 @@ public class JabaWsServerQuery implements Runnable jabasws2 = true; srv_set = registry.getSupportedServices(); + + // dan test + System.out.println("registry.getSupportedServices: " + srv_set.toString()); + svccategories = registry.getServiceCategories(); + + // dan test +// System.out.println("registry.getServiceCategories: " + svccategories.toString()); } } catch (Exception ex) diff --git a/src/jalview/ws/jws2/Jws2Discoverer.java b/src/jalview/ws/jws2/Jws2Discoverer.java index 8ad14e0..cb700bc 100644 --- a/src/jalview/ws/jws2/Jws2Discoverer.java +++ b/src/jalview/ws/jws2/Jws2Discoverer.java @@ -126,6 +126,8 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI Cache.log.debug("Old discovery thread has finished."); } running = true; + + changeSupport.firePropertyChange("services", services, new Vector()); oldthread = Thread.currentThread(); try diff --git a/src/jalview/ws/jws2/RNAalifoldClient.java b/src/jalview/ws/jws2/RNAalifoldClient.java index 7d06701..090b2a4 100644 --- a/src/jalview/ws/jws2/RNAalifoldClient.java +++ b/src/jalview/ws/jws2/RNAalifoldClient.java @@ -4,22 +4,22 @@ import jalview.api.AlignCalcWorkerI; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.Annotation; import jalview.gui.AlignFrame; -import jalview.schemes.NucleotideColourScheme; import jalview.ws.jws2.jabaws2.Jws2Instance; import jalview.ws.params.WsParamSetI; +import java.text.MessageFormat; import java.util.ArrayList; -import java.util.Iterator; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; -import compbio.data.msa.jaxws.Align; +import compbio.data.sequence.RNAStructReader.AlifoldResult; +import compbio.data.sequence.RNAStructScoreManager; import compbio.data.sequence.Range; import compbio.data.sequence.Score; -import compbio.data.sequence.RNAStructScoreManager; -import compbio.data.sequence.ScoreManager; import compbio.metadata.Argument; public class RNAalifoldClient extends JabawsAlignCalcWorker implements @@ -32,6 +32,9 @@ public class RNAalifoldClient extends JabawsAlignCalcWorker implements AlignFrame af; + // keeps track of whether the RNAalifold result includes base contact probabilities + boolean bpScores; + public RNAalifoldClient(Jws2Instance sh, AlignFrame alignFrame, WsParamSetI preset, List paramset) { @@ -52,108 +55,55 @@ public class RNAalifoldClient extends JabawsAlignCalcWorker implements arguments.add(sh.getRunnerConfig().getArgumentByOptionName("-p")); } - @Override - public String getServiceActionText() - { - return "Submitting RNA alignment for Secondary Structure prediction using " - + "RNAalifold Service"; - } - + @Override + public String getServiceActionText() + { + return "Submitting RNA alignment for Secondary Structure prediction using " + + "RNAalifold Service"; + } + + @Override public void updateResultAnnotation(boolean immediate) { - if (immediate || !calcMan.isWorking(this) && scoremanager != null) { List ourAnnot = new ArrayList(); - // ourAnnots = new ArrayList(); - // So I don't have to do any more casting + // Unpack the ScoreManager List structs = ((RNAStructScoreManager) scoremanager).getStructs(); List> data = ((RNAStructScoreManager) scoremanager).getData(); - - // I think this will never find an annotation at the moment. It will always create... - AlignmentAnnotation annotation = alignViewport.getAlignment() - .findOrCreateAnnotation("Consensus Structure", getCalcId(), false, null , null); - - // construct Annotation from scoremanager - - // Deal with the consensus structure and (?)BasePair Probabilities - Annotation[] anns = new Annotation[structs.get(1).length()]; - - // check if the first Score object is populated with base pair probabilities + // test to see if this data object contains base pair contacts Score fscore = data.get(0).first(); - boolean BPScores = (fscore.getScores().size() > 0 - && fscore.getRanges() != null); - - TreeMap basePairs = null; - if (BPScores) { - // The base pair probabilities are stored in a set in scoremanager... we want a map - basePairs = new TreeMap(); - for (Score score : data.get(0)) { - // The Score objects contain a set of size one containing the range and - // an ArrayList of size one containing the probabilty - basePairs.put(score.getRanges().first(), new Float(score.getScores().get(0))); - } - } - - // ignoring the Consensus alignemnt for now, get the Structure and make an AlignmentAnnotation - String struct = structs.get(1); // get(1) - for (int i = 0; i < struct.length(); i++) { - - if (BPScores) { - // Return all the contacts associated with position i - List contacts = isContact(basePairs, i+1); + this.bpScores = (fscore.getMethod().equals( + AlifoldResult.contactProbabilities.toString())); - if (contacts.size() == 0) { - anns[i] = new Annotation(struct.substring(i, i+1), "", struct.charAt(i), 0f); - } - else if (contacts.size() == 1) { - // There is only one contact associated with this base - float prob = basePairs.get(contacts.get(0)); - anns[i] = new Annotation(struct.substring(i, i+1), "", struct.charAt(i), prob); - } - else if (contacts.size() > 1) { - // For now we will simply deal with alternate contact information by mentioning its - // existance in the description - float prob = basePairs.get(contacts.get(0)); - anns[i] = new Annotation(struct.substring(i, i+1), "This base has alternate contacts", - struct.charAt(i), prob); + // Add annotations for the mfe Structure + if (bpScores) + createAnnotationRowforScoreHolder(ourAnnot, getCalcId(), structs.get(1), + data.get(0), data.get(1)); + else + createAnnotationRowforScoreHolder(ourAnnot, getCalcId(), structs.get(1), + data.get(1)); + + // add annotation for the consensus sequence alignment + createAnnotationRowforScoreHolder(ourAnnot, getCalcId(), structs.get(0), null); + + // Not loop for the rest of the Annotations + if (structs.size() > 2) { + for (int i = 2; i < structs.size(); i++) { + // I can't think of a nice way of presenting the ensembleValues data + // so I wont for now. + if (!data.get(i).first().getMethod().equals( + AlifoldResult.ensembleValues.toString())) { + createAnnotationRowforScoreHolder(ourAnnot, getCalcId(), structs.get(i), + data.get(i)); } } - else { - // Same as the first if from the previous block - anns[i] = new Annotation(struct.substring(i, i+1), "", struct.charAt(i), 0f); - } - } - - System.out.println("size of anns: " + anns.length); - - // Set the annotation to the AlignmentAnnotation object - annotation.annotations = anns; - - // Set the probability - annotation.setScore(data.get(1).first().getScores().get(0)); - - - - // old -// AlignmentAnnotation annot = new AlignmentAnnotation("Consensus Structure", "Free Energy", anns); - - - - - System.out.println("RNAalifoldClient - annotation:\n"); - for (Annotation ann : annotation.annotations) { - System.out.print(ann.toString()+"|"); } - System.out.println(); - - // Instead of this look at existing methods for creating annotations - ourAnnot.add(annotation); if (ourAnnot.size() > 0) { @@ -161,12 +111,172 @@ public class RNAalifoldClient extends JabawsAlignCalcWorker implements // Modify the visible annotation on the alignment viewport with the // new alignment annotation rows created. updateOurAnnots(ourAnnot); - ap.adjustAnnotationHeight(); + // ap.adjustAnnotationHeight(); } - } } + // just for the base pair contact annotation. It uses a second score object. + protected void createAnnotationRowforScoreHolder( + List ourAnnot, String calcId, + String struct, TreeSet data, TreeSet descriptionData) { + + String typename = data.first().getMethod().toString(); + + AlignmentAnnotation annotation = alignViewport.getAlignment() + .findOrCreateAnnotation(typename, calcId, false, null, null); + + constructAnnotationFromContactProbabilities(annotation, struct, data); + + String description = constructAlignmentAnnotationDescription(descriptionData.first()); + if (description.length() == 0) description = typename; + annotation.description = description; + + // dan test + annotation.belowAlignment = false; + + annotation.validateRangeAndDisplay(); + + ourAnnot.add(annotation); + } + + protected void createAnnotationRowforScoreHolder( + List ourAnnot, String calcId, + String struct, TreeSet data) + { + /* If contactProbability information is returned from RNAalifold it is stored + * in the first TreeSet object corresponding to the String Id which + * holds the consensus alignment. The method enumeration is then updated to + * AlifoldResult.contactProbabilties. This line (hack) recreates the same + * data object as was overwritten with the contact probabilites data. + */ + if (data == null) data = compbio.data.sequence.RNAStructReader + .newEmptyScore(AlifoldResult.consensusAlignment); + + String typename = data.first().getMethod().toString(); + + AlignmentAnnotation annotation = alignViewport.getAlignment() + .findOrCreateAnnotation(typename, calcId, false, null, null); + + // construct annotation from ScoreHolder (unpacked into struct and data) + if (bpScores && data.first().getMethod().equals( + AlifoldResult.contactProbabilities.toString())) + constructAnnotationFromContactProbabilities(annotation, struct, data); + + else + // if bpScores is false the TreeSet data should always contain + // a single Score object + constructAnnotationFromStructureString(annotation, struct, data.first()); + + /* update annotation description with the free Energy, frequency in ensemble + * or other data where appropriate. + * + * Doesnt deal with AlifoldResult.ensembleValues, the free energy of ensemble + * and frequency of mfe structure in ensemble. How to deal with these? + */ + String description = constructAlignmentAnnotationDescription(data.first()); + if (description.length() == 0) description = typename; + annotation.description = description; + + // dan test + annotation.belowAlignment = false; + + annotation.validateRangeAndDisplay(); + + ourAnnot.add(annotation); + } + + + + private AlignmentAnnotation constructAnnotationFromStructureString( + AlignmentAnnotation annotation, String struct, Score score) + { + + Annotation[] anns = new Annotation[struct.length()]; + + for (int i = 0; i < struct.length(); i++) { + anns[i] = new Annotation(struct.substring(i, i+1), "", + struct.charAt(i), Float.NaN); + } + + annotation.graph = 0; // No graph + annotation.annotations = anns; + + + return annotation; + + } + + private String constructAlignmentAnnotationDescription(Score score) { + String description = ""; + String datatype = score.getMethod(); + + if (datatype.equals(AlifoldResult.mfeStructure.toString()) || + datatype.equals(AlifoldResult.centroidStructure.toString())) { + description = MessageFormat.format("Energy: {0} = {1} + {2}", + score.getScores().get(0), score.getScores().get(1), score.getScores().get(2)); + } + else if (datatype.equals(AlifoldResult.contactProbabilityStructure.toString())) { + description = MessageFormat.format("Energy: {0} Frequency: {1}", + score.getScores().get(0), score.getScores().get(1)); + } + else if (datatype.equals(AlifoldResult.stochBTStructure.toString())) { + if (score.getScores().size() > 0) { + description = MessageFormat.format("Probability: {0} Energy: {1}", + score.getScores().get(0), score.getScores().get(1)); + } + else description = "Stochastic Backtrack Structure"; + } + else if (datatype.equals(AlifoldResult.MEAStucture.toString())) { + description = MessageFormat.format("Maximum Expected Accuracy Values: '{' {0} MEA={1} '}", + score.getScores().get(0), score.getScores().get(1)); + } + + return description; + } + + + private AlignmentAnnotation constructAnnotationFromContactProbabilities( + AlignmentAnnotation annotation, String struct, TreeSet data) + { + Annotation[] anns = new Annotation[struct.length()]; + + TreeMap basePairs = null; + // The base pair probabilities are stored in a set in scoreholder. we want a map + basePairs = new TreeMap(); + for (Score score : data) { + // The Score objects contain a set of size one containing the range and + // an ArrayList of size one containing the probabilty + basePairs.put(score.getRanges().first(), new Float(score.getScores().get(0))); + } + for (int i = 0; i < struct.length(); i++) { + + // Return all the contacts associated with position i + List contacts = isContact(basePairs, i+1); + + if (contacts.size() == 0) { + anns[i] = new Annotation(struct.substring(i, i+1), "", struct.charAt(i), 0f); + } + else if (contacts.size() == 1) { + // There is only one contact associated with this base + float prob = basePairs.get(contacts.get(0)); + anns[i] = new Annotation(struct.substring(i, i+1), "", struct.charAt(i), prob); + } + else if (contacts.size() > 1) { + // For now we will simply deal with alternate contact information by mentioning its + // existance in the description + float prob = basePairs.get(contacts.get(0)); + anns[i] = new Annotation(struct.substring(i, i+1), "This base has alternate contacts", + struct.charAt(i), prob); + } + } + + annotation.annotations = anns; + + return annotation; + } + + // Check whether, at position i there is a base contact and return all the // contacts at this position. Should be in order of descending probability. private List isContact(TreeMap basePairs, int i) { @@ -182,6 +292,7 @@ public class RNAalifoldClient extends JabawsAlignCalcWorker implements return contacts; } + public String getCalcId() { return SequenceAnnotationWSClient.AAConCalcId; diff --git a/src/jalview/ws/jws2/SequenceAnnotationWSClient.java b/src/jalview/ws/jws2/SequenceAnnotationWSClient.java index e985f41..eecefd9 100644 --- a/src/jalview/ws/jws2/SequenceAnnotationWSClient.java +++ b/src/jalview/ws/jws2/SequenceAnnotationWSClient.java @@ -179,20 +179,6 @@ public class SequenceAnnotationWSClient extends Jws2Client } } - -// -// if (!processParams(sh, editParams, true)) -// { -// return; -// } -// -// alignFrame -// .getViewport() -// .getCalcManager() -// .startWorker( -// new RNAalifoldClient(sh, alignFrame, preset, paramset)); -// - } public SequenceAnnotationWSClient(AAConSettings fave, diff --git a/test/jalview/ws/jabaws/RNAStructExportImport.java b/test/jalview/ws/jabaws/RNAStructExportImport.java index 510b913..74a24aa 100644 --- a/test/jalview/ws/jabaws/RNAStructExportImport.java +++ b/test/jalview/ws/jabaws/RNAStructExportImport.java @@ -40,13 +40,9 @@ public class RNAStructExportImport { - System.out.println("test1"); - jalview.bin.Cache.initLogger(); disc = JalviewJabawsTestUtils.getJabawsDiscoverer(); - System.out.println("test2"); - for (Jws2Instance svc : disc.getServices()) { @@ -62,8 +58,6 @@ public class RNAStructExportImport if (rnaalifoldws == null) System.exit(0); - System.out.println("test3"); - jalview.io.FileLoader fl = new jalview.io.FileLoader(false); // Following this method a long way we find some (probably important!) @@ -72,8 +66,6 @@ public class RNAStructExportImport assertNotNull("Couldn't load test data ('" + testseqs + "')", af); - System.out.println("test5"); - } @AfterClass @@ -94,8 +86,6 @@ public class RNAStructExportImport { alifoldClient = new RNAalifoldClient(rnaalifoldws, af, null, null); - System.out.println("Service action text:\n" + alifoldClient.getServiceActionText()); - System.out.println("START FOLDING"); af.getViewport().getCalcManager().startWorker(alifoldClient);