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;
40 import javax.swing.JOptionPane;
43 * Factory constructor and runnable for discovering and displaying
44 * cross-references for a set of aligned sequences
49 public class CrossRefAction implements Runnable
51 private AlignFrame alignFrame;
53 private SequenceI[] sel;
55 private boolean _odna;
57 private String source;
59 List<AlignmentViewPanel> xrefViews = new ArrayList<AlignmentViewPanel>();
61 public List<jalview.api.AlignmentViewPanel> getXrefViews()
69 final long sttime = System.currentTimeMillis();
70 alignFrame.setProgressBar(
71 MessageManager.formatMessage(
72 "status.searching_for_sequences_from",
73 new Object[] { source }), sttime);
76 AlignmentI alignment = alignFrame.getViewport().getAlignment();
77 AlignmentI dataset = alignment.getDataset() == null ? alignment
78 : alignment.getDataset();
79 boolean dna = alignment.isNucleotide();
83 .println("Conflict: showProducts for alignment originally "
84 + "thought to be " + (_odna ? "DNA" : "Protein")
85 + " now searching for " + (dna ? "DNA" : "Protein")
88 AlignmentI xrefs = new CrossRef(sel, dataset).findXrefSequences(
95 * get display scheme (if any) to apply to features
97 FeatureSettingsModelI featureColourScheme = new SequenceFetcher()
98 .getFeatureColourScheme(source);
100 AlignmentI xrefsAlignment = makeCrossReferencesAlignment(dataset,
104 xrefsAlignment = AlignmentUtils.makeCdsAlignment(
105 xrefsAlignment.getSequencesArray(), dataset, sel);
106 xrefsAlignment.alignAs(alignment);
110 * If we are opening a splitframe, make a copy of this alignment (sharing the same dataset
111 * sequences). If we are DNA, drop introns and update mappings
113 AlignmentI copyAlignment = null;
115 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
117 boolean copyAlignmentIsAligned = false;
120 copyAlignment = AlignmentUtils.makeCdsAlignment(sel, dataset,
121 xrefsAlignment.getSequencesArray());
122 if (copyAlignment.getHeight() == 0)
124 JvOptionPane.showMessageDialog(alignFrame,
125 MessageManager.getString("label.cant_map_cds"),
126 MessageManager.getString("label.operation_failed"),
127 JvOptionPane.OK_OPTION);
128 System.err.println("Failed to make CDS alignment");
132 * pending getting Embl transcripts to 'align',
133 * we are only doing this for Ensembl
135 // TODO proper criteria for 'can align as cdna'
136 if (DBRefSource.ENSEMBL.equalsIgnoreCase(source)
137 || AlignmentUtils.looksLikeEnsembl(alignment))
139 copyAlignment.alignAs(alignment);
140 copyAlignmentIsAligned = true;
145 copyAlignment = AlignmentUtils.makeCopyAlignment(sel,
146 xrefs.getSequencesArray(), dataset);
149 .setGapCharacter(alignFrame.viewport.getGapCharacter());
151 StructureSelectionManager ssm = StructureSelectionManager
152 .getStructureSelectionManager(Desktop.instance);
155 * register any new mappings for sequence mouseover etc
156 * (will not duplicate any previously registered mappings)
158 ssm.registerMappings(dataset.getCodonFrames());
160 if (copyAlignment.getHeight() <= 0)
162 System.err.println("No Sequences generated for xRef type "
167 * align protein to dna
169 if (dna && copyAlignmentIsAligned)
171 xrefsAlignment.alignAs(copyAlignment);
176 * align cdna to protein - currently only if
177 * fetching and aligning Ensembl transcripts!
179 // TODO: generalise for other sources of locus/transcript/cds data
180 if (dna && DBRefSource.ENSEMBL.equalsIgnoreCase(source))
182 copyAlignment.alignAs(xrefsAlignment);
187 * build AlignFrame(s) according to available alignment data
189 AlignFrame newFrame = new AlignFrame(xrefsAlignment,
190 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
191 if (Cache.getDefault("HIDE_INTRONS", true))
193 newFrame.hideFeatureColumns(SequenceOntologyI.EXON, false);
195 String newtitle = String.format("%s %s %s",
196 dna ? MessageManager.getString("label.proteins")
197 : MessageManager.getString("label.nucleotides"),
198 MessageManager.getString("label.for"), alignFrame.getTitle());
199 newFrame.setTitle(newtitle);
201 if (copyAlignment == null)
204 * split frame display is turned off in preferences file
206 Desktop.addInternalFrame(newFrame, newtitle,
207 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
208 xrefViews.add(newFrame.alignPanel);
209 return; // via finally clause
211 AlignFrame copyThis = new AlignFrame(copyAlignment,
212 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
213 copyThis.setTitle(alignFrame.getTitle());
215 boolean showSequenceFeatures = alignFrame.getViewport()
216 .isShowSequenceFeatures();
217 newFrame.setShowSeqFeatures(showSequenceFeatures);
218 copyThis.setShowSeqFeatures(showSequenceFeatures);
219 FeatureRenderer myFeatureStyling = alignFrame.alignPanel
220 .getSeqPanel().seqCanvas.getFeatureRenderer();
223 * copy feature rendering settings to split frame
225 newFrame.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
226 .transferSettings(myFeatureStyling);
227 copyThis.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
228 .transferSettings(myFeatureStyling);
231 * apply 'database source' feature configuration
234 // TODO is this the feature colouring for the original
235 // alignment or the fetched xrefs? either could be Ensembl
236 newFrame.getViewport().applyFeaturesStyle(featureColourScheme);
237 copyThis.getViewport().applyFeaturesStyle(featureColourScheme);
239 SplitFrame sf = new SplitFrame(dna ? copyThis : newFrame,
240 dna ? newFrame : copyThis);
241 newFrame.setVisible(true);
242 copyThis.setVisible(true);
243 String linkedTitle = MessageManager
244 .getString("label.linked_view_title");
245 Desktop.addInternalFrame(sf, linkedTitle, -1, -1);
248 // finally add the top, then bottom frame to the view list
249 xrefViews.add(dna ? copyThis.alignPanel : newFrame.alignPanel);
250 xrefViews.add(!dna ? copyThis.alignPanel : newFrame.alignPanel);
252 } catch (OutOfMemoryError e)
254 new OOMWarning("whilst fetching crossreferences", e);
255 } catch (Throwable e)
257 Cache.log.error("Error when finding crossreferences", e);
260 alignFrame.setProgressBar(MessageManager.formatMessage(
261 "status.finished_searching_for_sequences_from",
262 new Object[] { source }), sttime);
267 * Makes an alignment containing the given sequences, and adds them to the
268 * given dataset, which is also set as the dataset for the new alignment
270 * TODO: refactor to DatasetI method
276 protected AlignmentI makeCrossReferencesAlignment(AlignmentI dataset,
279 SequenceI[] sprods = new SequenceI[seqs.getHeight()];
280 for (int s = 0; s < sprods.length; s++)
282 sprods[s] = (seqs.getSequenceAt(s)).deriveSequence();
283 if (dataset.getSequences() == null
284 || !dataset.getSequences().contains(
285 sprods[s].getDatasetSequence()))
287 dataset.addSequence(sprods[s].getDatasetSequence());
289 sprods[s].updatePDBIds();
291 Alignment al = new Alignment(sprods);
292 al.setDataset(dataset);
296 public CrossRefAction(AlignFrame alignFrame, SequenceI[] sel,
297 boolean _odna, String source)
299 this.alignFrame = alignFrame;
302 this.source = source;
305 public static CrossRefAction showProductsFor(final SequenceI[] sel,
306 final boolean _odna, final String source,
307 final AlignFrame alignFrame)
309 return new CrossRefAction(alignFrame, sel, _odna, source);