X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fproject%2FJalview2XML.java;h=d80fd86abd19705526623106ded1522d55ef4873;hb=21fcce633c77a700ee488806f60b5e4dc8f6895b;hp=f772cf56f086b74f7f1e675751cdbd194eeac0c0;hpb=dc005e4ed3722c21925c026570b7219913f787e7;p=jalview.git diff --git a/src/jalview/project/Jalview2XML.java b/src/jalview/project/Jalview2XML.java index f772cf5..d80fd86 100644 --- a/src/jalview/project/Jalview2XML.java +++ b/src/jalview/project/Jalview2XML.java @@ -24,6 +24,8 @@ import static jalview.math.RotatableMatrix.Axis.X; import static jalview.math.RotatableMatrix.Axis.Y; import static jalview.math.RotatableMatrix.Axis.Z; +import jalview.analysis.AnnotationSorter; +import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.analysis.Conservation; import jalview.analysis.PCA; import jalview.analysis.scoremodels.ScoreModels; @@ -90,6 +92,7 @@ import jalview.util.StringUtils; import jalview.util.jarInputStreamProvider; import jalview.util.matcher.Condition; import jalview.viewmodel.AlignmentViewport; +import jalview.viewmodel.AlignmentViewport.AutoAnnotation; import jalview.viewmodel.PCAModel; import jalview.viewmodel.ViewportRanges; import jalview.viewmodel.seqfeatures.FeatureRendererSettings; @@ -197,17 +200,21 @@ import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; /** - * Write out the current jalview desktop state as a Jalview XML stream. - * - * Note: the vamsas objects referred to here are primitive versions of the - * VAMSAS project schema elements - they are not the same and most likely never - * will be :) - * - * @author $author$ - * @version $Revision: 1.134 $ + * Provides methods to read in or write out the Jalview desktop state as a + * Jalview XML model, as one or more entries in a .jar archive. The jar file may + * include additional data file entries, such as + * */ public class Jalview2XML { + private static final String TRUE = "true"; + + private static final String FALSE = "false"; + private static final String VIEWER_PREFIX = "viewer_"; private static final String RNA_PREFIX = "rna_"; @@ -1479,6 +1486,8 @@ public class Jalview2XML view.setRenderGaps(av.isRenderGaps()); view.setShowAnnotation(av.isShowAnnotation()); view.setShowBoxes(av.getShowBoxes()); + view.setShowAutocalcAbove(av.isShowAutocalculatedAbove()); + view.setSortAnnotationsBy(av.getSortAnnotationsBy().name()); view.setShowColourText(av.getColourText()); view.setShowFullId(av.getShowJVSuffix()); view.setRightAlignIds(av.isRightAlignIds()); @@ -3619,7 +3628,7 @@ public class Jalview2XML // //////////////////////////////// // LOAD ANNOTATIONS - List autoAlan = new ArrayList<>(); + List addedAnnotation = new ArrayList<>(); /* * store any annotations which forward reference a group's ID @@ -3638,17 +3647,14 @@ public class Jalview2XML * test if annotation is automatically calculated for this view only */ boolean autoForView = false; - if (annotation.getLabel().equals("Quality") - || annotation.getLabel().equals("Conservation") - || annotation.getLabel().equals("Consensus")) + if (annotation.getLabel().equals(AutoAnnotation.QUALITY.label) + || annotation.getLabel() + .equals(AutoAnnotation.CONSERVATION.label) + || annotation.getLabel() + .equals(AutoAnnotation.CONSENSUS.label)) { // Kludge for pre 2.5 projects which lacked the autocalculated flag autoForView = true; - // JAXB has no has() test; schema defaults value to false - // if (!annotation.hasAutoCalculated()) - // { - // annotation.setAutoCalculated(true); - // } } if (autoForView || annotation.isAutoCalculated()) { @@ -3670,7 +3676,7 @@ public class Jalview2XML } al.addAnnotation(jda); - + addedAnnotation.add(jda); continue; } // Construct new annotation from model. @@ -3710,7 +3716,11 @@ public class Jalview2XML } } } - jalview.datamodel.AlignmentAnnotation jaa = null; + + /* + * construct the Jalview AlignmentAnnotation, add to alignment + */ + AlignmentAnnotation jaa = null; if (annotation.isGraph()) { @@ -3808,9 +3818,10 @@ public class Jalview2XML jaa.autoCalculated = true; // means annotation will be marked for // update at end of load. } - if (annotation.getGraphHeight() != null) + Integer graphHeight = annotation.getGraphHeight(); + if (graphHeight != null) { - jaa.graphHeight = annotation.getGraphHeight().intValue(); + jaa.graphHeight = graphHeight.intValue(); } jaa.belowAlignment = annotation.isBelowAlignment(); jaa.setCalcId(annotation.getCalcId()); @@ -3822,17 +3833,16 @@ public class Jalview2XML jaa.setProperty(prop.getName(), prop.getValue()); } } - if (jaa.autoCalculated) + if (!jaa.autoCalculated) { - autoAlan.add(new JvAnnotRow(i, jaa)); - } - else - // if (!autoForView) - { - // add autocalculated group annotation and any user created annotation - // for the view + // TODO ensure Consensus etc is enabled if found in project? + /* + * add autocalculated group annotation and any user created annotation + * for the view + */ al.addAnnotation(jaa); } + addedAnnotation.add(jaa); } } // /////////////////////// @@ -3859,7 +3869,7 @@ public class Jalview2XML } else { - cs = ColourSchemeProperty.getColourScheme(al, + cs = ColourSchemeProperty.getColourScheme(null, al, jGroup.getColour()); } } @@ -4024,10 +4034,25 @@ public class Jalview2XML if (isnewview) { - af = loadViewport(file, jseqs, hiddenSeqs, al, jalviewModel, view, - uniqueSeqSetId, viewId, autoAlan); + Map originalPreferences = null; + try + { + originalPreferences = setAutocalcPreferences(jalviewModel); + af = loadViewport(file, jseqs, hiddenSeqs, al, jalviewModel, view, + uniqueSeqSetId, viewId); + } finally + { + restoreAutocalcPreferences(originalPreferences); + } + + /* + * resort annotations to their order in the project + * (also sets height and visibility for autocalc'd annotation) + */ av = af.getViewport(); + new AnnotationSorter(av).sort(addedAnnotation); ap = af.alignPanel; + ap.adjustAnnotationHeight(); } /* @@ -4047,6 +4072,93 @@ public class Jalview2XML } /** + * Restores previously captured preferences (or deletes the preference if the + * map entry value is null) + * + * @param originalPreferences + */ + private void restoreAutocalcPreferences( + Map originalPreferences) + { + for (Entry entry : originalPreferences.entrySet()) + { + String key = entry.getKey(); + String value = entry.getValue(); + if (value == null) + { + Cache.removeProperty(key); + } + else + { + Cache.setProperty(key, value); + } + } + } + + /** + * Inspects saved annotations and temporarily sets preferences for whether + * autocalculated annotations should be created for Conservation, Consensus, + * Quality, Occupancy. Returns a map containing the original values (which may + * be null if property is not set, or is set to null). + * + * @param jalviewModel + * @return + */ + private Map setAutocalcPreferences( + JalviewModel jalviewModel) + { + Map original = Cache.getProperties( + AutoAnnotation.OCCUPANCY.preferenceKey, + AutoAnnotation.CONSERVATION.preferenceKey, + AutoAnnotation.QUALITY.preferenceKey, + AutoAnnotation.CONSENSUS.preferenceKey); + + Cache.setProperty(AutoAnnotation.OCCUPANCY.preferenceKey, FALSE); + Cache.setProperty(AutoAnnotation.CONSERVATION.preferenceKey, FALSE); + Cache.setProperty(AutoAnnotation.QUALITY.preferenceKey, FALSE); + Cache.setProperty(AutoAnnotation.CONSENSUS.preferenceKey, FALSE); + + List sequenceSet = jalviewModel.getVamsasModel() + .getSequenceSet(); + + /* + * expect sequenceSet to have just one entry + */ + if (sequenceSet.size() != 1) + { + System.err.println( + "Unexpected sequenceSet size: " + sequenceSet.size()); + return original; + } + List anns = sequenceSet.get(0).getAnnotation(); + for (Annotation ann : anns) + { + if (ann.isAutoCalculated()) + { + String label = ann.getLabel(); + if (AutoAnnotation.CONSERVATION.label.equals(label)) + { + Cache.setProperty(AutoAnnotation.CONSERVATION.preferenceKey, + TRUE); + } + else if (AutoAnnotation.QUALITY.label.equals(label)) + { + Cache.setProperty(AutoAnnotation.QUALITY.preferenceKey, TRUE); + } + else if (AutoAnnotation.CONSENSUS.label.equals(label)) + { + Cache.setProperty(AutoAnnotation.CONSENSUS.preferenceKey, TRUE); + } + else if (AutoAnnotation.OCCUPANCY.label.equals(label)) + { + Cache.setProperty(AutoAnnotation.OCCUPANCY.preferenceKey, TRUE); + } + } + } + return original; + } + + /** * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna * panel is restored from separate jar entries, two (gapped and trimmed) per * sequence and secondary structure. @@ -4187,10 +4299,8 @@ public class Jalview2XML // TODO: verify 'associate with all views' works still tp.getTreeCanvas().setViewport(av); // af.viewport; tp.getTreeCanvas().setAssociatedPanel(ap); // af.alignPanel; - // FIXME: should we use safeBoolean here ? - tp.getTreeCanvas().setApplyToAllViews(tree.isLinkToAllViews()); - } + tp.getTreeCanvas().setApplyToAllViews(tree.isLinkToAllViews()); if (tp == null) { warn("There was a problem recovering stored Newick tree: \n" @@ -4576,7 +4686,7 @@ public class Jalview2XML { if (val.contains("e")) // eh? what can it be? { - if (val.trim().equals("true")) + if (val.trim().equals(TRUE)) { val = "1"; } @@ -4837,7 +4947,7 @@ public class Jalview2XML AlignFrame loadViewport(String file, List JSEQ, List hiddenSeqs, AlignmentI al, JalviewModel jm, Viewport view, String uniqueSeqSetId, - String viewId, List autoAlan) + String viewId) { AlignFrame af = null; af = new AlignFrame(al, safeInt(view.getWidth()), @@ -4918,9 +5028,8 @@ public class Jalview2XML viewport.setColourText(safeBoolean(view.isShowColourText())); - viewport - .setConservationSelected( - safeBoolean(view.isConservationSelected())); + viewport.setConservationSelected( + safeBoolean(view.isConservationSelected())); viewport.setIncrement(safeInt(view.getConsThreshold())); viewport.setShowJVSuffix(safeBoolean(view.isShowFullId())); viewport.setRightAlignIds(safeBoolean(view.isRightAlignIds())); @@ -4936,10 +5045,27 @@ public class Jalview2XML viewport.setWrapAlignment(safeBoolean(view.isWrapAlignment())); viewport.setShowAnnotation(safeBoolean(view.isShowAnnotation())); - viewport.setShowBoxes(safeBoolean(view.isShowBoxes())); + Boolean autocalcFirst = view.isShowAutocalcAbove(); + if (autocalcFirst != null) + { + af.setShowAutoCalculatedAbove(autocalcFirst.booleanValue()); + } + String sortBy = view.getSortAnnotationsBy(); + if (sortBy != null) + { + try + { + viewport.setSortAnnotationsBy( + SequenceAnnotationOrder.valueOf(sortBy)); + } catch (IllegalArgumentException e) + { + Cache.log.error( + "Invalid annotation sort specifier in project: " + sortBy); + } + } + viewport.setShowBoxes(safeBoolean(view.isShowBoxes())); viewport.setShowText(safeBoolean(view.isShowText())); - viewport.setTextColour(new Color(safeInt(view.getTextCol1()))); viewport.setTextColour2(new Color(safeInt(view.getTextCol2()))); viewport.setThresholdTextColour(safeInt(view.getTextColThreshold())); @@ -4973,25 +5099,27 @@ public class Jalview2XML } else { - cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour()); + cs = ColourSchemeProperty.getColourScheme(af.getViewport(), al, + view.getBgColour()); } } + /* + * turn off 'alignment colour applies to all groups' + * while restoring global colour scheme + */ + viewport.setColourAppliesToAllGroups(false); viewport.setGlobalColourScheme(cs); viewport.getResidueShading().setThreshold(pidThreshold, view.isIgnoreGapsinConsensus()); viewport.getResidueShading() .setConsensus(viewport.getSequenceConsensusHash()); - viewport.setColourAppliesToAllGroups(false); - if (safeBoolean(view.isConservationSelected()) && cs != null) { viewport.getResidueShading() .setConservationInc(safeInt(view.getConsThreshold())); } - af.changeColour(cs); - viewport.setColourAppliesToAllGroups(true); viewport @@ -5067,7 +5195,8 @@ public class Jalview2XML float min = safeFloat(safeFloat(setting.getMin())); float max = setting.getMax() == null ? 1f : setting.getMax().floatValue(); - FeatureColourI gc = new FeatureColour(minColour, maxColour, + FeatureColourI gc = new FeatureColour(maxColour, minColour, + maxColour, noValueColour, min, max); if (setting.getAttributeName().size() > 0) { @@ -5175,7 +5304,6 @@ public class Jalview2XML safeInt(view.getWidth()), safeInt(view.getHeight())); // recompute any autoannotation af.alignPanel.updateAnnotation(false, true); - reorderAutoannotation(af, al, autoAlan); af.alignPanel.alignmentChanged(); } else @@ -5269,7 +5397,7 @@ public class Jalview2XML else { cs = new AnnotationColourGradient(matchedAnnotation, - ColourSchemeProperty.getColourScheme(al, + ColourSchemeProperty.getColourScheme(af.getViewport(), al, viewAnnColour.getColourScheme()), safeInt(viewAnnColour.getAboveThreshold())); } @@ -5302,106 +5430,6 @@ public class Jalview2XML return cs; } - private void reorderAutoannotation(AlignFrame af, AlignmentI al, - List autoAlan) - { - // copy over visualization settings for autocalculated annotation in the - // view - if (al.getAlignmentAnnotation() != null) - { - /** - * Kludge for magic autoannotation names (see JAL-811) - */ - String[] magicNames = new String[] { "Consensus", "Quality", - "Conservation" }; - JvAnnotRow nullAnnot = new JvAnnotRow(-1, null); - Hashtable visan = new Hashtable<>(); - for (String nm : magicNames) - { - visan.put(nm, nullAnnot); - } - for (JvAnnotRow auan : autoAlan) - { - visan.put(auan.template.label - + (auan.template.getCalcId() == null ? "" - : "\t" + auan.template.getCalcId()), - auan); - } - int hSize = al.getAlignmentAnnotation().length; - List reorder = new ArrayList<>(); - // work through any autoCalculated annotation already on the view - // removing it if it should be placed in a different location on the - // annotation panel. - List remains = new ArrayList<>(visan.keySet()); - for (int h = 0; h < hSize; h++) - { - jalview.datamodel.AlignmentAnnotation jalan = al - .getAlignmentAnnotation()[h]; - if (jalan.autoCalculated) - { - String k; - JvAnnotRow valan = visan.get(k = jalan.label); - if (jalan.getCalcId() != null) - { - valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId()); - } - - if (valan != null) - { - // delete the auto calculated row from the alignment - al.deleteAnnotation(jalan, false); - remains.remove(k); - hSize--; - h--; - if (valan != nullAnnot) - { - if (jalan != valan.template) - { - // newly created autoannotation row instance - // so keep a reference to the visible annotation row - // and copy over all relevant attributes - if (valan.template.graphHeight >= 0) - - { - jalan.graphHeight = valan.template.graphHeight; - } - jalan.visible = valan.template.visible; - } - reorder.add(new JvAnnotRow(valan.order, jalan)); - } - } - } - } - // Add any (possibly stale) autocalculated rows that were not appended to - // the view during construction - for (String other : remains) - { - JvAnnotRow othera = visan.get(other); - if (othera != nullAnnot && othera.template.getCalcId() != null - && othera.template.getCalcId().length() > 0) - { - reorder.add(othera); - } - } - // now put the automatic annotation in its correct place - int s = 0, srt[] = new int[reorder.size()]; - JvAnnotRow[] rws = new JvAnnotRow[reorder.size()]; - for (JvAnnotRow jvar : reorder) - { - rws[s] = jvar; - srt[s++] = jvar.order; - } - reorder.clear(); - jalview.util.QuickSort.sort(srt, rws); - // and re-insert the annotation at its correct position - for (JvAnnotRow jvar : rws) - { - al.addAnnotation(jvar.template, jvar.order); - } - af.alignPanel.adjustAnnotationHeight(); - } - } - Hashtable skipList = null; /** @@ -6562,7 +6590,7 @@ public class Jalview2XML noValueColour = maxcol; } - colour = new FeatureColour(mincol, maxcol, noValueColour, + colour = new FeatureColour(maxcol, mincol, maxcol, noValueColour, safeFloat(colourModel.getMin()), safeFloat(colourModel.getMax())); final List attributeName = colourModel.getAttributeName();