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 JOptionPane.showMessageDialog(alignFrame,
125 MessageManager.getString("label.cant_map_cds"),
126 MessageManager.getString("label.operation_failed"),
127 JOptionPane.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", MessageManager
196 .getString(dna ? "label.proteins" : "label.nucleotides"),
197 MessageManager.getString("label.for"), alignFrame.getTitle());
198 newFrame.setTitle(newtitle);
200 if (copyAlignment == null)
203 * split frame display is turned off in preferences file
205 Desktop.addInternalFrame(newFrame, newtitle,
206 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
207 xrefViews.add(newFrame.alignPanel);
208 return; // via finally clause
210 AlignFrame copyThis = new AlignFrame(copyAlignment,
211 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
212 copyThis.setTitle(alignFrame.getTitle());
214 boolean showSequenceFeatures = alignFrame.getViewport()
215 .isShowSequenceFeatures();
216 newFrame.setShowSeqFeatures(showSequenceFeatures);
217 copyThis.setShowSeqFeatures(showSequenceFeatures);
218 FeatureRenderer myFeatureStyling = alignFrame.alignPanel
219 .getSeqPanel().seqCanvas.getFeatureRenderer();
222 * copy feature rendering settings to split frame
224 newFrame.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
225 .transferSettings(myFeatureStyling);
226 copyThis.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
227 .transferSettings(myFeatureStyling);
230 * apply 'database source' feature configuration
233 // TODO is this the feature colouring for the original
234 // alignment or the fetched xrefs? either could be Ensembl
235 newFrame.getViewport().applyFeaturesStyle(featureColourScheme);
236 copyThis.getViewport().applyFeaturesStyle(featureColourScheme);
238 SplitFrame sf = new SplitFrame(dna ? copyThis : newFrame,
239 dna ? newFrame : copyThis);
240 newFrame.setVisible(true);
241 copyThis.setVisible(true);
242 String linkedTitle = MessageManager
243 .getString("label.linked_view_title");
244 Desktop.addInternalFrame(sf, linkedTitle, -1, -1);
247 // finally add the top, then bottom frame to the view list
248 xrefViews.add(dna ? copyThis.alignPanel : newFrame.alignPanel);
249 xrefViews.add(!dna ? copyThis.alignPanel : newFrame.alignPanel);
251 } catch (OutOfMemoryError e)
253 new OOMWarning("whilst fetching crossreferences", e);
254 } catch (Throwable e)
256 Cache.log.error("Error when finding crossreferences", e);
259 alignFrame.setProgressBar(MessageManager.formatMessage(
260 "status.finished_searching_for_sequences_from",
261 new Object[] { source }), sttime);
266 * Makes an alignment containing the given sequences, and adds them to the
267 * given dataset, which is also set as the dataset for the new alignment
269 * TODO: refactor to DatasetI method
275 protected AlignmentI makeCrossReferencesAlignment(AlignmentI dataset,
278 SequenceI[] sprods = new SequenceI[seqs.getHeight()];
279 for (int s = 0; s < sprods.length; s++)
281 sprods[s] = (seqs.getSequenceAt(s)).deriveSequence();
282 if (dataset.getSequences() == null
283 || !dataset.getSequences().contains(
284 sprods[s].getDatasetSequence()))
286 dataset.addSequence(sprods[s].getDatasetSequence());
288 sprods[s].updatePDBIds();
290 Alignment al = new Alignment(sprods);
291 al.setDataset(dataset);
295 public CrossRefAction(AlignFrame alignFrame, SequenceI[] sel,
296 boolean _odna, String source)
298 this.alignFrame = alignFrame;
301 this.source = source;
304 public static CrossRefAction showProductsFor(final SequenceI[] sel,
305 final boolean _odna, final String source,
306 final AlignFrame alignFrame)
308 return new CrossRefAction(alignFrame, sel, _odna, source);