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(MessageManager.formatMessage(
71 "status.searching_for_sequences_from", new Object[]
75 AlignmentI alignment = alignFrame.getViewport().getAlignment();
76 AlignmentI dataset = alignment.getDataset() == null ? alignment
77 : alignment.getDataset();
78 boolean dna = alignment.isNucleotide();
82 .println("Conflict: showProducts for alignment originally "
83 + "thought to be " + (_odna ? "DNA" : "Protein")
84 + " now searching for " + (dna ? "DNA" : "Protein")
87 AlignmentI xrefs = new CrossRef(sel, dataset)
88 .findXrefSequences(source, dna);
94 * get display scheme (if any) to apply to features
96 FeatureSettingsModelI featureColourScheme = new SequenceFetcher()
97 .getFeatureColourScheme(source);
99 AlignmentI xrefsAlignment = makeCrossReferencesAlignment(dataset,
103 xrefsAlignment = AlignmentUtils.makeCdsAlignment(
104 xrefsAlignment.getSequencesArray(), dataset, sel);
105 xrefsAlignment.alignAs(alignment);
109 * If we are opening a splitframe, make a copy of this alignment (sharing the same dataset
110 * sequences). If we are DNA, drop introns and update mappings
112 AlignmentI copyAlignment = null;
114 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
116 boolean copyAlignmentIsAligned = false;
119 copyAlignment = AlignmentUtils.makeCdsAlignment(sel, dataset,
120 xrefsAlignment.getSequencesArray());
121 if (copyAlignment.getHeight() == 0)
123 JvOptionPane.showMessageDialog(alignFrame,
124 MessageManager.getString("label.cant_map_cds"),
125 MessageManager.getString("label.operation_failed"),
126 JvOptionPane.OK_OPTION);
127 System.err.println("Failed to make CDS alignment");
131 * pending getting Embl transcripts to 'align',
132 * we are only doing this for Ensembl
134 // TODO proper criteria for 'can align as cdna'
135 if (DBRefSource.ENSEMBL.equalsIgnoreCase(source)
136 || AlignmentUtils.looksLikeEnsembl(alignment))
138 copyAlignment.alignAs(alignment);
139 copyAlignmentIsAligned = true;
144 copyAlignment = AlignmentUtils.makeCopyAlignment(sel,
145 xrefs.getSequencesArray(), dataset);
148 .setGapCharacter(alignFrame.viewport.getGapCharacter());
150 StructureSelectionManager ssm = StructureSelectionManager
151 .getStructureSelectionManager(Desktop.instance);
154 * register any new mappings for sequence mouseover etc
155 * (will not duplicate any previously registered mappings)
157 ssm.registerMappings(dataset.getCodonFrames());
159 if (copyAlignment.getHeight() <= 0)
162 "No Sequences generated for xRef type " + source);
166 * align protein to dna
168 if (dna && copyAlignmentIsAligned)
170 xrefsAlignment.alignAs(copyAlignment);
175 * align cdna to protein - currently only if
176 * fetching and aligning Ensembl transcripts!
178 // TODO: generalise for other sources of locus/transcript/cds data
179 if (dna && DBRefSource.ENSEMBL.equalsIgnoreCase(source))
181 copyAlignment.alignAs(xrefsAlignment);
186 * build AlignFrame(s) according to available alignment data
188 AlignFrame newFrame = new AlignFrame(xrefsAlignment,
189 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
190 if (Cache.getDefault("HIDE_INTRONS", true))
192 newFrame.hideFeatureColumns(SequenceOntologyI.EXON, false);
194 String newtitle = String.format("%s %s %s",
195 dna ? MessageManager.getString("label.proteins")
196 : MessageManager.getString("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);
245 sf.adjustInitialLayout();
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", new Object[]
261 { 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 || !dataset.getSequences()
283 .contains(sprods[s].getDatasetSequence()))
285 dataset.addSequence(sprods[s].getDatasetSequence());
287 sprods[s].updatePDBIds();
289 Alignment al = new Alignment(sprods);
290 al.setDataset(dataset);
294 public CrossRefAction(AlignFrame alignFrame, SequenceI[] sel,
295 boolean _odna, String source)
297 this.alignFrame = alignFrame;
300 this.source = source;
303 public static CrossRefAction showProductsFor(final SequenceI[] sel,
304 final boolean _odna, final String source,
305 final AlignFrame alignFrame)
307 return new CrossRefAction(alignFrame, sel, _odna, source);