X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FJalview2XML.java;h=f3854fe8addc5f3c641df05e35f5b546f2e5aebf;hb=ab43013b7e357b84b4abade0dba949668dfb2a0e;hp=dc1ef4fe8a1df373f7bc9d6e12cb946d81c66154;hpb=d053a3c980cf4318b9a19a255f9fc870e74de989;p=jalview.git diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index dc1ef4f..f3854fe 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -1,44 +1,115 @@ /* - * 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.2b1) + * 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 - * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * + * 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 * 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 . + * 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; -import java.awt.Rectangle; -import java.io.*; -import java.lang.reflect.InvocationTargetException; -import java.net.*; -import java.util.*; -import java.util.Map.Entry; -import java.util.jar.*; - -import javax.swing.*; - -import org.exolab.castor.xml.*; - -import uk.ac.vamsas.objects.utils.MapList; +import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceI; -import jalview.schemabinding.version2.*; -import jalview.schemes.*; +import jalview.schemabinding.version2.AlcodMap; +import jalview.schemabinding.version2.Alcodon; +import jalview.schemabinding.version2.AlcodonFrame; +import jalview.schemabinding.version2.Annotation; +import jalview.schemabinding.version2.AnnotationColours; +import jalview.schemabinding.version2.AnnotationElement; +import jalview.schemabinding.version2.CalcIdParam; +import jalview.schemabinding.version2.DBRef; +import jalview.schemabinding.version2.Features; +import jalview.schemabinding.version2.Group; +import jalview.schemabinding.version2.HiddenColumns; +import jalview.schemabinding.version2.JGroup; +import jalview.schemabinding.version2.JSeq; +import jalview.schemabinding.version2.JalviewModel; +import jalview.schemabinding.version2.JalviewModelSequence; +import jalview.schemabinding.version2.MapListFrom; +import jalview.schemabinding.version2.MapListTo; +import jalview.schemabinding.version2.Mapping; +import jalview.schemabinding.version2.MappingChoice; +import jalview.schemabinding.version2.OtherData; +import jalview.schemabinding.version2.PdbentryItem; +import jalview.schemabinding.version2.Pdbids; +import jalview.schemabinding.version2.Property; +import jalview.schemabinding.version2.Sequence; +import jalview.schemabinding.version2.SequenceSet; +import jalview.schemabinding.version2.SequenceSetProperties; +import jalview.schemabinding.version2.Setting; +import jalview.schemabinding.version2.StructureState; +import jalview.schemabinding.version2.ThresholdLine; +import jalview.schemabinding.version2.Tree; +import jalview.schemabinding.version2.UserColours; +import jalview.schemabinding.version2.Viewport; +import jalview.schemes.AnnotationColourGradient; +import jalview.schemes.ColourSchemeI; +import jalview.schemes.ColourSchemeProperty; +import jalview.schemes.GraduatedColor; +import jalview.schemes.ResidueColourScheme; +import jalview.schemes.ResidueProperties; import jalview.structure.StructureSelectionManager; +import jalview.util.MessageManager; +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; + +import java.awt.Rectangle; +import java.io.BufferedReader; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.Vector; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +import java.util.jar.JarOutputStream; + +import javax.swing.JInternalFrame; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +import org.exolab.castor.xml.Unmarshaller; /** * Write out the current jalview desktop state as a Jalview XML stream. @@ -272,6 +343,8 @@ public class Jalview2XML return; } + Hashtable dsses = new Hashtable(); + try { @@ -326,6 +399,7 @@ public class Jalview2XML } int ap, apSize = af.alignPanels.size(); + for (ap = 0; ap < apSize; ap++) { AlignmentPanel apanel = (AlignmentPanel) af.alignPanels @@ -337,9 +411,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(); @@ -369,6 +455,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 @@ -379,8 +466,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(); @@ -398,6 +491,22 @@ 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 @@ -414,6 +523,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(); @@ -424,7 +555,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(); @@ -443,6 +575,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) { @@ -458,13 +595,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) @@ -496,28 +636,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) @@ -559,9 +705,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(); @@ -570,7 +716,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(); @@ -589,7 +738,9 @@ public class Jalview2XML .startsWith( jmol.jmb.pdbentry[peid].getId() .toLowerCase()))) + { continue; + } if (matchedFile == null) { matchedFile = jmol.jmb.pdbentry[peid].getFile(); @@ -610,7 +761,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 (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1) + if (jds == jmol.jmb.sequence[peid][smap]) { StructureState state = new StructureState(); state.setVisible(true); @@ -636,6 +788,7 @@ public class Jalview2XML } pdb.addStructureState(state); } + } } } @@ -704,7 +857,7 @@ public class Jalview2XML jms.addJSeq(jseq); } - if (av.hasHiddenRows()) + if (!storeDS && av.hasHiddenRows()) { jal = av.getAlignment(); } @@ -748,7 +901,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,148 +943,44 @@ 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); - - 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()); - } - 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 + // Store annotation on dataset sequences only + jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation(); + if (aa != null && aa.length > 0) { - an.setScoreOnly(true); + storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS, + vamsasSet); } - 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 if (jal.getGroups() != null) { JGroup[] groups = new JGroup[jal.getGroups().size()]; - - for (int i = 0; i < groups.length; i++) + int i = -1; + for (jalview.datamodel.SequenceGroup sg : jal.getGroups()) { - groups[i] = new JGroup(); + groups[++i] = new JGroup(); - jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) jal - .getGroups().elementAt(i); groups[i].setStart(sg.getStartRes()); groups[i].setEnd(sg.getEndRes()); groups[i].setName(sg.getName()); @@ -959,10 +1008,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) { @@ -988,6 +1037,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 @@ -998,260 +1048,540 @@ 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); + } + en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups + .keySet().iterator(); + Vector groupsAdded = new Vector(); + while (en.hasNext()) + { + 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); + } - // Make sure we save none displayed feature settings - Enumeration en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours - .keys(); - while (en.hasMoreElements()) + if (av.hasHiddenColumns()) { - String key = en.nextElement().toString(); - if (settingsAdded.contains(key)) + if (av.getColumnSelection() == null + || av.getColumnSelection().getHiddenColumns() == null) { - continue; + warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this."); } - - 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) + else { - setting.setOrder(rorder); + 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); + } } - fs.addSetting(setting); - settingsAdded.addElement(key); } - en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keys(); - Vector groupsAdded = new Vector(); - while (en.hasMoreElements()) + if (calcIdSet.size() > 0) { - String grp = en.nextElement().toString(); - if (groupsAdded.contains(grp)) + for (String calcId : calcIdSet) { - continue; + if (calcId.trim().length() > 0) + { + CalcIdParam cidp = createCalcIdParam(calcId, av); + // Some calcIds have no parameters. + if (cidp != null) + { + view.addCalcIdParam(cidp); + } + } } - 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); + jms.addViewport(view); } + object.setJalviewModelSequence(jms); + object.getVamsasModel().addSequenceSet(vamsasSet); - if (av.hasHiddenColumns()) + if (jout != null && fileName != null) { - if (av.getColumnSelection() == null - || av.getColumnSelection().getHiddenColumns() == null) + // We may not want to write the object to disk, + // eg we can copy the alignViewport to a new view object + // using save and then load + try + { + JarEntry entry = new JarEntry(fileName); + jout.putNextEntry(entry); + PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout, + "UTF-8")); + org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller( + pout); + marshaller.marshal(object); + pout.flush(); + jout.closeEntry(); + } catch (Exception ex) { - warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this."); + // TODO: raise error in GUI if marshalling failed. + ex.printStackTrace(); + } + } + 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 { - for (int c = 0; c < av.getColumnSelection().getHiddenColumns() - .size(); c++) + 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()); + } + if (aa[i].hasProperties()) + { + for (String pr : aa[i].getProperties()) { - int[] region = (int[]) av.getColumnSelection().getHiddenColumns() - .elementAt(c); - HiddenColumns hc = new HiddenColumns(); - hc.setStart(region[0]); - hc.setEnd(region[1]); - view.addHiddenColumns(hc); + Property prop = new Property(); + prop.setName(pr); + prop.setValue(aa[i].getProperty(pr)); + an.addProperty(prop); } } + 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 > ' ') + { + 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); + } } - jms.addViewport(view); + } - object.setJalviewModelSequence(jms); - object.getVamsasModel().addSequenceSet(vamsasSet); + 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; + } - if (jout != null && fileName != null) + private boolean recoverCalcIdParam(CalcIdParam calcIdParam, + AlignViewport av) + { + if (calcIdParam.getVersion().equals("1.0")) { - // We may not want to write the object to disk, - // eg we can copy the alignViewport to a new view object - // using save and then load - try + Jws2Instance service = Jws2Discoverer.getDiscoverer() + .getPreferredServiceFor(calcIdParam.getServiceURL()); + if (service != null) { - JarEntry entry = new JarEntry(fileName); - jout.putNextEntry(entry); - PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout, - "UTF-8")); - org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller( - pout); - marshaller.marshal(object); - pout.flush(); - jout.closeEntry(); - } catch (Exception ex) + 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 { - // TODO: raise error in GUI if marshalling failed. - ex.printStackTrace(); + warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server."); + return false; } } - return object; + throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()})); } /** @@ -1543,6 +1873,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 @@ -1550,10 +1882,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; } @@ -1576,6 +1924,7 @@ public class Jalview2XML return new jarInputStreamProvider() { + @Override public JarInputStream getJarInputStream() throws IOException { if (_url != null) @@ -1588,6 +1937,7 @@ public class Jalview2XML } } + @Override public String getFilename() { return file; @@ -1624,7 +1974,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 @@ -1651,10 +2001,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++; @@ -1752,6 +2106,7 @@ public class Jalview2XML { javax.swing.SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { JOptionPane.showInternalMessageDialog(Desktop.desktop, @@ -1769,22 +2124,26 @@ public class Jalview2XML errorMessage = null; } - Hashtable alreadyLoadedPDB; + Hashtable alreadyLoadedPDB; /** * when set, local views will be updated from view stored in JalviewXML * Currently (28th Sep 2008) things will go horribly wrong in vamsas document * sync if this is set to true. */ - private boolean updateLocalViews = false; + private final boolean updateLocalViews = false; String loadPDBFile(jarInputStreamProvider jprovider, String pdbId) { if (alreadyLoadedPDB == null) + { alreadyLoadedPDB = new Hashtable(); + } if (alreadyLoadedPDB.containsKey(pdbId)) + { return alreadyLoadedPDB.get(pdbId).toString(); + } try { @@ -1820,9 +2179,9 @@ public class Jalview2XML } ; out.close(); - - alreadyLoadedPDB.put(pdbId, outFile.getAbsolutePath()); - return outFile.getAbsolutePath(); + String t = outFile.getAbsolutePath(); + alreadyLoadedPDB.put(pdbId, t); + return t; } else { @@ -1876,7 +2235,9 @@ public class Jalview2XML JalviewModelSequence jms = object.getJalviewModelSequence(); - Viewport view = jms.getViewport(0); + Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0) + : null; + // //////////////////////////////// // LOAD SEQUENCES @@ -1895,7 +2256,7 @@ public class Jalview2XML if (seqRefIds.get(seqId) != null) { - tmpseqs.add((jalview.datamodel.Sequence) seqRefIds.get(seqId)); + tmpseqs.add(seqRefIds.get(seqId)); multipleView = true; } else @@ -1918,8 +2279,7 @@ public class Jalview2XML hiddenSeqs = new Vector(); } - hiddenSeqs.addElement((jalview.datamodel.Sequence) seqRefIds - .get(seqId)); + hiddenSeqs.addElement(seqRefIds.get(seqId)); } } @@ -1953,7 +2313,10 @@ public class Jalview2XML } else { - recoverDatasetFor(vamsasSet, al); + // recover dataset - passing on flag indicating if this a 'viewless' + // sequence set (a.k.a. a stored dataset for the project) + recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence() + .getViewportCount() == 0); } // /////////////////////////////// @@ -2015,7 +2378,9 @@ public class Jalview2XML entry.setFile(pdbloaded.get(ids[p].getId()).toString()); } } - + StructureSelectionManager.getStructureSelectionManager( + Desktop.instance) + .registerPDBEntry(entry); al.getSequenceAt(i).getDatasetSequence().addPDBId(entry); } } @@ -2131,7 +2496,9 @@ public class Jalview2XML // in principle Visible should always be true for annotation displayed // in multiple views if (an[i].hasVisible()) + { jda.visible = an[i].getVisible(); + } al.addAnnotation(jda); @@ -2140,16 +2507,21 @@ 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] @@ -2165,8 +2537,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; @@ -2182,7 +2557,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] @@ -2202,25 +2577,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 @@ -2241,10 +2613,14 @@ public class Jalview2XML jaa.setScore(an[i].getScore()); } if (an[i].hasVisible()) + { jaa.visible = an[i].getVisible(); + } if (an[i].hasCentreColLabels()) + { jaa.centreColLabels = an[i].getCentreColLabels(); + } if (an[i].hasScaleColLabels()) { @@ -2261,6 +2637,19 @@ public class Jalview2XML { jaa.graphHeight = an[i].getGraphHeight(); } + if (an[i].hasBelowAlignment()) + { + jaa.belowAlignment = an[i].isBelowAlignment(); + } + jaa.setCalcId(an[i].getCalcId()); + if (an[i].getPropertyCount() > 0) + { + for (jalview.schemabinding.version2.Property prop : an[i] + .getProperty()) + { + jaa.setProperty(prop.getName(), prop.getValue()); + } + } if (jaa.autoCalculated) { autoAlan.add(new JvAnnotRow(i, jaa)); @@ -2274,14 +2663,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; @@ -2292,6 +2680,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()); @@ -2343,6 +2737,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()); @@ -2386,10 +2784,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 @@ -2433,6 +2840,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) @@ -2601,7 +3015,7 @@ public class Jalview2XML // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, { // seqs_file 2}, boolean[] { // linkAlignPanel,superposeWithAlignpanel}} from hash - Object[] jmoldat = (Object[]) jmolViewIds.get(sviewid); + Object[] jmoldat = jmolViewIds.get(sviewid); ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s) .hasAlignwithAlignPanel() ? ids[p].getStructureState( s).getAlignwithAlignPanel() : false; @@ -2624,12 +3038,12 @@ public class Jalview2XML } if (ids[p].getFile() != null) { + File mapkey = new File(ids[p].getFile()); Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2]) - .get(ids[p].getFile()); + .get(mapkey); if (seqstrmaps == null) { - ((Hashtable) jmoldat[2]).put( - new File(ids[p].getFile()).toString(), + ((Hashtable) jmoldat[2]).put(mapkey, seqstrmaps = new Object[] { pdbFile, ids[p].getId(), new Vector(), new Vector() }); @@ -2662,7 +3076,7 @@ public class Jalview2XML Object[] svattrib = entry.getValue(); int[] geom = (int[]) svattrib[0]; String state = (String) svattrib[1]; - Hashtable oldFiles = (Hashtable) svattrib[2]; + Hashtable oldFiles = (Hashtable) svattrib[2]; final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2]; int x = geom[0], y = geom[1], width = geom[2], height = geom[3]; // collate the pdbfile -> sequence mappings from this view @@ -2726,23 +3140,28 @@ public class Jalview2XML { newFileLoc = new StringBuffer(); } - 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) - .toString()); - newFileLoc.append(((String) filedat[0])); - pdbfilenames.addElement((String) filedat[0]); - pdbids.addElement((String) filedat[1]); - seqmaps.addElement((SequenceI[]) ((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. + 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); } if (cp > 0) { @@ -2755,7 +3174,7 @@ public class Jalview2XML .print("Ignoring incomplete Jmol state for PDB ids: "); newFileLoc = new StringBuffer(state); newFileLoc.append("; load append "); - for (String id : oldFiles.keySet()) + for (File id : oldFiles.keySet()) { // add this and any other pdb files that should be present in // the viewer @@ -2764,7 +3183,7 @@ public class Jalview2XML newFileLoc.append(((String) filedat[0])); pdbfilenames.addElement((String) filedat[0]); pdbids.addElement((String) filedat[1]); - seqmaps.addElement((SequenceI[]) ((Vector) filedat[2]) + seqmaps.addElement(((Vector) filedat[2]) .toArray(new SequenceI[0])); newFileLoc.append(" \""); newFileLoc.append((String) filedat[0]); @@ -2800,10 +3219,10 @@ public class Jalview2XML // TODO: assemble String[] { pdb files }, String[] { id for each // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, { // seqs_file 2}} from hash - final String[] pdbf = (String[]) pdbfilenames - .toArray(new String[pdbfilenames.size()]), id = (String[]) pdbids + final String[] pdbf = pdbfilenames + .toArray(new String[pdbfilenames.size()]), id = pdbids .toArray(new String[pdbids.size()]); - final SequenceI[][] sq = (SequenceI[][]) seqmaps + final SequenceI[][] sq = seqmaps .toArray(new SequenceI[seqmaps.size()][]); final String fileloc = newFileLoc.toString(), vid = sviewid; final AlignFrame alf = af; @@ -2813,14 +3232,17 @@ public class Jalview2XML { javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + @Override public void run() { - AppJmol sview = null; + JalviewStructureDisplayI sview = null; try { - sview = new AppJmol(pdbf, id, sq, alf.alignPanel, + // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera! + sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel, useinJmolsuperpos, usetoColourbyseq, jmolColouring, fileloc, rect, vid); + addNewStructureViewer(sview); } catch (OutOfMemoryError ex) { new OOMWarning("restoring structure view for PDB id " @@ -2853,36 +3275,35 @@ public class Jalview2XML // add mapping for sequences in this view to an already open Jmol // instance - for (String id : oldFiles.keySet()) + for (File id : oldFiles.keySet()) { // add this and any other pdb files that should be present in the // viewer Object[] filedat = oldFiles.get(id); String pdbFile = (String) filedat[0]; - SequenceI[] seq = (SequenceI[]) ((Vector) filedat[2]) + SequenceI[] seq = ((Vector) filedat[2]) .toArray(new SequenceI[0]); - ((AppJmol) comp).jmb.ssm.setMapping(seq, null, pdbFile, + comp.jmb.ssm.setMapping(seq, null, pdbFile, jalview.io.AppletFormatAdapter.FILE); - ((AppJmol) comp).jmb.addSequenceForStructFile(pdbFile, seq); + comp.jmb.addSequenceForStructFile(pdbFile, seq); } // and add the AlignmentPanel's reference to the Jmol view - ((AppJmol) comp).addAlignmentPanel(ap); + comp.addAlignmentPanel(ap); if (useinJmolsuperpos) { - ((AppJmol) comp).useAlignmentPanelForSuperposition(ap); + comp.useAlignmentPanelForSuperposition(ap); } else { - ((AppJmol) comp).excludeAlignmentPanelForSuperposition(ap); + comp.excludeAlignmentPanelForSuperposition(ap); } if (usetoColourbyseq) { - ((AppJmol) comp).useAlignmentPanelForColourbyseq(ap, - !jmolColouring); + comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring); } else { - ((AppJmol) comp).excludeAlignmentPanelForColourbyseq(ap); + comp.excludeAlignmentPanelForColourbyseq(ap); } } } @@ -2892,6 +3313,86 @@ 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(JalviewStructureDisplayI sview) + { + if (newStructureViewers != null) + { + sview.getBinding().setFinishedLoadingFromArchive(false); + newStructureViewers.add(sview); + } + } + + protected void setLoadingFinishedForNewStructureViewers() + { + if (newStructureViewers != null) + { + for (JalviewStructureDisplayI sview : newStructureViewers) + { + sview.getBinding().setFinishedLoadingFromArchive(true); + } + newStructureViewers.clear(); + newStructureViewers = null; + } + } + AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs, Alignment al, JalviewModelSequence jms, Viewport view, String uniqueSeqSetId, String viewId, @@ -2905,8 +3406,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(); @@ -3005,93 +3506,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) - - ); - } - - 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 = (jalview.datamodel.SequenceGroup) al - .getGroups().elementAt(g); - - if (sg.cs == null) - { - continue; - } - - /* - * 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()); - } - - } - } + AnnotationColours viewAnnColour = view.getAnnotationColours(); + cs = constructAnnotationColour(viewAnnColour, af, al, jms, true); - break; - } + // annpos - } - } } else { @@ -3127,8 +3546,8 @@ public class Jalview2XML } if (view.hasIgnoreGapsinConsensus()) { - af.viewport.setIgnoreGapsConsensus(view - .getIgnoreGapsinConsensus(), null); + af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(), + null); } if (view.hasFollowHighlight()) { @@ -3155,6 +3574,10 @@ public class Jalview2XML { af.viewport.setShowSequenceLogo(false); } + if (view.hasNormaliseSequenceLogo()) + { + af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo()); + } if (view.hasShowDbRefTooltip()) { af.viewport.setShowDbRefs(view.getShowDbRefTooltip()); @@ -3223,12 +3646,16 @@ public class Jalview2XML } renderOrder[fs] = setting.getType(); if (setting.hasOrder()) + { af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder( setting.getType(), setting.getOrder()); + } else + { af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder( setting.getType(), fs / jms.getFeatureSettings().getSettingCount()); + } if (setting.getDisplay()) { af.viewport.featuresDisplayed.put(setting.getType(), new Integer( @@ -3254,16 +3681,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) { @@ -3284,21 +3853,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) @@ -3320,6 +3902,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) @@ -3394,7 +3988,8 @@ public class Jalview2XML } } - private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al) + private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al, + boolean ignoreUnrefed) { jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId()); Vector dseqs = null; @@ -3406,7 +4001,7 @@ public class Jalview2XML for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++) { Sequence vamsasSeq = vamsasSet.getSequence(i); - ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs); + ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed); } // create a new dataset if (ds == null) @@ -3419,7 +4014,7 @@ public class Jalview2XML addDatasetRef(vamsasSet.getDatasetId(), ds); } // set the dataset for the newly imported alignment. - if (al.getDataset() == null) + if (al.getDataset() == null && !ignoreUnrefed) { al.setDataset(ds); } @@ -3435,7 +4030,7 @@ public class Jalview2XML * vector to add new dataset sequence to */ private void ensureJalviewDatasetSequence(Sequence vamsasSeq, - AlignmentI ds, Vector dseqs) + AlignmentI ds, Vector dseqs, boolean ignoreUnrefed) { // JBP TODO: Check this is called for AlCodonFrames to support recovery of // xRef Codon Maps @@ -3444,9 +4039,12 @@ public class Jalview2XML jalview.datamodel.SequenceI dsq = null; if (sq != null && sq.getDatasetSequence() != null) { - dsq = (jalview.datamodel.SequenceI) sq.getDatasetSequence(); + dsq = sq.getDatasetSequence(); + } + if (sq == null && ignoreUnrefed) + { + return; } - String sqid = vamsasSeq.getDsseqid(); if (dsq == null) { @@ -3484,6 +4082,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); + } + } + } } } } @@ -3510,11 +4126,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" : "")); } @@ -3731,7 +4348,7 @@ public class Jalview2XML * flag indicating if hashtables should be cleared on finalization TODO this * flag may not be necessary */ - private boolean _cleartables = true; + private final boolean _cleartables = true; private Hashtable jvids2vobj; @@ -3740,6 +4357,7 @@ public class Jalview2XML * * @see java.lang.Object#finalize() */ + @Override protected void finalize() throws Throwable { // really make sure we have no buried refs left. @@ -3884,7 +4502,9 @@ public class Jalview2XML } } else + { Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id); + } } }