From: Jim Procter Date: Tue, 23 Aug 2016 10:17:42 +0000 (+0100) Subject: Merge branch 'develop' into bug/JAL-2154projectMappings X-Git-Tag: Release_2_10_0~47^2~4^2~43^2~20 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=72d146eb50571b97a0f1190cbfa01d5d90428764;p=jalview.git Merge branch 'develop' into bug/JAL-2154projectMappings Conflicts: src/jalview/gui/AlignFrame.java - pushed raise warning dialog to CrossRefAction test/jalview/analysis/AlignmentUtilsTests.java - simple merge test/jalview/io/Jalview2xmlTests.java - pushed updated BeforeClass setup to Jalview2xmlBase --- 72d146eb50571b97a0f1190cbfa01d5d90428764 diff --cc src/jalview/gui/CrossRefAction.java index cb315d6,0000000..f0b0891 mode 100644,000000..100644 --- a/src/jalview/gui/CrossRefAction.java +++ b/src/jalview/gui/CrossRefAction.java @@@ -1,305 -1,0 +1,311 @@@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ 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. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.gui; + +import jalview.analysis.AlignmentUtils; +import jalview.analysis.CrossRef; +import jalview.api.AlignmentViewPanel; +import jalview.api.FeatureSettingsModelI; +import jalview.bin.Cache; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.DBRefSource; +import jalview.datamodel.SequenceI; +import jalview.io.gff.SequenceOntologyI; +import jalview.structure.StructureSelectionManager; +import jalview.util.MessageManager; +import jalview.ws.SequenceFetcher; + +import java.util.ArrayList; +import java.util.List; + ++import javax.swing.JOptionPane; ++ +/** + * Factory constructor and runnable for discovering and displaying + * cross-references for a set of aligned sequences + * + * @author jprocter + * + */ +public class CrossRefAction implements Runnable +{ + private AlignFrame alignFrame; + + private SequenceI[] sel; + + private boolean _odna; + + private String source; + + List xrefViews = new ArrayList(); + + public List getXrefViews() + { + return xrefViews; + } + + @Override + public void run() + { + final long sttime = System.currentTimeMillis(); + alignFrame.setProgressBar( + MessageManager.formatMessage( + "status.searching_for_sequences_from", + new Object[] { source }), sttime); + try + { + AlignmentI alignment = alignFrame.getViewport().getAlignment(); + AlignmentI dataset = alignment.getDataset() == null ? alignment + : alignment.getDataset(); + boolean dna = alignment.isNucleotide(); + if (_odna != dna) + { + System.err + .println("Conflict: showProducts for alignment originally " + + "thought to be " + (_odna ? "DNA" : "Protein") + + " now searching for " + (dna ? "DNA" : "Protein") + + " Context."); + } + AlignmentI xrefs = new CrossRef(sel, dataset).findXrefSequences( + source, dna); + if (xrefs == null) + { + return; + } + /* + * get display scheme (if any) to apply to features + */ + FeatureSettingsModelI featureColourScheme = new SequenceFetcher() + .getFeatureColourScheme(source); + + AlignmentI xrefsAlignment = makeCrossReferencesAlignment(dataset, + xrefs); + if (!dna) + { + xrefsAlignment = AlignmentUtils.makeCdsAlignment( + xrefsAlignment.getSequencesArray(), dataset, sel); + xrefsAlignment.alignAs(alignment); + } + + /* + * If we are opening a splitframe, make a copy of this alignment (sharing the same dataset + * sequences). If we are DNA, drop introns and update mappings + */ + AlignmentI copyAlignment = null; + + if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true)) + { + boolean copyAlignmentIsAligned = false; + if (dna) + { + copyAlignment = AlignmentUtils.makeCdsAlignment(sel, dataset, + xrefsAlignment.getSequencesArray()); + if (copyAlignment.getHeight() == 0) + { ++ JOptionPane.showMessageDialog(alignFrame, ++ MessageManager.getString("label.cant_map_cds"), ++ MessageManager.getString("label.operation_failed"), ++ JOptionPane.OK_OPTION); + System.err.println("Failed to make CDS alignment"); + } + + /* + * pending getting Embl transcripts to 'align', + * we are only doing this for Ensembl + */ + // TODO proper criteria for 'can align as cdna' + if (DBRefSource.ENSEMBL.equalsIgnoreCase(source) + || AlignmentUtils.looksLikeEnsembl(alignment)) + { + copyAlignment.alignAs(alignment); + copyAlignmentIsAligned = true; + } + } + else + { + copyAlignment = AlignmentUtils.makeCopyAlignment(sel, + xrefs.getSequencesArray(), dataset); + } + copyAlignment + .setGapCharacter(alignFrame.viewport.getGapCharacter()); + + StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + + /* + * register any new mappings for sequence mouseover etc + * (will not duplicate any previously registered mappings) + */ + ssm.registerMappings(dataset.getCodonFrames()); + + if (copyAlignment.getHeight() <= 0) + { + System.err.println("No Sequences generated for xRef type " + + source); + return; + } + /* + * align protein to dna + */ + if (dna && copyAlignmentIsAligned) + { + xrefsAlignment.alignAs(copyAlignment); + } + else + { + /* + * align cdna to protein - currently only if + * fetching and aligning Ensembl transcripts! + */ + // TODO: generalise for other sources of locus/transcript/cds data + if (dna && DBRefSource.ENSEMBL.equalsIgnoreCase(source)) + { + copyAlignment.alignAs(xrefsAlignment); + } + } + } + /* + * build AlignFrame(s) according to available alignment data + */ + AlignFrame newFrame = new AlignFrame(xrefsAlignment, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + if (Cache.getDefault("HIDE_INTRONS", true)) + { + newFrame.hideFeatureColumns(SequenceOntologyI.EXON, false); + } + String newtitle = String.format("%s %s %s", MessageManager + .getString(dna ? "label.proteins" : "label.nucleotides"), + MessageManager.getString("label.for"), alignFrame.getTitle()); + newFrame.setTitle(newtitle); + + if (copyAlignment == null) + { + /* + * split frame display is turned off in preferences file + */ + Desktop.addInternalFrame(newFrame, newtitle, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + xrefViews.add(newFrame.alignPanel); + return; // via finally clause + } + AlignFrame copyThis = new AlignFrame(copyAlignment, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + copyThis.setTitle(alignFrame.getTitle()); + + boolean showSequenceFeatures = alignFrame.getViewport() + .isShowSequenceFeatures(); + newFrame.setShowSeqFeatures(showSequenceFeatures); + copyThis.setShowSeqFeatures(showSequenceFeatures); + FeatureRenderer myFeatureStyling = alignFrame.alignPanel + .getSeqPanel().seqCanvas.getFeatureRenderer(); + + /* + * copy feature rendering settings to split frame + */ + newFrame.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer() + .transferSettings(myFeatureStyling); + copyThis.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer() + .transferSettings(myFeatureStyling); + + /* + * apply 'database source' feature configuration + * if any was found + */ + // TODO is this the feature colouring for the original + // alignment or the fetched xrefs? either could be Ensembl + newFrame.getViewport().applyFeaturesStyle(featureColourScheme); + copyThis.getViewport().applyFeaturesStyle(featureColourScheme); + + SplitFrame sf = new SplitFrame(dna ? copyThis : newFrame, + dna ? newFrame : copyThis); + newFrame.setVisible(true); + copyThis.setVisible(true); + String linkedTitle = MessageManager + .getString("label.linked_view_title"); + Desktop.addInternalFrame(sf, linkedTitle, -1, -1); + sf.adjustDivider(); + + // finally add the top, then bottom frame to the view list + xrefViews.add(dna ? copyThis.alignPanel : newFrame.alignPanel); + xrefViews.add(!dna ? copyThis.alignPanel : newFrame.alignPanel); + + } catch (OutOfMemoryError e) + { + new OOMWarning("whilst fetching crossreferences", e); + } catch (Throwable e) + { + Cache.log.error("Error when finding crossreferences", e); + } finally + { + alignFrame.setProgressBar(MessageManager.formatMessage( + "status.finished_searching_for_sequences_from", + new Object[] { source }), sttime); + } + } + + /** + * Makes an alignment containing the given sequences, and adds them to the + * given dataset, which is also set as the dataset for the new alignment + * + * TODO: refactor to DatasetI method + * + * @param dataset + * @param seqs + * @return + */ + protected AlignmentI makeCrossReferencesAlignment(AlignmentI dataset, + AlignmentI seqs) + { + SequenceI[] sprods = new SequenceI[seqs.getHeight()]; + for (int s = 0; s < sprods.length; s++) + { + sprods[s] = (seqs.getSequenceAt(s)).deriveSequence(); + if (dataset.getSequences() == null + || !dataset.getSequences().contains( + sprods[s].getDatasetSequence())) + { + dataset.addSequence(sprods[s].getDatasetSequence()); + } + sprods[s].updatePDBIds(); + } + Alignment al = new Alignment(sprods); + al.setDataset(dataset); + return al; + } + + public CrossRefAction(AlignFrame alignFrame, SequenceI[] sel, + boolean _odna, String source) + { + this.alignFrame = alignFrame; + this.sel = sel; + this._odna = _odna; + this.source = source; + } + + public static CrossRefAction showProductsFor(final SequenceI[] sel, + final boolean _odna, final String source, + final AlignFrame alignFrame) + { + return new CrossRefAction(alignFrame, sel, _odna, source); + } + +} diff --cc test/jalview/io/Jalview2xmlBase.java index 3ce5c4f,0000000..379fd68 mode 100644,000000..100644 --- a/test/jalview/io/Jalview2xmlBase.java +++ b/test/jalview/io/Jalview2xmlBase.java @@@ -1,69 -1,0 +1,76 @@@ +package jalview.io; + +import jalview.bin.Cache; ++import jalview.bin.Jalview; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.SequenceI; +import jalview.gui.Desktop; + - import java.time.Instant; +import java.util.Date; + +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeTest; + +public class Jalview2xmlBase +{ + + /** + * @throws java.lang.Exception + */ + @BeforeClass(alwaysRun = true) + public static void setUpBeforeClass() throws Exception + { - jalview.bin.Jalview.main(new String[] { "-props", - "test/jalview/io/testProps_nodas.jvprops" }); - jalview.bin.Cache.setProperty( - "JALVIEW_NEWS_RSS_LASTMODIFIED", - Cache.date_format.format(Date.from(Instant.now().plusSeconds( - 3600)))); ++ /* ++ * use read-only test properties file ++ */ ++ Cache.loadProperties("test/jalview/io/testProps.jvprops"); ++ ++ /* ++ * set news feed last read to a future time to ensure no ++ * 'unread' news item is displayed ++ */ ++ Date oneHourFromNow = new Date(System.currentTimeMillis() + 3600 * 1000); ++ Cache.setDateProperty("JALVIEW_NEWS_RSS_LASTMODIFIED", oneHourFromNow); ++ ++ Jalview.main(new String[] {}); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass(alwaysRun = true) + public static void tearDownAfterClass() throws Exception + { + jalview.gui.Desktop.instance.closeAll_actionPerformed(null); + } + + @BeforeTest(alwaysRun = true) + public static void clearDesktop() + { + if (Desktop.instance != null && Desktop.getAlignFrames() != null) + { + Desktop.instance.closeAll_actionPerformed(null); + } + } + + public int countDsAnn(jalview.viewmodel.AlignmentViewport avp) + { + int numdsann = 0; + for (SequenceI sq : avp.getAlignment().getDataset().getSequences()) + { + if (sq.getAnnotation() != null) + { + for (AlignmentAnnotation dssa : sq.getAnnotation()) + { + if (dssa.isValidStruc()) + { + numdsann++; + } + } + } + } + return numdsann; + } + +}