X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FJalview2XML.java;h=1a9bc033fd659bddd02994af1bf2c047db143630;hb=e74c1be398cd4ebe5f420c13be6143464100bb52;hp=b3cf1af8ffe11b877195988280e6c2617dd3ac64;hpb=08147bef2f987d715de9d4c617c7beb58a326d42;p=jalview.git diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java old mode 100755 new mode 100644 index b3cf1af..1a9bc03 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -1,27 +1,28 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4) - * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6) + * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle * - * This program 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 2 - * of the License, or (at your option) any later version. + * This file is part of Jalview. * - * This program 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. + * 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. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * 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 . */ 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.*; @@ -31,6 +32,7 @@ import org.exolab.castor.xml.*; import uk.ac.vamsas.objects.utils.MapList; import jalview.bin.Cache; import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceI; import jalview.schemabinding.version2.*; @@ -46,7 +48,7 @@ import jalview.util.jarInputStreamProvider; * will be :) * * @author $author$ - * @version $Revision$ + * @version $Revision: 1.134 $ */ public class Jalview2XML { @@ -401,19 +403,19 @@ public class Jalview2XML * JarOutputStream * * @param ap - * panel to create jalview model for + * panel to create jalview model for * @param fileName - * name of alignment panel written to output stream + * name of alignment panel written to output stream * @param jout - * jar output stream + * jar output stream * @param out - * jar entry name + * jar entry name */ public JalviewModel SaveState(AlignmentPanel ap, String fileName, JarOutputStream jout) { initSeqRefs(); - + Vector jmolViewIds = new Vector(); // Vector userColours = new Vector(); AlignViewport av = ap.av; @@ -574,41 +576,81 @@ public class Jalview2XML AppJmol jmol; // This must have been loaded, is it still visible? JInternalFrame[] frames = Desktop.desktop.getAllFrames(); + String matchedFile = null; for (int f = frames.length - 1; f > -1; f--) { if (frames[f] instanceof AppJmol) { jmol = (AppJmol) frames[f]; - if (!jmol.pdbentry.getId().equals(entry.getId()) - && !(entry.getId().length()>4 - && entry.getId().startsWith(jmol.pdbentry.getId()))) - continue; - - StructureState state = new StructureState(); - state.setVisible(true); - state.setXpos(jmol.getX()); - state.setYpos(jmol.getY()); - state.setWidth(jmol.getWidth()); - state.setHeight(jmol.getHeight()); - state.setViewId(jmol.getViewId()); - String statestring = jmol.viewer.getStateInfo(); - if (state != null) - { - state.setContent(statestring.replaceAll("\n", "")); - } - for (int s = 0; s < jmol.sequence.length; s++) + for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++) { - if (jal.findIndex(jmol.sequence[s]) > -1) + if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId()) + && !(entry.getId().length() > 4 && entry + .getId() + .toLowerCase() + .startsWith( + jmol.jmb.pdbentry[peid].getId() + .toLowerCase()))) + continue; + if (matchedFile == null) { - pdb.addStructureState(state); + matchedFile = jmol.jmb.pdbentry[peid].getFile(); + } + else if (!matchedFile.equals(jmol.jmb.pdbentry[peid] + .getFile())) + { + Cache.log + .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): " + + jmol.jmb.pdbentry[peid].getFile()); + ; // record the + } + // file so we + // can get at it if the ID + // match is ambiguous (e.g. + // 1QIP==1qipA) + String statestring = jmol.jmb.viewer.getStateInfo(); + + for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++) + { + if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1) + { + StructureState state = new StructureState(); + state.setVisible(true); + state.setXpos(jmol.getX()); + state.setYpos(jmol.getY()); + state.setWidth(jmol.getWidth()); + state.setHeight(jmol.getHeight()); + state.setViewId(jmol.getViewId()); + state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap)); + state.setColourwithAlignPanel(jmol + .isUsedforcolourby(ap)); + state.setColourByJmol(jmol.isColouredByJmol()); + if (!jmolViewIds.contains(state.getViewId())) + { + // Make sure we only store a Jmol state once in each XML + // document. + jmolViewIds.addElement(state.getViewId()); + state.setContent(statestring.replaceAll("\n", "")); + } + else + { + state.setContent("# duplicate state"); + } + pdb.addStructureState(state); + } } } } } - if (entry.getFile() != null) + if (matchedFile != null || entry.getFile() != null) { - pdb.setFile(entry.getFile()); + if (entry.getFile() != null) + { + // use entry's file + matchedFile = entry.getFile(); + } + pdb.setFile(matchedFile); // entry.getFile()); if (pdbfiles == null) { pdbfiles = new Vector(); @@ -619,7 +661,7 @@ public class Jalview2XML pdbfiles.addElement(entry.getId()); try { - File file = new File(entry.getFile()); + File file = new File(matchedFile); if (file.exists() && jout != null) { byte[] data = new byte[(int) file.length()]; @@ -679,9 +721,10 @@ public class Jalview2XML for (int p = 0; p < jac[i].aaWidth; p++) { Alcodon cmap = new Alcodon(); - if (jac[i].codons[p]!=null) + if (jac[i].codons[p] != null) { - // Null codons indicate a gapped column in the translated peptide alignment. + // Null codons indicate a gapped column in the translated peptide + // alignment. cmap.setPos1(jac[i].codons[p][0]); cmap.setPos2(jac[i].codons[p][1]); cmap.setPos3(jac[i].codons[p][2]); @@ -696,7 +739,7 @@ public class Jalview2XML for (int m = 0; m < pmaps.length; m++) { AlcodMap alcmap = new AlcodMap(); - alcmap.setDnasq(seqHash(dnas[m])); + alcmap.setDnasq(seqHash(dnas[m])); alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null, false)); alc.addAlcodMap(alcmap); @@ -751,6 +794,10 @@ public class Jalview2XML } // SAVE ANNOTATIONS + /** + * store forward refs from an annotationRow to any groups + */ + IdentityHashMap groupRefs = new IdentityHashMap(); if (jal.getAlignmentAnnotation() != null) { jalview.datamodel.AlignmentAnnotation[] aa = jal @@ -767,15 +814,6 @@ public class Jalview2XML an.setId(aa[i].annotationId); - if (aa[i] == av.quality || aa[i] == av.conservation - || aa[i] == av.consensus) - { - an.setLabel(aa[i].label); - an.setGraph(true); - vamsasSet.addAnnotation(an); - continue; - } - an.setVisible(aa[i].visible); an.setDescription(aa[i].description); @@ -786,7 +824,25 @@ public class Jalview2XML // 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); @@ -807,6 +863,13 @@ public class Jalview2XML } an.setLabel(aa[i].label); + + if (aa[i] == av.quality || aa[i] == av.conservation + || aa[i] == av.consensus || aa[i].autoCalculated) + { + // new way of indicating autocalculated annotation - + an.setAutoCalculated(aa[i].autoCalculated); + } if (aa[i].hasScore()) { an.setScore(aa[i].getScore()); @@ -834,9 +897,8 @@ public class Jalview2XML ae.setPosition(a); if (aa[i].annotations[a].secondaryStructure != ' ' && aa[i].annotations[a].secondaryStructure != '\0') - ae - .setSecondaryStructure(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) @@ -845,6 +907,11 @@ public class Jalview2XML } 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 @@ -854,7 +921,6 @@ public class Jalview2XML vamsasSet.addAnnotation(an); } } - // SAVE GROUPS if (jal.getGroups() != null) { @@ -868,9 +934,12 @@ public class Jalview2XML .getGroups().elementAt(i); groups[i].setStart(sg.getStartRes()); groups[i].setEnd(sg.getEndRes()); - groups[i].setName(sg.getName()); // TODO later sequence group should - // specify IDs of sequences, not just - // names + groups[i].setName(sg.getName()); + if (groupRefs.containsKey(sg)) + { + // group has references so set it's ID field + groups[i].setId(groupRefs.get(sg).toString()); + } if (sg.cs != null) { if (sg.cs.conservationApplied()) @@ -915,7 +984,10 @@ public class Jalview2XML groups[i].setTextCol1(sg.textColour.getRGB()); groups[i].setTextCol2(sg.textColour2.getRGB()); groups[i].setTextColThreshold(sg.thresholdTextColour); - groups[i].setShowUnconserved(sg.getShowunconserved()); + groups[i].setShowUnconserved(sg.getShowNonconserved()); + groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus()); + groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram()); + groups[i].setShowSequenceLogo(sg.isShowSequenceLogo()); for (int s = 0; s < sg.getSize(); s++) { jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg @@ -930,8 +1002,8 @@ public class Jalview2XML // /////////SAVE VIEWPORT Viewport view = new Viewport(); view.setTitle(ap.alignFrame.getTitle()); - view.setSequenceSetId(makeHashCode(av.getSequenceSetId(), av - .getSequenceSetId())); + view.setSequenceSetId(makeHashCode(av.getSequenceSetId(), + av.getSequenceSetId())); view.setId(av.getViewId()); view.setViewName(av.viewName); view.setGatheredViews(av.gatherViewsHere); @@ -1027,7 +1099,15 @@ public class Jalview2XML 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(); @@ -1035,12 +1115,31 @@ public class Jalview2XML String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder; Vector settingsAdded = new Vector(); + Object gstyle = null; + GraduatedColor gcol = null; for (int ro = 0; ro < renderOrder.length; ro++) { + gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer() + .getFeatureStyle(renderOrder[ro]); Setting setting = new Setting(); setting.setType(renderOrder[ro]); - setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer() - .getColour(renderOrder[ro]).getRGB()); + 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])); @@ -1091,10 +1190,8 @@ public class Jalview2XML } Group g = new Group(); g.setName(grp); - g - .setDisplay(((Boolean) ap.seqPanel.seqCanvas - .getFeatureRenderer().featureGroups.get(grp)) - .booleanValue()); + g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups + .get(grp)).booleanValue()); fs.addGroup(g); groupsAdded.addElement(grp); } @@ -1104,14 +1201,23 @@ public class Jalview2XML if (av.hasHiddenColumns) { - for (int c = 0; c < av.getColumnSelection().getHiddenColumns().size(); c++) + if (av.getColumnSelection() == null + || av.getColumnSelection().getHiddenColumns() == null) + { + warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this."); + } + else { - int[] region = (int[]) av.getColumnSelection().getHiddenColumns() - .elementAt(c); - HiddenColumns hc = new HiddenColumns(); - hc.setStart(region[0]); - hc.setEnd(region[1]); - view.addHiddenColumns(hc); + 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); + } } } @@ -1158,7 +1264,7 @@ public class Jalview2XML * exist, the result of the hashcode call for the object. * * @param jvobj - * jalview data object + * jalview data object * @return unique ID for referring to jvobj */ private String makeHashCode(Object jvobj, String altCode) @@ -1189,7 +1295,7 @@ public class Jalview2XML * return local jalview object mapped to ID, if it exists * * @param idcode - * (may be null) + * (may be null) * @return null or object bound to idcode */ private Object retrieveExistingObj(String idcode) @@ -1328,11 +1434,16 @@ public class Jalview2XML { String id = null; jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs; - + boolean newucs = false; if (!userColours.contains(ucs)) { userColours.add(ucs); - + newucs = true; + } + id = "ucs" + userColours.indexOf(ucs); + if (newucs) + { + // actually create the scheme's entry in the XML model java.awt.Color[] colours = ucs.getColours(); jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours(); jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme(); @@ -1356,7 +1467,6 @@ public class Jalview2XML } } - id = "ucs" + userColours.indexOf(ucs); uc.setId(id); uc.setUserColourScheme(jbucs); jms.addUserColours(uc); @@ -1420,8 +1530,8 @@ public class Jalview2XML /** * Load a jalview project archive from a jar file * - * @param file - - * HTTP URL or filename + * @param file + * - HTTP URL or filename */ public AlignFrame LoadJalviewAlign(final String file) { @@ -1597,8 +1707,10 @@ public class Jalview2XML + ex + "\n"); } catch (OutOfMemoryError e) { - new jalview.gui.OOMWarning("loading jalview XML file", e, - Desktop.instance); + // Don't use the OOM Window here + errorMessage = "Out of memory loading jalview XML file"; + System.err.println("Out of memory whilst loading jalview XML file"); + e.printStackTrace(); } if (Desktop.instance != null) @@ -1721,17 +1833,36 @@ public class Jalview2XML return null; } + private class JvAnnotRow + { + public JvAnnotRow(int i, AlignmentAnnotation jaa) + { + order = i; + template = jaa; + } + + /** + * persisted version of annotation row from which to take vis properties + */ + public jalview.datamodel.AlignmentAnnotation template; + + /** + * original position of the annotation row in the alignment + */ + public int order; + } + /** * Load alignment frame from jalview XML DOM object * * @param object - * DOM + * DOM * @param file - * filename source string + * filename source string * @param loadTreesAndStructures - * when false only create Viewport + * when false only create Viewport * @param jprovider - * data source provider + * data source provider * @return alignment frame created from view stored in DOM */ AlignFrame LoadFromObject(JalviewModel object, String file, @@ -1905,14 +2036,17 @@ public class Jalview2XML Alcodon[] alcods = alc[i].getAlcodon(); for (int p = 0; p < cf.codons.length; p++) { - if (alcods[p].hasPos1() && alcods[p].hasPos2() && alcods[p].hasPos3()) + if (alcods[p].hasPos1() && alcods[p].hasPos2() + && alcods[p].hasPos3()) { // translated codons require three valid positions cf.codons[p] = new int[3]; cf.codons[p][0] = (int) alcods[p].getPos1(); cf.codons[p][1] = (int) alcods[p].getPos2(); cf.codons[p][2] = (int) alcods[p].getPos3(); - } else { + } + else + { cf.codons[p] = null; } } @@ -1950,7 +2084,11 @@ public class Jalview2XML // //////////////////////////////// // LOAD ANNOTATIONS - boolean hideQuality = true, hideConservation = true, hideConsensus = true; + ArrayList autoAlan = new ArrayList(); + /** + * store any annotations which forward reference a group's ID + */ + Hashtable> groupAnnotRefs = new Hashtable>(); if (vamsasSet.getAnnotationCount() > 0) { @@ -1958,22 +2096,27 @@ public class Jalview2XML for (int i = 0; i < an.length; i++) { - // set visibility for automatic annotation for this view - if (an[i].getLabel().equals("Quality")) - { - hideQuality = false; - continue; - } - else if (an[i].getLabel().equals("Conservation")) - { - hideConservation = false; - continue; + /** + * test if annotation is automatically calculated for this view only + */ + boolean autoForView = false; + if (an[i].getLabel().equals("Quality") + || an[i].getLabel().equals("Conservation") + || an[i].getLabel().equals("Consensus")) + { + // Kludge for pre 2.5 projects which lacked the autocalculated flag + autoForView = true; + if (!an[i].hasAutoCalculated()) + { + an[i].setAutoCalculated(true); + } } - else if (an[i].getLabel().equals("Consensus")) - { - hideConsensus = false; - continue; + if (autoForView || (an[i].hasAutoCalculated() && an[i].isAutoCalculated())) { + // remove ID - we don't recover annotation from other views for + // view-specific annotation + an[i].setId(null); } + // set visiblity for other annotation in this view if (an[i].getId() != null && annotationIds.containsKey(an[i].getId())) @@ -1996,7 +2139,6 @@ public class Jalview2XML 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) @@ -2004,10 +2146,11 @@ public class Jalview2XML anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation( - ae[aa].getDisplayCharacter(), ae[aa].getDescription(), (ae[aa] - .getSecondaryStructure() == null || ae[aa] - .getSecondaryStructure().length() == 0) ? ' ' : ae[aa] - .getSecondaryStructure().charAt(0), ae[aa].getValue() + ae[aa].getDisplayCharacter(), ae[aa].getDescription(), + (ae[aa].getSecondaryStructure() == null || ae[aa] + .getSecondaryStructure().length() == 0) ? ' ' + : ae[aa].getSecondaryStructure().charAt(0), + ae[aa].getValue() ); // JBPNote: Consider verifying dataflow for IO of secondary @@ -2017,16 +2160,20 @@ public class Jalview2XML // { // anot[ae[aa].getPosition()].displayCharacter = ""; // } - anot[ae[aa].getPosition()].colour = new java.awt.Color(ae[aa] - .getColour()); + anot[ae[aa].getPosition()].colour = new java.awt.Color( + ae[aa].getColour()); } } jalview.datamodel.AlignmentAnnotation jaa = null; if (an[i].getGraph()) { + float llim=0,hlim=0; + // if (autoForView || an[i].isAutoCalculated()) { + // hlim=11f; + // } jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(), - an[i].getDescription(), anot, 0, 0, an[i].getGraphType()); + an[i].getDescription(), anot, llim, hlim, an[i].getGraphType()); jaa.graphGroup = an[i].getGraphGroup(); @@ -2038,38 +2185,81 @@ public class Jalview2XML an[i].getThresholdLine().getColour()))); } - + if (autoForView || an[i].isAutoCalculated()) { + // Hardwire the symbol display line to ensure that labels for histograms are displayed + jaa.hasText=true; + } } else { jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(), an[i].getDescription(), anot); } - // register new annotation - if (an[i].getId() != null) + if (autoForView) { - annotationIds.put(an[i].getId(), jaa); - jaa.annotationId = an[i].getId(); + // 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) + { + if (al.findName(an[i].getSequenceRef()) != null) + { + jaa.createSequenceMapping( + al.findName(an[i].getSequenceRef()), 1, true); + al.findName(an[i].getSequenceRef()).addAlignmentAnnotation( + jaa); + } + } } - // recover sequence association - if (an[i].getSequenceRef() != null) + // and make a note of any group association + if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0) { - if (al.findName(an[i].getSequenceRef()) != null) - { - jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()), - 1, true); - al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa); + ArrayList aal=groupAnnotRefs.get(an[i].getGroupRef()); + if (aal==null) { + aal = new ArrayList(); + groupAnnotRefs.put(an[i].getGroupRef(),aal); } + aal.add(jaa); } + if (an[i].hasScore()) { jaa.setScore(an[i].getScore()); } - if (an[i].hasVisible()) jaa.visible = an[i].getVisible(); - al.addAnnotation(jaa); + if (an[i].hasCentreColLabels()) + jaa.centreColLabels = an[i].getCentreColLabels(); + + if (an[i].hasScaleColLabels()) + { + jaa.scaleColLabel = an[i].getScaleColLabels(); + } + if (an[i].hasAutoCalculated() && an[i].isAutoCalculated()) + { + // newer files have an 'autoCalculated' flag and store calculation + // state in viewport properties + jaa.autoCalculated = true; // means annotation will be marked for + // update at end of load. + } + if (an[i].hasGraphHeight()) + { + jaa.graphHeight = an[i].getGraphHeight(); + } + if (jaa.autoCalculated) + { + autoAlan.add(new JvAnnotRow(i, jaa)); + } else + // if (!autoForView) + { + // add autocalculated group annotation and any user created annotation for the view + al.addAnnotation(jaa); + } } } @@ -2125,26 +2315,61 @@ public class Jalview2XML groups[i].getDisplayText(), groups[i].getColourText(), groups[i].getStart(), groups[i].getEnd()); - sg - .setOutlineColour(new java.awt.Color(groups[i] - .getOutlineColour())); + sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour())); sg.textColour = new java.awt.Color(groups[i].getTextCol1()); sg.textColour2 = new java.awt.Color(groups[i].getTextCol2()); - sg.setShowunconserved(groups[i].hasShowUnconserved() ? groups[i].isShowUnconserved() : false); + sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i] + .isShowUnconserved() : false); sg.thresholdTextColour = groups[i].getTextColThreshold(); - + if (groups[i].hasShowConsensusHistogram()) + { + sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram()); + } + ; + if (groups[i].hasShowSequenceLogo()) + { + sg.setshowSequenceLogo(groups[i].isShowSequenceLogo()); + } + if (groups[i].hasIgnoreGapsinConsensus()) + { + sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus()); + } if (groups[i].getConsThreshold() != 0) { jalview.analysis.Conservation c = new jalview.analysis.Conservation( - "All", ResidueProperties.propHash, 3, sg - .getSequences(null), 0, sg.getWidth() - 1); + "All", ResidueProperties.propHash, 3, + sg.getSequences(null), 0, sg.getWidth() - 1); c.calculate(); c.verdict(false, 25); sg.cs.setConservation(c); } + if (groups[i].getId() != null && groupAnnotRefs.size() > 0) + { + // re-instate unique group/annotation row reference + ArrayList jaal = groupAnnotRefs + .get(groups[i].getId()); + if (jaal != null) + { + for (jalview.datamodel.AlignmentAnnotation jaa:jaal) { + jaa.groupRef = sg; + if (jaa.autoCalculated) + { + // match up and try to set group autocalc alignment row for this annotation + if (jaa.label.startsWith("Consensus for ")) { + sg.setConsensus(jaa); + } + // match up and try to set group autocalc alignment row for this annotation + if (jaa.label.startsWith("Conservation for ")) { + sg.setConservationRow(jaa); + } + } + } + } + } al.addGroup(sg); + } } @@ -2218,9 +2443,8 @@ public class Jalview2XML if (isnewview) { - af = loadViewport(file, JSEQ, hiddenSeqs, al, hideConsensus, - hideQuality, hideConservation, jms, view, uniqueSeqSetId, - viewId); + af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view, + uniqueSeqSetId, viewId, autoAlan); av = af.viewport; ap = af.alignPanel; } @@ -2238,17 +2462,20 @@ public class Jalview2XML TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId()); if (tp == null) { - tp = af.ShowNewickTree(new jalview.io.NewickFile(tree - .getNewick()), tree.getTitle(), tree.getWidth(), tree - .getHeight(), tree.getXpos(), tree.getYpos()); + tp = af.ShowNewickTree( + new jalview.io.NewickFile(tree.getNewick()), + tree.getTitle(), tree.getWidth(), tree.getHeight(), + tree.getXpos(), tree.getYpos()); if (tree.getId() != null) { - + // perhaps bind the tree id to something ? } } else { // update local tree attributes ? + // TODO: should check if tp has been manipulated by user - if so its + // settings shouldn't be modified tp.setTitle(tree.getTitle()); tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree .getWidth(), tree.getHeight())); @@ -2259,9 +2486,10 @@ public class Jalview2XML tp.treeCanvas.ap = ap; // af.alignPanel; } - if (tp==null) + if (tp == null) { - warn("There was a problem recovering stored Newick tree: \n"+tree.getNewick()); + warn("There was a problem recovering stored Newick tree: \n" + + tree.getNewick()); continue; } @@ -2300,6 +2528,10 @@ public class Jalview2XML // //LOAD STRUCTURES if (loadTreesAndStructures) { + // run through all PDB ids on the alignment, and collect mappings between + // jmol view ids and all sequences referring to it + Hashtable jmolViewIds = new Hashtable(); + for (int i = 0; i < JSEQ.length; i++) { if (JSEQ[i].getPdbidsCount() > 0) @@ -2324,100 +2556,325 @@ public class Jalview2XML int y = ids[p].getStructureState(s).getYpos(); int width = ids[p].getStructureState(s).getWidth(); int height = ids[p].getStructureState(s).getHeight(); - AppJmol comp = null; - JInternalFrame[] frames = null; - do + + // Probably don't need to do this anymore... + // Desktop.desktop.getComponentAt(x, y); + // TODO: NOW: check that this recovers the PDB file correctly. + String pdbFile = loadPDBFile(jprovider, ids[p].getId()); + jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds + .get(JSEQ[i].getId() + ""); + if (sviewid == null) + { + sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width + + "," + height; + } + if (!jmolViewIds.containsKey(sviewid)) + { + jmolViewIds.put(sviewid, new Object[] + { new int[] + { x, y, width, height }, "", + new Hashtable(), new boolean[] + { false, false, true } }); + // Legacy pre-2.7 conversion JAL-823 : + // do not assume any view has to be linked for colour by sequence + } + + // assemble String[] { pdb files }, String[] { id for each + // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, { + // seqs_file 2}, boolean[] { + // linkAlignPanel,superposeWithAlignpanel}} from hash + Object[] jmoldat = (Object[]) jmolViewIds.get(sviewid); + ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s) + .hasAlignwithAlignPanel() ? ids[p].getStructureState( + s).getAlignwithAlignPanel() : false; + // never colour by linked panel if not specified + ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s) + .hasColourwithAlignPanel() ? ids[p] + .getStructureState(s).getColourwithAlignPanel() + : false; + // default for pre-2.7 projects is that Jmol colouring is enabled + ((boolean[])jmoldat[3])[2] &=ids[p].getStructureState(s).hasColourByJmol() ? ids[p].getStructureState(s).getColourByJmol() : true; + + if (((String) jmoldat[1]).length() < ids[p] + .getStructureState(s).getContent().length()) { - try - { - frames = Desktop.desktop.getAllFrames(); - } catch (ArrayIndexOutOfBoundsException e) { - // occasional No such child exceptions are thrown here... - frames = null; - try - { - Thread.sleep(10); - } catch (Exception f) - { - } - ; + jmoldat[1] = ids[p].getStructureState(s).getContent(); } - } while (frames == null); - // search for any Jmol windows already open from other - // alignment views that exactly match the stored structure state - for (int f = 0; comp == null && f < frames.length; f++) + } + if (ids[p].getFile() != null) { - if (frames[f] instanceof AppJmol) + Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2]) + .get(ids[p].getFile()); + if (seqstrmaps == null) { - if (sviewid != null - && ((AppJmol) frames[f]).getViewId().equals( - sviewid)) - { - // post jalview 2.4 schema includes structure view id - comp = (AppJmol) frames[f]; - } - else if (frames[f].getX() == x && frames[f].getY() == y - && frames[f].getHeight() == height - && frames[f].getWidth() == width) - { - comp = (AppJmol) frames[f]; - } + ((Hashtable) jmoldat[2]).put( + new File(ids[p].getFile()).toString(), + seqstrmaps = new Object[] + { pdbFile, ids[p].getId(), new Vector(), + new Vector() }); + } + if (!((Vector) seqstrmaps[2]).contains(seq)) + { + ((Vector) seqstrmaps[2]).addElement(seq); + // ((Vector)seqstrmaps[3]).addElement(n) : + // in principle, chains + // should be stored here : do we need to + // TODO: store and recover seq/pdb_id : + // chain mappings } } - Desktop.desktop.getComponentAt(x, y); - - String pdbFile = loadPDBFile(jprovider, ids[p].getId()); + else + { + errorMessage=("The Jmol views in the Jalview 2 project may\nnot be correctly bound to sequences in the alignment.\nIn the case of problems, see note at\nhttp://issues.jalview.org/browse/JAL-747"); + warn(errorMessage); + } + } + } + } + } + { - jalview.datamodel.SequenceI[] seq = new jalview.datamodel.SequenceI[] - { (jalview.datamodel.SequenceI) seqRefIds.get(JSEQ[i].getId() - + "") }; + // Instantiate the associated Jmol views + for (Entry entry : jmolViewIds.entrySet()) + { + String sviewid = entry.getKey(); + Object[] svattrib = entry.getValue(); + int[] geom = (int[]) svattrib[0]; + String state = (String) svattrib[1]; + 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 + Vector pdbfilenames = new Vector(); + Vector seqmaps = new Vector(); + Vector pdbids = new Vector(); - if (comp == null) + // Search to see if we've already created this Jmol view + AppJmol comp = null; + JInternalFrame[] frames = null; + do + { + try + { + frames = Desktop.desktop.getAllFrames(); + } catch (ArrayIndexOutOfBoundsException e) + { + // occasional No such child exceptions are thrown here... + frames = null; + try { - // create a new Jmol window - String state = ids[p].getStructureState(s).getContent(); - - StringBuffer newFileLoc = new StringBuffer(state.substring( - 0, state.indexOf("\"", state.indexOf("load")) + 1)); + Thread.sleep(10); + } catch (Exception f) + { + } + ; + } + } while (frames == null); + // search for any Jmol windows already open from other + // alignment views that exactly match the stored structure state + for (int f = 0; comp == null && f < frames.length; f++) + { + if (frames[f] instanceof AppJmol) + { + if (sviewid != null + && ((AppJmol) frames[f]).getViewId().equals(sviewid)) + { + // post jalview 2.4 schema includes structure view id + comp = (AppJmol) frames[f]; + } + else if (frames[f].getX() == x && frames[f].getY() == y + && frames[f].getHeight() == height + && frames[f].getWidth() == width) + { + comp = (AppJmol) frames[f]; + } + } + } - newFileLoc.append(jpdb.getFile()); - newFileLoc.append(state.substring(state.indexOf("\"", state - .indexOf("load \"") + 6))); + if (comp == null) + { + // create a new Jmol window. + // First parse the Jmol state to translate filenames loaded into the + // view, and record the order in which files are shown in the Jmol + // view, so we can add the sequence mappings in same order. + StringBuffer newFileLoc = null; + int cp = 0, ncp, ecp; + while ((ncp = state.indexOf("load ", cp)) > -1) + { + if (newFileLoc == null) + { + 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. + } + if (cp > 0) + { + // just append rest of state + newFileLoc.append(state.substring(cp)); + } + else + { + System.err + .print("Ignoring incomplete Jmol state for PDB ids: "); + newFileLoc = new StringBuffer(state); + newFileLoc.append("; load append "); + for (String id : oldFiles.keySet()) + { + // add this and any other pdb files that should be present in + // the viewer + Object[] filedat = oldFiles.get(id); + String nfilename; + 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(" \""); + newFileLoc.append((String) filedat[0]); + newFileLoc.append("\""); - new AppJmol(pdbFile, ids[p].getId(), seq, af.alignPanel, - newFileLoc.toString(), new java.awt.Rectangle(x, y, - width, height), sviewid); + } + newFileLoc.append(";"); + } + if (newFileLoc != null) + { + int histbug = newFileLoc.indexOf("history = "); + histbug += 10; + int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", + histbug); + String val = (diff == -1) ? null : newFileLoc.substring( + histbug, diff); + if (val != null && val.length() >= 4) + { + if (val.contains("e")) + { + if (val.trim().equals("true")) + { + val = "1"; + } + else + { + val = "0"; + } + newFileLoc.replace(histbug, diff, val); + } } - else - // if (comp != null) + // 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 + .toArray(new String[pdbids.size()]); + final SequenceI[][] sq = (SequenceI[][]) seqmaps + .toArray(new SequenceI[seqmaps.size()][]); + final String fileloc = newFileLoc.toString(), vid = sviewid; + final AlignFrame alf = af; + final java.awt.Rectangle rect = new java.awt.Rectangle(x, y, + width, height); + try { - // NOTE: if the jalview project is part of a shared session then - // view synchronization should/could be done here. - - // add mapping for this sequence to the already open Jmol - // instance (if it doesn't already exist) - // These - StructureSelectionManager.getStructureSelectionManager() - .setMapping(seq, null, pdbFile, - jalview.io.AppletFormatAdapter.FILE); + javax.swing.SwingUtilities.invokeAndWait(new Runnable() + { + public void run() + { + AppJmol sview = null; + try + { + sview = new AppJmol(pdbf, id, sq, alf.alignPanel, + useinJmolsuperpos, usetoColourbyseq, jmolColouring, fileloc, + rect, vid); + } catch (OutOfMemoryError ex) + { + new OOMWarning("restoring structure view for PDB id " + + id, (OutOfMemoryError) ex.getCause()); + if (sview != null && sview.isVisible()) + { + sview.closeViewer(); + sview.setVisible(false); + sview.dispose(); + } + } + } + }); + } catch (InvocationTargetException ex) + { + warn("Unexpected error when opening Jmol view.", ex); - ((AppJmol) comp).addSequence(seq); + } catch (InterruptedException e) + { + // e.printStackTrace(); } } + + } + else + // if (comp != null) + { + // NOTE: if the jalview project is part of a shared session then + // view synchronization should/could be done here. + + // add mapping for sequences in this view to an already open Jmol + // instance + for (String 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]) + .toArray(new SequenceI[0]); + ((AppJmol) comp).jmb.ssm.setMapping(seq, null, pdbFile, + jalview.io.AppletFormatAdapter.FILE); + ((AppJmol) comp).jmb.addSequenceForStructFile(pdbFile, seq); + } + // and add the AlignmentPanel's reference to the Jmol view + ((AppJmol) comp).addAlignmentPanel(ap); + if (useinJmolsuperpos) + { + ((AppJmol) comp).useAlignmentPanelForSuperposition(ap); + } + else + { + ((AppJmol) comp).excludeAlignmentPanelForSuperposition(ap); + } + if (usetoColourbyseq) + { + ((AppJmol) comp).useAlignmentPanelForColourbyseq(ap, !jmolColouring); + } + else + { + ((AppJmol) comp).excludeAlignmentPanelForColourbyseq(ap); + } } } } } - + // and finally return. return af; } AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs, - Alignment al, boolean hideConsensus, boolean hideQuality, - boolean hideConservation, JalviewModelSequence jms, - Viewport view, String uniqueSeqSetId, String viewId) + Alignment al, JalviewModelSequence jms, Viewport view, + String uniqueSeqSetId, String viewId, + ArrayList autoAlan) { AlignFrame af = null; af = new AlignFrame(al, view.getWidth(), view.getHeight(), @@ -2462,8 +2919,8 @@ public class Jalview2XML for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++) { - hidden.addSequence(al - .getSequenceAt(JSEQ[s].getHiddenSequences(r)), false); + hidden.addSequence( + al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false); } af.viewport.hideRepSequences(al.getSequenceAt(s), hidden); } @@ -2479,35 +2936,14 @@ public class Jalview2XML af.viewport.hideSequence(hseqs); } - // set visibility of annotation in view - if ((hideConsensus || hideQuality || hideConservation) - && al.getAlignmentAnnotation() != null) - { - int hSize = al.getAlignmentAnnotation().length; - for (int h = 0; h < hSize; h++) - { - if ((hideConsensus && al.getAlignmentAnnotation()[h].label - .equals("Consensus")) - || (hideQuality && al.getAlignmentAnnotation()[h].label - .equals("Quality")) - || (hideConservation && al.getAlignmentAnnotation()[h].label - .equals("Conservation"))) - { - al.deleteAnnotation(al.getAlignmentAnnotation()[h]); - hSize--; - h--; - } - } - af.alignPanel.adjustAnnotationHeight(); - } // recover view properties and display parameters if (view.getViewName() != null) { af.viewport.viewName = view.getViewName(); af.setInitialTabVisible(); } - af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(), view - .getHeight()); + af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(), + view.getHeight()); af.viewport.setShowAnnotation(view.getShowAnnotation()); af.viewport.setAbovePIDThreshold(view.getPidSelected()); @@ -2533,7 +2969,8 @@ public class Jalview2XML af.viewport.textColour = new java.awt.Color(view.getTextCol1()); af.viewport.textColour2 = new java.awt.Color(view.getTextCol2()); af.viewport.thresholdTextColour = view.getTextColThreshold(); - af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view.isShowUnconserved() : false); + af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view + .isShowUnconserved() : false); af.viewport.setStartRes(view.getStartRes()); af.viewport.setStartSeq(view.getStartSeq()); @@ -2548,85 +2985,91 @@ public class Jalview2XML else if (view.getBgColour().startsWith("Annotation")) { // int find annotation - for (int i = 0; i < af.viewport.alignment.getAlignmentAnnotation().length; i++) + if (af.viewport.alignment.getAlignmentAnnotation() != null) { - if (af.viewport.alignment.getAlignmentAnnotation()[i].label - .equals(view.getAnnotationColours().getAnnotation())) + for (int i = 0; i < af.viewport.alignment + .getAlignmentAnnotation().length; i++) { - if (af.viewport.alignment.getAlignmentAnnotation()[i] - .getThreshold() == null) + if (af.viewport.alignment.getAlignmentAnnotation()[i].label + .equals(view.getAnnotationColours().getAnnotation())) { - af.viewport.alignment.getAlignmentAnnotation()[i] - .setThreshold(new jalview.datamodel.GraphLine(view - .getAnnotationColours().getThreshold(), - "Threshold", java.awt.Color.black) - - ); - } + if (af.viewport.alignment.getAlignmentAnnotation()[i] + .getThreshold() == null) + { + af.viewport.alignment.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.alignment - .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.alignment - .getAlignmentAnnotation()[i], GetUserColourScheme( - jms, view.getAnnotationColours().getColourScheme()), - view.getAnnotationColours().getAboveThreshold()); - } - else - { - cs = new AnnotationColourGradient(af.viewport.alignment - .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++) + if (view.getAnnotationColours().getColourScheme() + .equals("None")) { - jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al - .getGroups().elementAt(g); + cs = new AnnotationColourGradient( + af.viewport.alignment.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.alignment.getAlignmentAnnotation()[i], + GetUserColourScheme(jms, view + .getAnnotationColours().getColourScheme()), + view.getAnnotationColours().getAboveThreshold()); + } + else + { + cs = new AnnotationColourGradient( + af.viewport.alignment.getAlignmentAnnotation()[i], + ColourSchemeProperty.getColour(al, view + .getAnnotationColours().getColourScheme()), + view.getAnnotationColours().getAboveThreshold()); + } - if (sg.cs == null) + // Also use these settings for all the groups + if (al.getGroups() != null) + { + for (int g = 0; g < al.getGroups().size(); g++) { - continue; - } + jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al + .getGroups().elementAt(g); - /* - * if - * (view.getAnnotationColours().getColourScheme().equals("None")) { - * sg.cs = new AnnotationColourGradient( - * af.viewport.alignment.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.alignment.getAlignmentAnnotation()[i], - sg.cs, view.getAnnotationColours() - .getAboveThreshold()); - } + if (sg.cs == null) + { + continue; + } + + /* + * if + * (view.getAnnotationColours().getColourScheme().equals("None" + * )) { sg.cs = new AnnotationColourGradient( + * af.viewport.alignment.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.alignment.getAlignmentAnnotation()[i], + sg.cs, view.getAnnotationColours() + .getAboveThreshold()); + } + } } + + break; } - break; } - } } else @@ -2657,6 +3100,65 @@ public class Jalview2XML { af.viewport.showSequenceFeatures = true; } + if (view.hasCentreColumnLabels()) + { + af.viewport.setCentreColumnLabels(view.getCentreColumnLabels()); + } + if (view.hasIgnoreGapsinConsensus()) + { + af.viewport.ignoreGapsInConsensusCalculation = view + .getIgnoreGapsinConsensus(); + } + if (view.hasFollowHighlight()) + { + af.viewport.followHighlight = view.getFollowHighlight(); + } + if (view.hasFollowSelection()) + { + af.viewport.followSelection = view.getFollowSelection(); + } + if (view.hasShowConsensusHistogram()) + { + af.viewport.setShowConsensusHistogram(view + .getShowConsensusHistogram()); + } + else + { + af.viewport.setShowConsensusHistogram(true); + } + if (view.hasShowSequenceLogo()) + { + af.viewport.showSequenceLogo = view.getShowSequenceLogo(); + } + else + { + af.viewport.showSequenceLogo = false; + } + if (view.hasShowDbRefTooltip()) + { + af.viewport.setShowDbRefs(view.getShowDbRefTooltip()); + } + if (view.hasShowNPfeatureTooltip()) + { + af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip()); + } + if (view.hasShowGroupConsensus()) + { + af.viewport.setShowGroupConsensus(view.getShowGroupConsensus()); + } + else + { + af.viewport.setShowGroupConsensus(false); + } + if (view.hasShowGroupConservation()) + { + af.viewport.setShowGroupConservation(view.getShowGroupConservation()); + } + else + { + af.viewport.setShowGroupConservation(false); + } + // recover featre settings if (jms.getFeatureSettings() != null) { @@ -2668,16 +3170,35 @@ public class Jalview2XML Setting setting = jms.getFeatureSettings().getSetting(fs); if (setting.hasMincolour()) { - // TODO: determine how to set data independent bounds for a graduated colour scheme's range. - GraduatedColor gc = new GraduatedColor(new java.awt.Color(setting.getMincolour()), new java.awt.Color(setting.getColour()), - 0,1); - if (setting.hasThreshold()) { + GraduatedColor gc = setting.hasMin() ? new GraduatedColor( + new java.awt.Color(setting.getMincolour()), + new java.awt.Color(setting.getColour()), + setting.getMin(), setting.getMax()) : new GraduatedColor( + new java.awt.Color(setting.getMincolour()), + new java.awt.Color(setting.getColour()), 0, 1); + if (setting.hasThreshold()) + { gc.setThresh(setting.getThreshold()); gc.setThreshType(setting.getThreshstate()); } - } else { + gc.setAutoScaled(true); // default + if (setting.hasAutoScale()) + { + gc.setAutoScaled(setting.getAutoScale()); + } + if (setting.hasColourByLabel()) + { + gc.setColourByLabel(setting.getColourByLabel()); + } + // and put in the feature colour table. af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour( - setting.getType(), new java.awt.Color(setting.getColour())); + setting.getType(), gc); + } + else + { + af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour( + setting.getType(), + new java.awt.Color(setting.getColour())); } renderOrder[fs] = setting.getType(); if (setting.hasOrder()) @@ -2715,11 +3236,85 @@ public class Jalview2XML 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()); + Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), + view.getHeight()); + af.alignPanel.updateAnnotation(false); // recompute any autoannotation + reorderAutoannotation(af,al,autoAlan); return af; } + private void reorderAutoannotation(AlignFrame af, Alignment al, + ArrayList autoAlan) + { + // copy over visualization settings for autocalculated annotation in the + // view + if (al.getAlignmentAnnotation() != null) + { + /** + * Kludge for magic autoannotation names (see JAL-811) + */ + String[] magicNames = new String[] + { "Consensus", "Quality", "Conservation" }; + JvAnnotRow nullAnnot = new JvAnnotRow(-1, null); + Hashtable visan = new Hashtable(); + for (String nm : magicNames) + { + visan.put(nm, nullAnnot); + } + for (JvAnnotRow auan : autoAlan) + { + visan.put(auan.template.label, auan); + } + int hSize = al.getAlignmentAnnotation().length; + ArrayList reorder = new ArrayList(); + for (int h = 0; h < hSize; h++) + { + jalview.datamodel.AlignmentAnnotation jalan = al + .getAlignmentAnnotation()[h]; + if (jalan.autoCalculated) + { + JvAnnotRow valan = visan.get(jalan.label); + if (valan != null) + { + // delete the auto calculated row from the alignment + al.deleteAnnotation(al.getAlignmentAnnotation()[h],false); + hSize--; + h--; + if (valan != nullAnnot) + { + if (jalan!=valan.template) { + // newly created autoannotation row instance + // so keep a reference to the visible annotation row + // and copy over all relevant attributes + if (valan.template.graphHeight >= 0) + + { + jalan.graphHeight = valan.template.graphHeight; + } + jalan.visible = valan.template.visible; + } + reorder.add(new JvAnnotRow(valan.order, jalan)); + } + } + } + } + int s=0,srt[] = new int[reorder.size()]; + JvAnnotRow[] rws = new JvAnnotRow[reorder.size()]; + for (JvAnnotRow jvar:reorder) { + rws[s] = jvar; + srt[s++]=jvar.order; + } + reorder.clear(); + jalview.util.QuickSort.sort(srt, rws); + // and re-insert the annotation at its correct position + for (JvAnnotRow jvar : rws) + { + al.addAnnotation(jvar.template, jvar.order); + } + af.alignPanel.adjustAnnotationHeight(); + } + } + Hashtable skipList = null; /** @@ -2796,6 +3391,8 @@ public class Jalview2XML SequenceI[] dsseqs = new SequenceI[dseqs.size()]; dseqs.copyInto(dsseqs); ds = new jalview.datamodel.Alignment(dsseqs); + debug("Created new dataset " + vamsasSet.getDatasetId() + + " for alignment " + System.identityHashCode(al)); addDatasetRef(vamsasSet.getDatasetId(), ds); } // set the dataset for the newly imported alignment. @@ -2808,11 +3405,11 @@ public class Jalview2XML /** * * @param vamsasSeq - * sequence definition to create/merge dataset sequence for + * sequence definition to create/merge dataset sequence for * @param ds - * dataset alignment + * dataset alignment * @param dseqs - * vector to add new dataset sequence to + * vector to add new dataset sequence to */ private void ensureJalviewDatasetSequence(Sequence vamsasSeq, AlignmentI ds, Vector dseqs) @@ -2902,7 +3499,9 @@ public class Jalview2XML } java.util.Hashtable datasetIds = null; + java.util.IdentityHashMap dataset2Ids = null; + private Alignment getDatasetFor(String datasetId) { if (datasetIds == null) @@ -2925,35 +3524,40 @@ public class Jalview2XML } datasetIds.put(datasetId, dataset); } + /** * make a new dataset ID for this jalview dataset alignment + * * @param dataset * @return */ private String getDatasetIdRef(jalview.datamodel.Alignment dataset) { - if (dataset.getDataset()!=null) + if (dataset.getDataset() != null) { warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment..."); } - String datasetId=makeHashCode(dataset, null); - if (datasetId==null) + String datasetId = makeHashCode(dataset, null); + if (datasetId == null) { // make a new datasetId and record it if (dataset2Ids == null) { dataset2Ids = new IdentityHashMap(); - } else { + } + else + { datasetId = (String) dataset2Ids.get(dataset); } - if (datasetId==null) + if (datasetId == null) { - datasetId = "ds"+dataset2Ids.size()+1; - dataset2Ids.put(dataset,datasetId); + datasetId = "ds" + dataset2Ids.size() + 1; + dataset2Ids.put(dataset, datasetId); } } return datasetId; } + private void addDBRefs(SequenceI datasetSequence, Sequence sequence) { for (int d = 0; d < sequence.getDBRefCount(); d++) @@ -2997,7 +3601,7 @@ public class Jalview2XML MappingChoice mc = m.getMappingChoice(); if (mc.getDseqFor() != null) { - String dsfor = ""+mc.getDseqFor(); + String dsfor = "" + mc.getDseqFor(); if (seqRefIds.containsKey(dsfor)) { /** @@ -3040,8 +3644,8 @@ public class Jalview2XML /** * make a new dataset sequence and add it to refIds hash */ - djs = new jalview.datamodel.Sequence(ms.getName(), ms - .getSequence()); + djs = new jalview.datamodel.Sequence(ms.getName(), + ms.getSequence()); djs.setStart(jmap.getMap().getToLowest()); djs.setEnd(jmap.getMap().getToHighest()); djs.setVamsasId(uniqueSetSuffix + sqid); @@ -3073,9 +3677,12 @@ public class Jalview2XML else { uniqueSetSuffix = ""; - jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't overwrite the view we just copied + jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't + // overwrite the + // view we just + // copied } - if (this.frefedSequence==null) + if (this.frefedSequence == null) { frefedSequence = new Vector(); } @@ -3087,8 +3694,9 @@ public class Jalview2XML af.closeMenuItem_actionPerformed(true); /* - * if(ap.av.alignment.getAlignmentAnnotation()!=null) { for(int i=0; i