X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FJalview2XML.java;h=7a71d79f04b99c17aee36a72d750173198786767;hb=a8f483d04205bb8273ee311c12968b7e86d205fa;hp=14650a9d5d102a637091312b238822c6b43d4c2d;hpb=e826112670b160df06adb4030835624248ac4a8a;p=jalview.git diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index 14650a9..7a71d79 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -1,19 +1,20 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7) - * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle - * + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) + * Copyright (C) 2014 The Jalview Authors + * * This file is part of Jalview. - * + * * Jalview is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License + * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * Jalview is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.gui; @@ -38,14 +39,21 @@ import jalview.schemabinding.version2.*; import jalview.schemes.*; import jalview.util.Platform; import jalview.util.jarInputStreamProvider; +import jalview.viewmodel.AlignmentViewport; +import jalview.ws.jws2.Jws2Discoverer; +import jalview.ws.jws2.dm.AAConSettings; +import jalview.ws.jws2.jabaws2.Jws2Instance; +import jalview.ws.params.ArgumentI; +import jalview.ws.params.AutoCalcSetting; +import jalview.ws.params.WsParamSetI; /** * 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 $ */ @@ -53,7 +61,7 @@ public class Jalview2XML { /** * create/return unique hash string for sq - * + * * @param sq * @return new or existing unique string for sq */ @@ -259,7 +267,7 @@ public class Jalview2XML /** * Writes a jalview project archive to the given Jar output stream. - * + * * @param jout */ public void SaveState(JarOutputStream jout) @@ -271,6 +279,8 @@ public class Jalview2XML return; } + Hashtable dsses = new Hashtable(); + try { @@ -325,6 +335,7 @@ public class Jalview2XML } int ap, apSize = af.alignPanels.size(); + for (ap = 0; ap < apSize; ap++) { AlignmentPanel apanel = (AlignmentPanel) af.alignPanels @@ -336,9 +347,21 @@ public class Jalview2XML } SaveState(apanel, fileName, jout); + + String dssid = getDatasetIdRef(af.getViewport().getAlignment() + .getDataset()); + if (!dsses.containsKey(dssid)) + { + dsses.put(dssid, af); + } + } } } + + writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix, + jout); + try { jout.flush(); @@ -368,6 +391,7 @@ public class Jalview2XML int ap, apSize = af.alignPanels.size(); FileOutputStream fos = new FileOutputStream(jarFile); JarOutputStream jout = new JarOutputStream(fos); + Hashtable dsses = new Hashtable(); for (ap = 0; ap < apSize; ap++) { AlignmentPanel apanel = (AlignmentPanel) af.alignPanels @@ -378,8 +402,14 @@ public class Jalview2XML jfileName = jfileName + ".xml"; } SaveState(apanel, jfileName, jout); + String dssid = getDatasetIdRef(af.getViewport().getAlignment() + .getDataset()); + if (!dsses.containsKey(dssid)) + { + dsses.put(dssid, af); + } } - + writeDatasetFor(dsses, fileName, jout); try { jout.flush(); @@ -397,10 +427,26 @@ public class Jalview2XML } } + private void writeDatasetFor(Hashtable dsses, + String fileName, JarOutputStream jout) + { + + for (String dssids : dsses.keySet()) + { + AlignFrame _af = dsses.get(dssids); + String jfileName = fileName + " Dataset for " + _af.getTitle(); + if (!jfileName.endsWith(".xml")) + { + jfileName = jfileName + ".xml"; + } + SaveState(_af.alignPanel, jfileName, true, jout); + } + } + /** * create a JalviewModel from an algnment view and marshall it to a * JarOutputStream - * + * * @param ap * panel to create jalview model for * @param fileName @@ -413,6 +459,28 @@ public class Jalview2XML public JalviewModel SaveState(AlignmentPanel ap, String fileName, JarOutputStream jout) { + return SaveState(ap, fileName, false, jout); + } + + /** + * create a JalviewModel from an algnment view and marshall it to a + * JarOutputStream + * + * @param ap + * panel to create jalview model for + * @param fileName + * name of alignment panel written to output stream + * @param storeDS + * when true, only write the dataset for the alignment, not the data + * associated with the view. + * @param jout + * jar output stream + * @param out + * jar entry name + */ + public JalviewModel SaveState(AlignmentPanel ap, String fileName, + boolean storeDS, JarOutputStream jout) + { initSeqRefs(); Vector jmolViewIds = new Vector(); // Vector userColours = new Vector(); @@ -423,7 +491,8 @@ public class Jalview2XML object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel()); object.setCreationDate(new java.util.Date(System.currentTimeMillis())); - object.setVersion(jalview.bin.Cache.getProperty("VERSION")); + object.setVersion(jalview.bin.Cache.getDefault("VERSION", + "Development Build")); jalview.datamodel.AlignmentI jal = av.getAlignment(); @@ -442,6 +511,11 @@ public class Jalview2XML { // dataset id is the dataset's hashcode vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset())); + if (storeDS) + { + // switch jal and the dataset + jal = jal.getDataset(); + } } if (jal.getProperties() != null) { @@ -457,13 +531,16 @@ public class Jalview2XML } JSeq jseq; + Set calcIdSet = new HashSet(); // SAVE SEQUENCES String id = ""; - jalview.datamodel.SequenceI jds; + jalview.datamodel.SequenceI jds, jdatasq; for (int i = 0; i < jal.getHeight(); i++) { jds = jal.getSequenceAt(i); + jdatasq = jds.getDatasetSequence() == null ? jds : jds + .getDatasetSequence(); id = seqHash(jds); if (seqRefIds.get(id) != null) @@ -495,28 +572,34 @@ public class Jalview2XML jseq.setColour(av.getSequenceColour(jds).getRGB()); jseq.setId(id); // jseq id should be a string not a number - - if (av.hasHiddenRows()) + if (!storeDS) { - jseq.setHidden(av.getAlignment().getHiddenSequences().isHidden(jds)); - - if (av.isHiddenRepSequence(jal.getSequenceAt(i))) + // Store any sequences this sequence represents + if (av.hasHiddenRows()) { - jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(jal.getSequenceAt(i)).getSequencesInOrder(jal); + jseq.setHidden(av.getAlignment().getHiddenSequences() + .isHidden(jds)); - for (int h = 0; h < reps.length; h++) + if (av.isHiddenRepSequence(jal.getSequenceAt(i))) { - if (reps[h] != jal.getSequenceAt(i)) + jalview.datamodel.SequenceI[] reps = av + .getRepresentedSequences(jal.getSequenceAt(i)) + .getSequencesInOrder(jal); + + for (int h = 0; h < reps.length; h++) { - jseq.addHiddenSequences(jal.findIndex(reps[h])); + if (reps[h] != jal.getSequenceAt(i)) + { + jseq.addHiddenSequences(jal.findIndex(reps[h])); + } } } } } - if (jds.getDatasetSequence().getSequenceFeatures() != null) + if (jdatasq.getSequenceFeatures() != null) { - jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence() + jalview.datamodel.SequenceFeature[] sf = jdatasq .getSequenceFeatures(); int index = 0; while (index < sf.length) @@ -558,9 +641,9 @@ public class Jalview2XML } } - if (jds.getDatasetSequence().getPDBId() != null) + if (jdatasq.getPDBId() != null) { - Enumeration en = jds.getDatasetSequence().getPDBId().elements(); + Enumeration en = jdatasq.getPDBId().elements(); while (en.hasMoreElements()) { Pdbids pdb = new Pdbids(); @@ -569,7 +652,10 @@ public class Jalview2XML pdb.setId(entry.getId()); pdb.setType(entry.getType()); - + // + // store any JMol views associated with this seqeunce + // this section copes with duplicate entries in the project, so a + // dataset only view *should* be coped with sensibly AppJmol jmol; // This must have been loaded, is it still visible? JInternalFrame[] frames = Desktop.desktop.getAllFrames(); @@ -609,8 +695,8 @@ public class Jalview2XML for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++) { -// if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1) - if (jds==jmol.jmb.sequence[peid][smap]) + // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1) + if (jds == jmol.jmb.sequence[peid][smap]) { StructureState state = new StructureState(); state.setVisible(true); @@ -636,6 +722,7 @@ public class Jalview2XML } pdb.addStructureState(state); } + } } } @@ -704,7 +791,7 @@ public class Jalview2XML jms.addJSeq(jseq); } - if (av.hasHiddenRows()) + if (!storeDS && av.hasHiddenRows()) { jal = av.getAlignment(); } @@ -748,7 +835,7 @@ public class Jalview2XML // SAVE TREES // ///////////////////////////////// - if (av.currentTree != null) + if (!storeDS && av.currentTree != null) { // FIND ANY ASSOCIATED TREES // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT @@ -790,142 +877,33 @@ public class Jalview2XML } } } - // SAVE ANNOTATIONS /** * store forward refs from an annotationRow to any groups */ IdentityHashMap groupRefs = new IdentityHashMap(); - if (jal.getAlignmentAnnotation() != null) + if (storeDS) { - jalview.datamodel.AlignmentAnnotation[] aa = jal - .getAlignmentAnnotation(); - - for (int i = 0; i < aa.length; i++) + for (SequenceI sq : jal.getSequences()) { - Annotation an = new Annotation(); - - if (aa[i].annotationId != null) - { - annotationIds.put(aa[i].annotationId, aa[i]); - } - - an.setId(aa[i].annotationId); - - an.setVisible(aa[i].visible); - - an.setDescription(aa[i].description); - - if (aa[i].sequenceRef != null) - { - // TODO later annotation sequenceRef should be the XML ID of the - // sequence rather than its display name - an.setSequenceRef(aa[i].sequenceRef.getName()); - } - if (aa[i].groupRef != null) - { - Object groupIdr = groupRefs.get(aa[i].groupRef); - if (groupIdr == null) - { - // make a locally unique String - groupRefs.put(aa[i].groupRef, - groupIdr = ("" + System.currentTimeMillis() - + aa[i].groupRef.getName() + groupRefs.size())); - } - an.setGroupRef(groupIdr.toString()); - } - - // store all visualization attributes for annotation - an.setGraphHeight(aa[i].graphHeight); - an.setCentreColLabels(aa[i].centreColLabels); - an.setScaleColLabels(aa[i].scaleColLabel); - an.setShowAllColLabels(aa[i].showAllColLabels); - an.setBelowAlignment(aa[i].belowAlignment); - - if (aa[i].graph > 0) - { - an.setGraph(true); - an.setGraphType(aa[i].graph); - an.setGraphGroup(aa[i].graphGroup); - if (aa[i].getThreshold() != null) - { - ThresholdLine line = new ThresholdLine(); - line.setLabel(aa[i].getThreshold().label); - line.setValue(aa[i].getThreshold().value); - line.setColour(aa[i].getThreshold().colour.getRGB()); - an.setThresholdLine(line); - } - } - else - { - an.setGraph(false); - } - - an.setLabel(aa[i].label); - - if (aa[i] == av.getAlignmentQualityAnnot() || aa[i] == av.getAlignmentConservationAnnotation() - || aa[i] == av.getAlignmentConsensusAnnotation() || aa[i].autoCalculated) - { - // new way of indicating autocalculated annotation - - an.setAutoCalculated(aa[i].autoCalculated); - } - if (aa[i].hasScore()) + // Store annotation on dataset sequences only + jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation(); + if (aa != null && aa.length > 0) { - an.setScore(aa[i].getScore()); + storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS, + vamsasSet); } - - if (aa[i].getCalcId()!=null) - { - an.setCalcId(aa[i].getCalcId()); - } - - AnnotationElement ae; - if (aa[i].annotations != null) - { - an.setScoreOnly(false); - for (int a = 0; a < aa[i].annotations.length; a++) - { - if ((aa[i] == null) || (aa[i].annotations[a] == null)) - { - continue; - } - - ae = new AnnotationElement(); - if (aa[i].annotations[a].description != null) - ae.setDescription(aa[i].annotations[a].description); - if (aa[i].annotations[a].displayCharacter != null) - ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter); - - if (!Float.isNaN(aa[i].annotations[a].value)) - ae.setValue(aa[i].annotations[a].value); - - ae.setPosition(a); - if (aa[i].annotations[a].secondaryStructure != ' ' - && aa[i].annotations[a].secondaryStructure != '\0') - ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure - + ""); - - if (aa[i].annotations[a].colour != null - && aa[i].annotations[a].colour != java.awt.Color.black) - { - ae.setColour(aa[i].annotations[a].colour.getRGB()); - } - - an.addAnnotationElement(ae); - if (aa[i].autoCalculated) - { - // only write one non-null entry into the annotation row - - // sufficient to get the visualization attributes necessary to - // display data - continue; - } - } - } - else - { - an.setScoreOnly(true); - } - vamsasSet.addAnnotation(an); + } + } + else + { + if (jal.getAlignmentAnnotation() != null) + { + // Store the annotation shown on the alignment. + jalview.datamodel.AlignmentAnnotation[] aa = jal + .getAlignmentAnnotation(); + storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS, + vamsasSet); } } // SAVE GROUPS @@ -933,7 +911,7 @@ public class Jalview2XML { JGroup[] groups = new JGroup[jal.getGroups().size()]; int i = -1; - for (jalview.datamodel.SequenceGroup sg:jal.getGroups()) + for (jalview.datamodel.SequenceGroup sg : jal.getGroups()) { groups[++i] = new JGroup(); @@ -964,10 +942,10 @@ public class Jalview2XML } else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient) { - groups[i] - .setColour(ColourSchemeProperty - .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs) - .getBaseColour())); + groups[i].setColour("AnnotationColourGradient"); + groups[i].setAnnotationColours(constructAnnotationColours( + (jalview.schemes.AnnotationColourGradient) sg.cs, + userColours, jms)); } else if (sg.cs instanceof jalview.schemes.UserColourScheme) { @@ -993,6 +971,7 @@ public class Jalview2XML groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus()); groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram()); groups[i].setShowSequenceLogo(sg.isShowSequenceLogo()); + groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo()); for (int s = 0; s < sg.getSize(); s++) { jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg @@ -1003,234 +982,238 @@ public class Jalview2XML jms.setJGroup(groups); } + if (!storeDS) + { + // /////////SAVE VIEWPORT + Viewport view = new Viewport(); + view.setTitle(ap.alignFrame.getTitle()); + view.setSequenceSetId(makeHashCode(av.getSequenceSetId(), + av.getSequenceSetId())); + view.setId(av.getViewId()); + view.setViewName(av.viewName); + view.setGatheredViews(av.gatherViewsHere); + + if (ap.av.explodedPosition != null) + { + view.setXpos(av.explodedPosition.x); + view.setYpos(av.explodedPosition.y); + view.setWidth(av.explodedPosition.width); + view.setHeight(av.explodedPosition.height); + } + else + { + view.setXpos(ap.alignFrame.getBounds().x); + view.setYpos(ap.alignFrame.getBounds().y); + view.setWidth(ap.alignFrame.getBounds().width); + view.setHeight(ap.alignFrame.getBounds().height); + } - // /////////SAVE VIEWPORT - Viewport view = new Viewport(); - view.setTitle(ap.alignFrame.getTitle()); - view.setSequenceSetId(makeHashCode(av.getSequenceSetId(), - av.getSequenceSetId())); - view.setId(av.getViewId()); - view.setViewName(av.viewName); - view.setGatheredViews(av.gatherViewsHere); - - if (ap.av.explodedPosition != null) - { - view.setXpos(av.explodedPosition.x); - view.setYpos(av.explodedPosition.y); - view.setWidth(av.explodedPosition.width); - view.setHeight(av.explodedPosition.height); - } - else - { - view.setXpos(ap.alignFrame.getBounds().x); - view.setYpos(ap.alignFrame.getBounds().y); - view.setWidth(ap.alignFrame.getBounds().width); - view.setHeight(ap.alignFrame.getBounds().height); - } - - view.setStartRes(av.startRes); - view.setStartSeq(av.startSeq); - - if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme) - { - view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(), - userColours, jms)); - } - else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient) - { - jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av - .getGlobalColourScheme(); + view.setStartRes(av.startRes); + view.setStartSeq(av.startSeq); - AnnotationColours ac = new AnnotationColours(); - ac.setAboveThreshold(acg.getAboveThreshold()); - ac.setThreshold(acg.getAnnotationThreshold()); - ac.setAnnotation(acg.getAnnotation()); - if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme) + if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme) { - ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(), + view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(), userColours, jms)); } + else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient) + { + AnnotationColours ac = constructAnnotationColours( + (jalview.schemes.AnnotationColourGradient) av + .getGlobalColourScheme(), + userColours, jms); + + view.setAnnotationColours(ac); + view.setBgColour("AnnotationColourGradient"); + } else { - ac.setColourScheme(ColourSchemeProperty.getColourName(acg - .getBaseColour())); + view.setBgColour(ColourSchemeProperty.getColourName(av + .getGlobalColourScheme())); } - ac.setMaxColour(acg.getMaxColour().getRGB()); - ac.setMinColour(acg.getMinColour().getRGB()); - view.setAnnotationColours(ac); - view.setBgColour("AnnotationColourGradient"); - } - else - { - view.setBgColour(ColourSchemeProperty.getColourName(av - .getGlobalColourScheme())); - } - - ColourSchemeI cs = av.getGlobalColourScheme(); + ColourSchemeI cs = av.getGlobalColourScheme(); - if (cs != null) - { - if (cs.conservationApplied()) + if (cs != null) { - view.setConsThreshold(cs.getConservationInc()); - if (cs instanceof jalview.schemes.UserColourScheme) + if (cs.conservationApplied()) { - view.setBgColour(SetUserColourScheme(cs, userColours, jms)); + view.setConsThreshold(cs.getConservationInc()); + if (cs instanceof jalview.schemes.UserColourScheme) + { + view.setBgColour(SetUserColourScheme(cs, userColours, jms)); + } } - } - if (cs instanceof ResidueColourScheme) - { - view.setPidThreshold(cs.getThreshold()); + if (cs instanceof ResidueColourScheme) + { + view.setPidThreshold(cs.getThreshold()); + } } - } - view.setConservationSelected(av.getConservationSelected()); - view.setPidSelected(av.getAbovePIDThreshold()); - view.setFontName(av.font.getName()); - view.setFontSize(av.font.getSize()); - view.setFontStyle(av.font.getStyle()); - view.setRenderGaps(av.renderGaps); - view.setShowAnnotation(av.getShowAnnotation()); - view.setShowBoxes(av.getShowBoxes()); - view.setShowColourText(av.getColourText()); - view.setShowFullId(av.getShowJVSuffix()); - view.setRightAlignIds(av.rightAlignIds); - view.setShowSequenceFeatures(av.showSequenceFeatures); - view.setShowText(av.getShowText()); - view.setShowUnconserved(av.getShowUnconserved()); - view.setWrapAlignment(av.getWrapAlignment()); - view.setTextCol1(av.textColour.getRGB()); - view.setTextCol2(av.textColour2.getRGB()); - view.setTextColThreshold(av.thresholdTextColour); - view.setShowConsensusHistogram(av.isShowConsensusHistogram()); - view.setShowSequenceLogo(av.isShowSequenceLogo()); - view.setShowGroupConsensus(av.isShowGroupConsensus()); - view.setShowGroupConservation(av.isShowGroupConservation()); - view.setShowNPfeatureTooltip(av.isShowNpFeats()); - view.setShowDbRefTooltip(av.isShowDbRefs()); - view.setFollowHighlight(av.followHighlight); - view.setFollowSelection(av.followSelection); - view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus()); - if (av.featuresDisplayed != null) - { - jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings(); + view.setConservationSelected(av.getConservationSelected()); + view.setPidSelected(av.getAbovePIDThreshold()); + view.setFontName(av.font.getName()); + view.setFontSize(av.font.getSize()); + view.setFontStyle(av.font.getStyle()); + view.setRenderGaps(av.renderGaps); + view.setShowAnnotation(av.getShowAnnotation()); + view.setShowBoxes(av.getShowBoxes()); + view.setShowColourText(av.getColourText()); + view.setShowFullId(av.getShowJVSuffix()); + view.setRightAlignIds(av.rightAlignIds); + view.setShowSequenceFeatures(av.showSequenceFeatures); + view.setShowText(av.getShowText()); + view.setShowUnconserved(av.getShowUnconserved()); + view.setWrapAlignment(av.getWrapAlignment()); + view.setTextCol1(av.textColour.getRGB()); + view.setTextCol2(av.textColour2.getRGB()); + view.setTextColThreshold(av.thresholdTextColour); + view.setShowConsensusHistogram(av.isShowConsensusHistogram()); + view.setShowSequenceLogo(av.isShowSequenceLogo()); + view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo()); + view.setShowGroupConsensus(av.isShowGroupConsensus()); + view.setShowGroupConservation(av.isShowGroupConservation()); + view.setShowNPfeatureTooltip(av.isShowNpFeats()); + view.setShowDbRefTooltip(av.isShowDbRefs()); + view.setFollowHighlight(av.followHighlight); + view.setFollowSelection(av.followSelection); + view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus()); + if (av.featuresDisplayed != null) + { + jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings(); - String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder; + String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder; - Vector settingsAdded = new Vector(); - Object gstyle = null; - GraduatedColor gcol = null; - if (renderOrder != null) - { - for (int ro = 0; ro < renderOrder.length; ro++) + Vector settingsAdded = new Vector(); + Object gstyle = null; + GraduatedColor gcol = null; + if (renderOrder != null) { - gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer() - .getFeatureStyle(renderOrder[ro]); - Setting setting = new Setting(); - setting.setType(renderOrder[ro]); - if (gstyle instanceof GraduatedColor) - { - gcol = (GraduatedColor) gstyle; - setting.setColour(gcol.getMaxColor().getRGB()); - setting.setMincolour(gcol.getMinColor().getRGB()); - setting.setMin(gcol.getMin()); - setting.setMax(gcol.getMax()); - setting.setColourByLabel(gcol.isColourByLabel()); - setting.setAutoScale(gcol.isAutoScale()); - setting.setThreshold(gcol.getThresh()); - setting.setThreshstate(gcol.getThreshType()); + for (int ro = 0; ro < renderOrder.length; ro++) + { + gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer() + .getFeatureStyle(renderOrder[ro]); + Setting setting = new Setting(); + setting.setType(renderOrder[ro]); + if (gstyle instanceof GraduatedColor) + { + gcol = (GraduatedColor) gstyle; + setting.setColour(gcol.getMaxColor().getRGB()); + setting.setMincolour(gcol.getMinColor().getRGB()); + setting.setMin(gcol.getMin()); + setting.setMax(gcol.getMax()); + setting.setColourByLabel(gcol.isColourByLabel()); + setting.setAutoScale(gcol.isAutoScale()); + setting.setThreshold(gcol.getThresh()); + setting.setThreshstate(gcol.getThreshType()); + } + else + { + setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer() + .getColour(renderOrder[ro]).getRGB()); + } + + setting.setDisplay(av.featuresDisplayed + .containsKey(renderOrder[ro])); + float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer() + .getOrder(renderOrder[ro]); + if (rorder > -1) + { + setting.setOrder(rorder); + } + fs.addSetting(setting); + settingsAdded.addElement(renderOrder[ro]); } - else + } + + // Make sure we save none displayed feature settings + Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours + .keySet().iterator(); + while (en.hasNext()) + { + String key = en.next().toString(); + if (settingsAdded.contains(key)) { - setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer() - .getColour(renderOrder[ro]).getRGB()); + continue; } - setting.setDisplay(av.featuresDisplayed - .containsKey(renderOrder[ro])); + Setting setting = new Setting(); + setting.setType(key); + setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer() + .getColour(key).getRGB()); + + setting.setDisplay(false); float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer() - .getOrder(renderOrder[ro]); + .getOrder(key); if (rorder > -1) { setting.setOrder(rorder); } fs.addSetting(setting); - settingsAdded.addElement(renderOrder[ro]); + settingsAdded.addElement(key); } - } - - // Make sure we save none displayed feature settings - Enumeration en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours - .keys(); - while (en.hasMoreElements()) - { - String key = en.nextElement().toString(); - if (settingsAdded.contains(key)) + en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups + .keySet().iterator(); + Vector groupsAdded = new Vector(); + while (en.hasNext()) { - continue; + String grp = en.next().toString(); + if (groupsAdded.contains(grp)) + { + continue; + } + Group g = new Group(); + g.setName(grp); + g.setDisplay(((Boolean) ap.seqPanel.seqCanvas + .getFeatureRenderer().featureGroups.get(grp)) + .booleanValue()); + fs.addGroup(g); + groupsAdded.addElement(grp); } + jms.setFeatureSettings(fs); - Setting setting = new Setting(); - setting.setType(key); - setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer() - .getColour(key).getRGB()); + } - setting.setDisplay(false); - float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder( - key); - if (rorder > -1) + if (av.hasHiddenColumns()) + { + if (av.getColumnSelection() == null + || av.getColumnSelection().getHiddenColumns() == null) { - setting.setOrder(rorder); + warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this."); } - fs.addSetting(setting); - settingsAdded.addElement(key); - } - en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keys(); - Vector groupsAdded = new Vector(); - while (en.hasMoreElements()) - { - String grp = en.nextElement().toString(); - if (groupsAdded.contains(grp)) + else { - continue; + for (int c = 0; c < av.getColumnSelection().getHiddenColumns() + .size(); c++) + { + int[] region = (int[]) av.getColumnSelection() + .getHiddenColumns().elementAt(c); + HiddenColumns hc = new HiddenColumns(); + hc.setStart(region[0]); + hc.setEnd(region[1]); + view.addHiddenColumns(hc); + } } - Group g = new Group(); - g.setName(grp); - g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups - .get(grp)).booleanValue()); - fs.addGroup(g); - groupsAdded.addElement(grp); } - jms.setFeatureSettings(fs); - - } - - if (av.hasHiddenColumns()) - { - if (av.getColumnSelection() == null - || av.getColumnSelection().getHiddenColumns() == null) - { - warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this."); - } - else + if (calcIdSet.size() > 0) { - for (int c = 0; c < av.getColumnSelection().getHiddenColumns() - .size(); c++) + for (String calcId : calcIdSet) { - int[] region = (int[]) av.getColumnSelection().getHiddenColumns() - .elementAt(c); - HiddenColumns hc = new HiddenColumns(); - hc.setStart(region[0]); - hc.setEnd(region[1]); - view.addHiddenColumns(hc); + if (calcId.trim().length() > 0) + { + CalcIdParam cidp = createCalcIdParam(calcId, av); + // Some calcIds have no parameters. + if (cidp != null) + { + view.addCalcIdParam(cidp); + } + } } } - } - - jms.addViewport(view); + jms.addViewport(view); + } object.setJalviewModelSequence(jms); object.getVamsasModel().addSequenceSet(vamsasSet); @@ -1259,6 +1242,267 @@ public class Jalview2XML return object; } + private AnnotationColours constructAnnotationColours( + AnnotationColourGradient acg, Vector userColours, + JalviewModelSequence jms) + { + AnnotationColours ac = new AnnotationColours(); + ac.setAboveThreshold(acg.getAboveThreshold()); + ac.setThreshold(acg.getAnnotationThreshold()); + ac.setAnnotation(acg.getAnnotation()); + if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme) + { + ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(), + userColours, jms)); + } + else + { + ac.setColourScheme(ColourSchemeProperty.getColourName(acg + .getBaseColour())); + } + + ac.setMaxColour(acg.getMaxColour().getRGB()); + ac.setMinColour(acg.getMinColour().getRGB()); + ac.setPerSequence(acg.isSeqAssociated()); + ac.setPredefinedColours(acg.isPredefinedColours()); + return ac; + } + + private void storeAlignmentAnnotation(AlignmentAnnotation[] aa, + IdentityHashMap groupRefs, AlignmentViewport av, + Set calcIdSet, boolean storeDS, SequenceSet vamsasSet) + { + + for (int i = 0; i < aa.length; i++) + { + Annotation an = new Annotation(); + + if (aa[i].annotationId != null) + { + annotationIds.put(aa[i].annotationId, aa[i]); + } + + an.setId(aa[i].annotationId); + + an.setVisible(aa[i].visible); + + an.setDescription(aa[i].description); + + if (aa[i].sequenceRef != null) + { + // TODO later annotation sequenceRef should be the XML ID of the + // sequence rather than its display name + an.setSequenceRef(aa[i].sequenceRef.getName()); + } + if (aa[i].groupRef != null) + { + Object groupIdr = groupRefs.get(aa[i].groupRef); + if (groupIdr == null) + { + // make a locally unique String + groupRefs.put(aa[i].groupRef, + groupIdr = ("" + System.currentTimeMillis() + + aa[i].groupRef.getName() + groupRefs.size())); + } + an.setGroupRef(groupIdr.toString()); + } + + // store all visualization attributes for annotation + an.setGraphHeight(aa[i].graphHeight); + an.setCentreColLabels(aa[i].centreColLabels); + an.setScaleColLabels(aa[i].scaleColLabel); + an.setShowAllColLabels(aa[i].showAllColLabels); + an.setBelowAlignment(aa[i].belowAlignment); + + if (aa[i].graph > 0) + { + an.setGraph(true); + an.setGraphType(aa[i].graph); + an.setGraphGroup(aa[i].graphGroup); + if (aa[i].getThreshold() != null) + { + ThresholdLine line = new ThresholdLine(); + line.setLabel(aa[i].getThreshold().label); + line.setValue(aa[i].getThreshold().value); + line.setColour(aa[i].getThreshold().colour.getRGB()); + an.setThresholdLine(line); + } + } + else + { + an.setGraph(false); + } + + an.setLabel(aa[i].label); + + if (aa[i] == av.getAlignmentQualityAnnot() + || aa[i] == av.getAlignmentConservationAnnotation() + || aa[i] == av.getAlignmentConsensusAnnotation() + || aa[i].autoCalculated) + { + // new way of indicating autocalculated annotation - + an.setAutoCalculated(aa[i].autoCalculated); + } + if (aa[i].hasScore()) + { + an.setScore(aa[i].getScore()); + } + + if (aa[i].getCalcId() != null) + { + calcIdSet.add(aa[i].getCalcId()); + an.setCalcId(aa[i].getCalcId()); + } + + AnnotationElement ae; + if (aa[i].annotations != null) + { + an.setScoreOnly(false); + for (int a = 0; a < aa[i].annotations.length; a++) + { + if ((aa[i] == null) || (aa[i].annotations[a] == null)) + { + continue; + } + + ae = new AnnotationElement(); + if (aa[i].annotations[a].description != null) + ae.setDescription(aa[i].annotations[a].description); + if (aa[i].annotations[a].displayCharacter != null) + ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter); + + if (!Float.isNaN(aa[i].annotations[a].value)) + ae.setValue(aa[i].annotations[a].value); + + ae.setPosition(a); + if (aa[i].annotations[a].secondaryStructure != ' ' + && aa[i].annotations[a].secondaryStructure != '\0') + ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure + + ""); + + if (aa[i].annotations[a].colour != null + && aa[i].annotations[a].colour != java.awt.Color.black) + { + ae.setColour(aa[i].annotations[a].colour.getRGB()); + } + + an.addAnnotationElement(ae); + if (aa[i].autoCalculated) + { + // only write one non-null entry into the annotation row - + // sufficient to get the visualization attributes necessary to + // display data + continue; + } + } + } + else + { + an.setScoreOnly(true); + } + if (!storeDS || (storeDS && !aa[i].autoCalculated)) + { + // skip autocalculated annotation - these are only provided for + // alignments + vamsasSet.addAnnotation(an); + } + } + + } + + private CalcIdParam createCalcIdParam(String calcId, AlignViewport av) + { + AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId); + if (settings != null) + { + CalcIdParam vCalcIdParam = new CalcIdParam(); + vCalcIdParam.setCalcId(calcId); + vCalcIdParam.addServiceURL(settings.getServiceURI()); + // generic URI allowing a third party to resolve another instance of the + // service used for this calculation + for (String urls : settings.getServiceURLs()) + { + vCalcIdParam.addServiceURL(urls); + } + vCalcIdParam.setVersion("1.0"); + if (settings.getPreset() != null) + { + WsParamSetI setting = settings.getPreset(); + vCalcIdParam.setName(setting.getName()); + vCalcIdParam.setDescription(setting.getDescription()); + } + else + { + vCalcIdParam.setName(""); + vCalcIdParam.setDescription("Last used parameters"); + } + // need to be able to recover 1) settings 2) user-defined presets or + // recreate settings from preset 3) predefined settings provided by + // service - or settings that can be transferred (or discarded) + vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n", + "|\\n|")); + vCalcIdParam.setAutoUpdate(settings.isAutoUpdate()); + // todo - decide if updateImmediately is needed for any projects. + + return vCalcIdParam; + } + return null; + } + + private boolean recoverCalcIdParam(CalcIdParam calcIdParam, + AlignViewport av) + { + if (calcIdParam.getVersion().equals("1.0")) + { + Jws2Instance service = Jws2Discoverer.getDiscoverer() + .getPreferredServiceFor(calcIdParam.getServiceURL()); + if (service != null) + { + WsParamSetI parmSet = null; + try + { + parmSet = service.getParamStore().parseServiceParameterFile( + calcIdParam.getName(), calcIdParam.getDescription(), + calcIdParam.getServiceURL(), + calcIdParam.getParameters().replace("|\\n|", "\n")); + } catch (IOException x) + { + warn("Couldn't parse parameter data for " + + calcIdParam.getCalcId(), x); + return false; + } + List argList = null; + if (calcIdParam.getName().length() > 0) + { + parmSet = service.getParamStore() + .getPreset(calcIdParam.getName()); + if (parmSet != null) + { + // TODO : check we have a good match with settings in AACon - + // otherwise we'll need to create a new preset + } + } + else + { + argList = parmSet.getArguments(); + parmSet = null; + } + AAConSettings settings = new AAConSettings( + calcIdParam.isAutoUpdate(), service, parmSet, argList); + av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings, + calcIdParam.isNeedsUpdate()); + return true; + } + else + { + warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server."); + return false; + } + } + throw new Error("Unsupported Version for calcIdparam " + + calcIdParam.toString()); + } + /** * External mapping between jalview objects and objects yielding a valid and * unique object ID string. This is null for normal Jalview project IO, but @@ -1270,7 +1514,7 @@ public class Jalview2XML /** * Construct a unique ID for jvobj using either existing bindings or if none * exist, the result of the hashcode call for the object. - * + * * @param jvobj * jalview data object * @return unique ID for referring to jvobj @@ -1301,7 +1545,7 @@ public class Jalview2XML /** * return local jalview object mapped to ID, if it exists - * + * * @param idcode * (may be null) * @return null or object bound to idcode @@ -1537,7 +1781,7 @@ public class Jalview2XML /** * Load a jalview project archive from a jar file - * + * * @param file * - HTTP URL or filename */ @@ -1548,6 +1792,8 @@ public class Jalview2XML try { + // create list to store references for any new Jmol viewers created + newStructureViewers = new Vector(); // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING // Workaround is to make sure caller implements the JarInputStreamProvider // interface @@ -1555,10 +1801,26 @@ public class Jalview2XML jarInputStreamProvider jprovider = createjarInputStreamProvider(file); af = LoadJalviewAlign(jprovider); + } catch (MalformedURLException e) { errorMessage = "Invalid URL format for '" + file + "'"; reportErrors(); + } finally + { + try + { + SwingUtilities.invokeAndWait(new Runnable() + { + public void run() + { + setLoadingFinishedForNewStructureViewers(); + }; + }); + } catch (Exception x) + { + + } } return af; } @@ -1607,7 +1869,7 @@ public class Jalview2XML * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence * themselves. Any null fields will be initialised with default values, * non-null fields are left alone. - * + * * @param jprovider * @return */ @@ -1631,7 +1893,7 @@ public class Jalview2XML frefedSequence = new Vector(); } - jalview.gui.AlignFrame af = null; + jalview.gui.AlignFrame af = null, _af = null; Hashtable gatherToThisFrame = new Hashtable(); final String file = jprovider.getFilename(); try @@ -1658,10 +1920,14 @@ public class Jalview2XML object = (JalviewModel) unmar.unmarshal(in); if (true) // !skipViewport(object)) { - af = LoadFromObject(object, file, true, jprovider); - if (af.viewport.gatherViewsHere) + _af = LoadFromObject(object, file, true, jprovider); + if (object.getJalviewModelSequence().getViewportCount() > 0) { - gatherToThisFrame.put(af.viewport.getSequenceSetId(), af); + af = _af; + if (af.viewport.gatherViewsHere) + { + gatherToThisFrame.put(af.viewport.getSequenceSetId(), af); + } } } entryCount++; @@ -1828,7 +2094,7 @@ public class Jalview2XML } ; out.close(); - String t=outFile.getAbsolutePath(); + String t = outFile.getAbsolutePath(); alreadyLoadedPDB.put(pdbId, t); return t; } @@ -1865,7 +2131,7 @@ public class Jalview2XML /** * Load alignment frame from jalview XML DOM object - * + * * @param object * DOM * @param file @@ -1884,7 +2150,9 @@ public class Jalview2XML JalviewModelSequence jms = object.getJalviewModelSequence(); - Viewport view = jms.getViewport(0); + Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0) + : null; + // //////////////////////////////// // LOAD SEQUENCES @@ -1926,8 +2194,7 @@ public class Jalview2XML hiddenSeqs = new Vector(); } - hiddenSeqs.addElement(seqRefIds - .get(seqId)); + hiddenSeqs.addElement(seqRefIds.get(seqId)); } } @@ -2148,16 +2415,19 @@ public class Jalview2XML // Construct new annotation from model. AnnotationElement[] ae = an[i].getAnnotationElement(); jalview.datamodel.Annotation[] anot = null; - + java.awt.Color firstColour = null; + int anpos; if (!an[i].getScoreOnly()) { anot = new jalview.datamodel.Annotation[al.getWidth()]; for (int aa = 0; aa < ae.length && aa < anot.length; aa++) { - if (ae[aa].getPosition() >= anot.length) + anpos = ae[aa].getPosition(); + + if (anpos >= anot.length) continue; - anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation( + anot[anpos] = new jalview.datamodel.Annotation( ae[aa].getDisplayCharacter(), ae[aa].getDescription(), (ae[aa].getSecondaryStructure() == null || ae[aa] @@ -2173,8 +2443,11 @@ public class Jalview2XML // { // anot[ae[aa].getPosition()].displayCharacter = ""; // } - anot[ae[aa].getPosition()].colour = new java.awt.Color( - ae[aa].getColour()); + anot[anpos].colour = new java.awt.Color(ae[aa].getColour()); + if (firstColour == null) + { + firstColour = anot[anpos].colour; + } } } jalview.datamodel.AlignmentAnnotation jaa = null; @@ -2190,7 +2463,7 @@ public class Jalview2XML an[i].getGraphType()); jaa.graphGroup = an[i].getGraphGroup(); - + jaa._linecolour = firstColour; if (an[i].getThresholdLine() != null) { jaa.setThreshold(new jalview.datamodel.GraphLine(an[i] @@ -2210,25 +2483,22 @@ public class Jalview2XML { jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(), an[i].getDescription(), anot); + jaa._linecolour = firstColour; } - if (autoForView) + // register new annotation + if (an[i].getId() != null) { - // register new annotation - if (an[i].getId() != null) - { - annotationIds.put(an[i].getId(), jaa); - jaa.annotationId = an[i].getId(); - } - // recover sequence association - if (an[i].getSequenceRef() != null) + annotationIds.put(an[i].getId(), jaa); + jaa.annotationId = an[i].getId(); + } + // recover sequence association + if (an[i].getSequenceRef() != null) + { + if (al.findName(an[i].getSequenceRef()) != null) { - if (al.findName(an[i].getSequenceRef()) != null) - { - jaa.createSequenceMapping( - al.findName(an[i].getSequenceRef()), 1, true); - al.findName(an[i].getSequenceRef()).addAlignmentAnnotation( - jaa); - } + jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()), + 1, true); + al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa); } } // and make a note of any group association @@ -2271,7 +2541,7 @@ public class Jalview2XML } if (an[i].hasBelowAlignment()) { - jaa.belowAlignment=an[i].isBelowAlignment(); + jaa.belowAlignment = an[i].isBelowAlignment(); } jaa.setCalcId(an[i].getCalcId()); @@ -2288,14 +2558,13 @@ public class Jalview2XML } } } - // /////////////////////// // LOAD GROUPS // Create alignment markup and styles for this view if (jms.getJGroupCount() > 0) { JGroup[] groups = jms.getJGroup(); - + boolean addAnnotSchemeGroup = false; for (int i = 0; i < groups.length; i++) { ColourSchemeI cs = null; @@ -2306,6 +2575,12 @@ public class Jalview2XML { cs = GetUserColourScheme(jms, groups[i].getColour()); } + else if (groups[i].getColour().equals("AnnotationColourGradient") + && groups[i].getAnnotationColours() != null) + { + addAnnotSchemeGroup = true; + cs = null; + } else { cs = ColourSchemeProperty.getColour(al, groups[i].getColour()); @@ -2357,6 +2632,10 @@ public class Jalview2XML { sg.setshowSequenceLogo(groups[i].isShowSequenceLogo()); } + if (groups[i].hasNormaliseSequenceLogo()) + { + sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo()); + } if (groups[i].hasIgnoreGapsinConsensus()) { sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus()); @@ -2400,10 +2679,19 @@ public class Jalview2XML } } al.addGroup(sg); - + if (addAnnotSchemeGroup) + { + // reconstruct the annotation colourscheme + sg.cs = constructAnnotationColour( + groups[i].getAnnotationColours(), null, al, jms, false); + } } } - + if (view == null) + { + // only dataset in this model, so just return. + return null; + } // /////////////////////////////// // LOAD VIEWPORT @@ -2447,6 +2735,13 @@ public class Jalview2XML } } + /** + * indicate that annotation colours are applied across all groups (pre + * Jalview 2.8.1 behaviour) + */ + boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1", + object.getVersion()); + AlignmentPanel ap = null; boolean isnewview = true; if (viewId != null) @@ -2638,13 +2933,12 @@ public class Jalview2XML } if (ids[p].getFile() != null) { - File mapkey=new File(ids[p].getFile()); + File mapkey = new File(ids[p].getFile()); Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2]) .get(mapkey); if (seqstrmaps == null) { - ((Hashtable) jmoldat[2]).put( - mapkey, + ((Hashtable) jmoldat[2]).put(mapkey, seqstrmaps = new Object[] { pdbFile, ids[p].getId(), new Vector(), new Vector() }); @@ -2741,25 +3035,28 @@ public class Jalview2XML { newFileLoc = new StringBuffer(); } - do { + do + { // look for next filename in load statement - newFileLoc.append(state.substring(cp, - ncp = (state.indexOf("\"", ncp + 1) + 1))); - String oldfilenam = state.substring(ncp, - ecp = state.indexOf("\"", ncp)); - // recover the new mapping data for this old filename - // have to normalize filename - since Jmol and jalview do filename - // translation differently. - Object[] filedat = oldFiles.get(new File(oldfilenam)); - newFileLoc.append(Platform.escapeString((String) filedat[0])); - pdbfilenames.addElement((String) filedat[0]); - pdbids.addElement((String) filedat[1]); - seqmaps.addElement(((Vector) filedat[2]) - .toArray(new SequenceI[0])); - newFileLoc.append("\""); - cp = ecp + 1; // advance beyond last \" and set cursor so we can - // look for next file statement. - } while ((ncp=state.indexOf("/*file*/",cp))>-1); + newFileLoc.append(state.substring(cp, + ncp = (state.indexOf("\"", ncp + 1) + 1))); + String oldfilenam = state.substring(ncp, + ecp = state.indexOf("\"", ncp)); + // recover the new mapping data for this old filename + // have to normalize filename - since Jmol and jalview do + // filename + // translation differently. + Object[] filedat = oldFiles.get(new File(oldfilenam)); + newFileLoc.append(Platform + .escapeString((String) filedat[0])); + pdbfilenames.addElement((String) filedat[0]); + pdbids.addElement((String) filedat[1]); + seqmaps.addElement(((Vector) filedat[2]) + .toArray(new SequenceI[0])); + newFileLoc.append("\""); + cp = ecp + 1; // advance beyond last \" and set cursor so we can + // look for next file statement. + } while ((ncp = state.indexOf("/*file*/", cp)) > -1); } if (cp > 0) { @@ -2839,6 +3136,7 @@ public class Jalview2XML sview = new AppJmol(pdbf, id, sq, alf.alignPanel, useinJmolsuperpos, usetoColourbyseq, jmolColouring, fileloc, rect, vid); + addNewStructureViewer(sview); } catch (OutOfMemoryError ex) { new OOMWarning("restoring structure view for PDB id " @@ -2895,8 +3193,7 @@ public class Jalview2XML } if (usetoColourbyseq) { - comp.useAlignmentPanelForColourbyseq(ap, - !jmolColouring); + comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring); } else { @@ -2910,6 +3207,83 @@ public class Jalview2XML return af; } + /** + * + * @param supported - minimum version we are comparing against + * @param version - version of data being processsed. + * @return true if version is development/null or evaluates to the same or + * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*) + */ + private boolean isVersionStringLaterThan(String supported, String version) + { + if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD") + || version.equalsIgnoreCase("Test") || version.equalsIgnoreCase("AUTOMATED BUILD")) + { + System.err.println("Assuming project file with " + + (version == null ? "null" : version) + + " is compatible with Jalview version " + supported); + return true; + } + else + { + StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer( + version, "."); + while (currentV.hasMoreTokens() && fileV.hasMoreTokens()) + { + // convert b to decimal to catch bugfix releases within a series + String curT = currentV.nextToken().toLowerCase().replace('b', '.'); + String fileT = fileV.nextToken().toLowerCase().replace('b', '.'); + try + { + if (Float.valueOf(curT) > Float.valueOf(fileT)) + { + // current version is newer than the version that wrote the file + return false; + } + } catch (NumberFormatException nfe) + { + System.err + .println("** WARNING: Version comparison failed for tokens (" + + curT + + ") and (" + + fileT + + ")\n** Current: '" + + supported + "' and Version: '" + version + "'"); + } + } + if (currentV.hasMoreElements()) + { + // fileV has no minor version but identical series to current + return false; + } + } + return true; + } + + Vector newStructureViewers = null; + + protected void addNewStructureViewer(AppJmol sview) + { + if (newStructureViewers != null) + { + sview.jmb.setFinishedLoadingFromArchive(false); + newStructureViewers.add(sview); + } + } + + protected void setLoadingFinishedForNewStructureViewers() + { + if (newStructureViewers != null) + { + for (AppJmol sview : newStructureViewers) + { + sview.jmb.setFinishedLoadingFromArchive(true); + } + newStructureViewers.clear(); + newStructureViewers = null; + } + } + AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs, Alignment al, JalviewModelSequence jms, Viewport view, String uniqueSeqSetId, String viewId, @@ -2923,8 +3297,8 @@ public class Jalview2XML for (int i = 0; i < JSEQ.length; i++) { - af.viewport.setSequenceColour(af.viewport.getAlignment().getSequenceAt(i), - new java.awt.Color(JSEQ[i].getColour())); + af.viewport.setSequenceColour(af.viewport.getAlignment() + .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour())); } af.viewport.gatherViewsHere = view.getGatheredViews(); @@ -3023,93 +3397,11 @@ public class Jalview2XML } else if (view.getBgColour().startsWith("Annotation")) { - // int find annotation - if (af.viewport.getAlignment().getAlignmentAnnotation() != null) - { - for (int i = 0; i < af.viewport.getAlignment() - .getAlignmentAnnotation().length; i++) - { - if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label - .equals(view.getAnnotationColours().getAnnotation())) - { - if (af.viewport.getAlignment().getAlignmentAnnotation()[i] - .getThreshold() == null) - { - af.viewport.getAlignment().getAlignmentAnnotation()[i] - .setThreshold(new jalview.datamodel.GraphLine(view - .getAnnotationColours().getThreshold(), - "Threshold", java.awt.Color.black) + AnnotationColours viewAnnColour = view.getAnnotationColours(); + cs = constructAnnotationColour(viewAnnColour, af, al, jms, true); - ); - } - - if (view.getAnnotationColours().getColourScheme() - .equals("None")) - { - cs = new AnnotationColourGradient( - af.viewport.getAlignment().getAlignmentAnnotation()[i], - new java.awt.Color(view.getAnnotationColours() - .getMinColour()), new java.awt.Color(view - .getAnnotationColours().getMaxColour()), - view.getAnnotationColours().getAboveThreshold()); - } - else if (view.getAnnotationColours().getColourScheme() - .startsWith("ucs")) - { - cs = new AnnotationColourGradient( - af.viewport.getAlignment().getAlignmentAnnotation()[i], - GetUserColourScheme(jms, view - .getAnnotationColours().getColourScheme()), - view.getAnnotationColours().getAboveThreshold()); - } - else - { - cs = new AnnotationColourGradient( - af.viewport.getAlignment().getAlignmentAnnotation()[i], - ColourSchemeProperty.getColour(al, view - .getAnnotationColours().getColourScheme()), - view.getAnnotationColours().getAboveThreshold()); - } - - // Also use these settings for all the groups - if (al.getGroups() != null) - { - for (int g = 0; g < al.getGroups().size(); g++) - { - jalview.datamodel.SequenceGroup sg = al - .getGroups().get(g); - - if (sg.cs == null) - { - continue; - } + // annpos - /* - * if - * (view.getAnnotationColours().getColourScheme().equals("None" - * )) { sg.cs = new AnnotationColourGradient( - * af.viewport.getAlignment().getAlignmentAnnotation()[i], new - * java.awt.Color(view.getAnnotationColours(). - * getMinColour()), new - * java.awt.Color(view.getAnnotationColours(). - * getMaxColour()), - * view.getAnnotationColours().getAboveThreshold()); } else - */ - { - sg.cs = new AnnotationColourGradient( - af.viewport.getAlignment().getAlignmentAnnotation()[i], - sg.cs, view.getAnnotationColours() - .getAboveThreshold()); - } - - } - } - - break; - } - - } - } } else { @@ -3145,8 +3437,8 @@ public class Jalview2XML } if (view.hasIgnoreGapsinConsensus()) { - af.viewport.setIgnoreGapsConsensus(view - .getIgnoreGapsinConsensus(), null); + af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(), + null); } if (view.hasFollowHighlight()) { @@ -3173,6 +3465,10 @@ public class Jalview2XML { af.viewport.setShowSequenceLogo(false); } + if (view.hasNormaliseSequenceLogo()) + { + af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo()); + } if (view.hasShowDbRefTooltip()) { af.viewport.setShowDbRefs(view.getShowDbRefTooltip()); @@ -3272,16 +3568,158 @@ public class Jalview2XML ); } } - + if (view.getCalcIdParam() != null) + { + for (CalcIdParam calcIdParam : view.getCalcIdParam()) + { + if (calcIdParam != null) + { + if (recoverCalcIdParam(calcIdParam, af.viewport)) + { + } + else + { + warn("Couldn't recover parameters for " + + calcIdParam.getCalcId()); + } + } + } + } af.setMenusFromViewport(af.viewport); // TODO: we don't need to do this if the viewport is aready visible. Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), view.getHeight()); - af.alignPanel.updateAnnotation(false); // recompute any autoannotation + af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation reorderAutoannotation(af, al, autoAlan); + af.alignPanel.alignmentChanged(); return af; } + private ColourSchemeI constructAnnotationColour( + AnnotationColours viewAnnColour, AlignFrame af, Alignment al, + JalviewModelSequence jms, boolean checkGroupAnnColour) + { + boolean propagateAnnColour = false; + ColourSchemeI cs = null; + AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al; + if (checkGroupAnnColour && al.getGroups() != null + && al.getGroups().size() > 0) + { + // pre 2.8.1 behaviour + // check to see if we should transfer annotation colours + propagateAnnColour = true; + for (jalview.datamodel.SequenceGroup sg : al.getGroups()) + { + if (sg.cs instanceof AnnotationColourGradient) + { + propagateAnnColour = false; + } + } + } + // int find annotation + if (annAlignment.getAlignmentAnnotation() != null) + { + for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++) + { + if (annAlignment.getAlignmentAnnotation()[i].label + .equals(viewAnnColour.getAnnotation())) + { + if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null) + { + annAlignment.getAlignmentAnnotation()[i] + .setThreshold(new jalview.datamodel.GraphLine( + viewAnnColour.getThreshold(), "Threshold", + java.awt.Color.black) + + ); + } + + if (viewAnnColour.getColourScheme().equals("None")) + { + cs = new AnnotationColourGradient( + annAlignment.getAlignmentAnnotation()[i], + new java.awt.Color(viewAnnColour.getMinColour()), + new java.awt.Color(viewAnnColour.getMaxColour()), + viewAnnColour.getAboveThreshold()); + } + else if (viewAnnColour.getColourScheme().startsWith("ucs")) + { + cs = new AnnotationColourGradient( + annAlignment.getAlignmentAnnotation()[i], + GetUserColourScheme(jms, + viewAnnColour.getColourScheme()), + viewAnnColour.getAboveThreshold()); + } + else + { + cs = new AnnotationColourGradient( + annAlignment.getAlignmentAnnotation()[i], + ColourSchemeProperty.getColour(al, + viewAnnColour.getColourScheme()), + viewAnnColour.getAboveThreshold()); + } + if (viewAnnColour.hasPerSequence()) + { + ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour + .isPerSequence()); + } + if (viewAnnColour.hasPredefinedColours()) + { + ((AnnotationColourGradient) cs) + .setPredefinedColours(viewAnnColour + .isPredefinedColours()); + } + if (propagateAnnColour && al.getGroups() != null) + { + // Also use these settings for all the groups + for (int g = 0; g < al.getGroups().size(); g++) + { + jalview.datamodel.SequenceGroup sg = al.getGroups().get(g); + + if (sg.cs == null) + { + continue; + } + + /* + * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs = + * new AnnotationColourGradient( + * annAlignment.getAlignmentAnnotation()[i], new + * java.awt.Color(viewAnnColour. getMinColour()), new + * java.awt.Color(viewAnnColour. getMaxColour()), + * viewAnnColour.getAboveThreshold()); } else + */ + { + sg.cs = new AnnotationColourGradient( + annAlignment.getAlignmentAnnotation()[i], sg.cs, + viewAnnColour.getAboveThreshold()); + if (cs instanceof AnnotationColourGradient) + { + if (viewAnnColour.hasPerSequence()) + { + ((AnnotationColourGradient) cs) + .setSeqAssociated(viewAnnColour.isPerSequence()); + } + if (viewAnnColour.hasPredefinedColours()) + { + ((AnnotationColourGradient) cs) + .setPredefinedColours(viewAnnColour + .isPredefinedColours()); + } + } + } + + } + } + + break; + } + + } + } + return cs; + } + private void reorderAutoannotation(AlignFrame af, Alignment al, ArrayList autoAlan) { @@ -3302,21 +3740,34 @@ public class Jalview2XML } for (JvAnnotRow auan : autoAlan) { - visan.put(auan.template.label, auan); + visan.put(auan.template.label + + (auan.template.getCalcId() == null ? "" : "\t" + + auan.template.getCalcId()), auan); } int hSize = al.getAlignmentAnnotation().length; ArrayList 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) { - JvAnnotRow valan = visan.get(jalan.label); + 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(al.getAlignmentAnnotation()[h], false); + al.deleteAnnotation(jalan, false); + remains.remove(k); hSize--; h--; if (valan != nullAnnot) @@ -3338,6 +3789,18 @@ public class Jalview2XML } } } + // 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) @@ -3360,7 +3823,7 @@ public class Jalview2XML /** * TODO remove this method - * + * * @param view * @return AlignFrame bound to sequenceSetId from view, if one exists. private * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) { @@ -3371,7 +3834,7 @@ public class Jalview2XML /** * Check if the Jalview view contained in object should be skipped or not. - * + * * @param object * @return true if view's sequenceSetId is a key in skipList */ @@ -3444,7 +3907,7 @@ public class Jalview2XML } /** - * + * * @param vamsasSeq * sequence definition to create/merge dataset sequence for * @param ds @@ -3502,6 +3965,24 @@ public class Jalview2XML if (sq != dsq) { // make this dataset sequence sq's dataset sequence sq.setDatasetSequence(dsq); + // and update the current dataset alignment + if (ds == null) + { + if (dseqs != null) + { + if (!dseqs.contains(dsq)) + { + dseqs.add(dsq); + } + } + else + { + if (ds.findIndex(dsq) < 0) + { + ds.addSequence(dsq); + } + } + } } } } @@ -3528,11 +4009,12 @@ public class Jalview2XML * sb.append(newres.substring(newres.length() - sq.getEnd() - * dsq.getEnd())); dsq.setEnd(sq.getEnd()); } */ - dsq.setSequence(sb.toString()); + dsq.setSequence(newres); } // TODO: merges will never happen if we 'know' we have the real dataset // sequence - this should be detected when id==dssid - System.err.println("DEBUG Notice: Merged dataset sequence"); // (" + System.err + .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // (" // + (pre ? "prepended" : "") + " " // + (post ? "appended" : "")); } @@ -3568,7 +4050,7 @@ public class Jalview2XML /** * make a new dataset ID for this jalview dataset alignment - * + * * @param dataset * @return */ @@ -3755,7 +4237,7 @@ public class Jalview2XML /* * (non-Javadoc) - * + * * @see java.lang.Object#finalize() */ @Override @@ -3833,13 +4315,13 @@ public class Jalview2XML * finalize and clearSeqRefs will not clear the tables when the Jalview2XML * object goes out of scope. - also populates the datasetIds hashtable with * alignment objects containing dataset sequences - * + * * @param vobj2jv * Map from ID strings to jalview datamodel * @param jv2vobj * Map from jalview datamodel to ID strings - * - * + * + * */ public void setObjectMappingTables(Hashtable vobj2jv, IdentityHashMap jv2vobj) @@ -3911,7 +4393,7 @@ public class Jalview2XML * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview * objects created from the project archive. If string is null (default for * construction) then suffix will be set automatically. - * + * * @param string */ public void setUniqueSetSuffix(String string) @@ -3923,7 +4405,7 @@ public class Jalview2XML /** * uses skipList2 as the skipList for skipping views on sequence sets * associated with keys in the skipList - * + * * @param skipList2 */ public void setSkipList(Hashtable skipList2)