2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.analysis.AlignmentUtils;
24 import jalview.analysis.CrossRef;
25 import jalview.api.AlignmentViewPanel;
26 import jalview.api.FeatureSettingsModelI;
27 import jalview.bin.Cache;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.DBRefSource;
31 import jalview.datamodel.SequenceI;
32 import jalview.io.gff.SequenceOntologyI;
33 import jalview.structure.StructureSelectionManager;
34 import jalview.util.MessageManager;
35 import jalview.ws.SequenceFetcher;
37 import java.util.ArrayList;
38 import java.util.List;
41 * Factory constructor and runnable for discovering and displaying
42 * cross-references for a set of aligned sequences
47 public class CrossRefAction implements Runnable
49 private AlignFrame alignFrame;
51 private SequenceI[] sel;
53 private boolean _odna;
55 private String source;
57 List<AlignmentViewPanel> xrefViews = new ArrayList<AlignmentViewPanel>();
59 public List<jalview.api.AlignmentViewPanel> getXrefViews()
67 final long sttime = System.currentTimeMillis();
68 alignFrame.setProgressBar(
69 MessageManager.formatMessage(
70 "status.searching_for_sequences_from",
71 new Object[] { source }), sttime);
74 AlignmentI alignment = alignFrame.getViewport().getAlignment();
75 AlignmentI dataset = alignment.getDataset() == null ? alignment
76 : alignment.getDataset();
77 boolean dna = alignment.isNucleotide();
81 .println("Conflict: showProducts for alignment originally "
82 + "thought to be " + (_odna ? "DNA" : "Protein")
83 + " now searching for " + (dna ? "DNA" : "Protein")
86 AlignmentI xrefs = new CrossRef(sel, dataset).findXrefSequences(
93 * get display scheme (if any) to apply to features
95 FeatureSettingsModelI featureColourScheme = new SequenceFetcher()
96 .getFeatureColourScheme(source);
98 AlignmentI xrefsAlignment = makeCrossReferencesAlignment(dataset,
102 xrefsAlignment = AlignmentUtils.makeCdsAlignment(
103 xrefsAlignment.getSequencesArray(), dataset, sel);
104 xrefsAlignment.alignAs(alignment);
108 * If we are opening a splitframe, make a copy of this alignment (sharing the same dataset
109 * sequences). If we are DNA, drop introns and update mappings
111 AlignmentI copyAlignment = null;
113 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
115 boolean copyAlignmentIsAligned = false;
118 copyAlignment = AlignmentUtils.makeCdsAlignment(sel, dataset,
119 xrefsAlignment.getSequencesArray());
120 if (copyAlignment.getHeight() == 0)
122 System.err.println("Failed to make CDS alignment");
126 * pending getting Embl transcripts to 'align',
127 * we are only doing this for Ensembl
129 // TODO proper criteria for 'can align as cdna'
130 if (DBRefSource.ENSEMBL.equalsIgnoreCase(source)
131 || AlignmentUtils.looksLikeEnsembl(alignment))
133 copyAlignment.alignAs(alignment);
134 copyAlignmentIsAligned = true;
139 copyAlignment = AlignmentUtils.makeCopyAlignment(sel,
140 xrefs.getSequencesArray(), dataset);
143 .setGapCharacter(alignFrame.viewport.getGapCharacter());
145 StructureSelectionManager ssm = StructureSelectionManager
146 .getStructureSelectionManager(Desktop.instance);
149 * register any new mappings for sequence mouseover etc
150 * (will not duplicate any previously registered mappings)
152 ssm.registerMappings(dataset.getCodonFrames());
154 if (copyAlignment.getHeight() <= 0)
156 System.err.println("No Sequences generated for xRef type "
161 * align protein to dna
163 if (dna && copyAlignmentIsAligned)
165 xrefsAlignment.alignAs(copyAlignment);
170 * align cdna to protein - currently only if
171 * fetching and aligning Ensembl transcripts!
173 // TODO: generalise for other sources of locus/transcript/cds data
174 if (dna && DBRefSource.ENSEMBL.equalsIgnoreCase(source))
176 copyAlignment.alignAs(xrefsAlignment);
181 * build AlignFrame(s) according to available alignment data
183 AlignFrame newFrame = new AlignFrame(xrefsAlignment,
184 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
185 if (Cache.getDefault("HIDE_INTRONS", true))
187 newFrame.hideFeatureColumns(SequenceOntologyI.EXON, false);
189 String newtitle = String.format("%s %s %s", MessageManager
190 .getString(dna ? "label.proteins" : "label.nucleotides"),
191 MessageManager.getString("label.for"), alignFrame.getTitle());
192 newFrame.setTitle(newtitle);
194 if (copyAlignment == null)
197 * split frame display is turned off in preferences file
199 Desktop.addInternalFrame(newFrame, newtitle,
200 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
201 xrefViews.add(newFrame.alignPanel);
202 return; // via finally clause
204 AlignFrame copyThis = new AlignFrame(copyAlignment,
205 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
206 copyThis.setTitle(alignFrame.getTitle());
208 boolean showSequenceFeatures = alignFrame.getViewport()
209 .isShowSequenceFeatures();
210 newFrame.setShowSeqFeatures(showSequenceFeatures);
211 copyThis.setShowSeqFeatures(showSequenceFeatures);
212 FeatureRenderer myFeatureStyling = alignFrame.alignPanel
213 .getSeqPanel().seqCanvas.getFeatureRenderer();
216 * copy feature rendering settings to split frame
218 newFrame.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
219 .transferSettings(myFeatureStyling);
220 copyThis.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
221 .transferSettings(myFeatureStyling);
224 * apply 'database source' feature configuration
227 // TODO is this the feature colouring for the original
228 // alignment or the fetched xrefs? either could be Ensembl
229 newFrame.getViewport().applyFeaturesStyle(featureColourScheme);
230 copyThis.getViewport().applyFeaturesStyle(featureColourScheme);
232 SplitFrame sf = new SplitFrame(dna ? copyThis : newFrame,
233 dna ? newFrame : copyThis);
234 newFrame.setVisible(true);
235 copyThis.setVisible(true);
236 String linkedTitle = MessageManager
237 .getString("label.linked_view_title");
238 Desktop.addInternalFrame(sf, linkedTitle, -1, -1);
241 // finally add the top, then bottom frame to the view list
242 xrefViews.add(dna ? copyThis.alignPanel : newFrame.alignPanel);
243 xrefViews.add(!dna ? copyThis.alignPanel : newFrame.alignPanel);
245 } catch (OutOfMemoryError e)
247 new OOMWarning("whilst fetching crossreferences", e);
248 } catch (Throwable e)
250 Cache.log.error("Error when finding crossreferences", e);
253 alignFrame.setProgressBar(MessageManager.formatMessage(
254 "status.finished_searching_for_sequences_from",
255 new Object[] { source }), sttime);
260 * Makes an alignment containing the given sequences, and adds them to the
261 * given dataset, which is also set as the dataset for the new alignment
263 * TODO: refactor to DatasetI method
269 protected AlignmentI makeCrossReferencesAlignment(AlignmentI dataset,
272 SequenceI[] sprods = new SequenceI[seqs.getHeight()];
273 for (int s = 0; s < sprods.length; s++)
275 sprods[s] = (seqs.getSequenceAt(s)).deriveSequence();
276 if (dataset.getSequences() == null
277 || !dataset.getSequences().contains(
278 sprods[s].getDatasetSequence()))
280 dataset.addSequence(sprods[s].getDatasetSequence());
282 sprods[s].updatePDBIds();
284 Alignment al = new Alignment(sprods);
285 al.setDataset(dataset);
289 public CrossRefAction(AlignFrame alignFrame, SequenceI[] sel,
290 boolean _odna, String source)
292 this.alignFrame = alignFrame;
295 this.source = source;
298 public static CrossRefAction showProductsFor(final SequenceI[] sel,
299 final boolean _odna, final String source,
300 final AlignFrame alignFrame)
302 return new CrossRefAction(alignFrame, sel, _odna, source);