3 * Copyright (C) 2014 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.taxeditor
.editor
.molecular
;
13 import info
.bioinfweb
.libralign
.alignmentarea
.AlignmentArea
;
14 import info
.bioinfweb
.libralign
.alignmentarea
.content
.AlignmentContentArea
;
15 import info
.bioinfweb
.libralign
.dataarea
.implementations
.ConsensusSequenceArea
;
16 import info
.bioinfweb
.libralign
.dataarea
.implementations
.SequenceIndexArea
;
17 import info
.bioinfweb
.libralign
.dataarea
.implementations
.pherogram
.PherogramArea
;
18 import info
.bioinfweb
.libralign
.editsettings
.EditSettingsChangeEvent
;
19 import info
.bioinfweb
.libralign
.editsettings
.EditSettingsListener
;
20 import info
.bioinfweb
.libralign
.multiplealignments
.AlignmentAreaList
;
21 import info
.bioinfweb
.libralign
.multiplealignments
.MultipleAlignmentsContainer
;
22 import info
.bioinfweb
.libralign
.pherogram
.provider
.BioJavaPherogramProvider
;
23 import info
.bioinfweb
.libralign
.pherogram
.provider
.PherogramProvider
;
24 import info
.bioinfweb
.libralign
.sequenceprovider
.SequenceDataProvider
;
25 import info
.bioinfweb
.libralign
.sequenceprovider
.implementations
.PackedSequenceDataProvider
;
26 import info
.bioinfweb
.libralign
.sequenceprovider
.tokenset
.BioJavaTokenSet
;
27 import info
.bioinfweb
.libralign
.sequenceprovider
.tokenset
.TokenSet
;
30 import java
.io
.IOException
;
31 import java
.io
.InputStream
;
33 import java
.util
.ArrayList
;
34 import java
.util
.Collection
;
35 import java
.util
.Collections
;
37 import java
.util
.TreeMap
;
39 import org
.biojava
.bio
.chromatogram
.ChromatogramFactory
;
40 import org
.biojava
.bio
.chromatogram
.UnsupportedChromatogramFormatException
;
41 import org
.biojava3
.core
.sequence
.compound
.DNACompoundSet
;
42 import org
.biojava3
.core
.sequence
.compound
.NucleotideCompound
;
43 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
44 import org
.eclipse
.swt
.SWT
;
45 import org
.eclipse
.swt
.widgets
.Composite
;
46 import org
.eclipse
.ui
.IActionBars
;
47 import org
.eclipse
.ui
.IEditorInput
;
48 import org
.eclipse
.ui
.IEditorSite
;
49 import org
.eclipse
.ui
.PartInitException
;
50 import org
.eclipse
.ui
.PlatformUI
;
51 import org
.eclipse
.ui
.commands
.ICommandService
;
52 import org
.eclipse
.ui
.part
.EditorPart
;
54 import eu
.etaxonomy
.taxeditor
.editor
.handler
.ToggleInsertOverwriteHandler
;
55 import eu
.etaxonomy
.taxeditor
.editor
.handler
.ToggleLeftRightInsertionHandler
;
60 * Editor component to edit a contig alignment used to combine different overlapping pherograms from Sanger sequencing to
61 * a consensus sequence.
63 * The contained GUI components used to edit the alignment come from <a href="http://bioinfweb.info/LibrAlign/">LibrAlign</a>.
69 public class AlignmentEditor
extends EditorPart
{
70 public static final String ID
= "eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditor";
71 public static final int READS_AREA_INDEX
= 1;
72 public static final int CONSENSUS_AREA_INDEX
= READS_AREA_INDEX
+ 1;
73 public static final String DEFAULT_READ_NAME_PREFIX
= "Read ";
76 private MultipleAlignmentsContainer alignmentsContainer
= null;
77 private Map
<Integer
, URI
> uriMap
= new TreeMap
<Integer
, URI
>(); //TODO Move this to ContigSequenceDataProvider
80 private void refreshToolbarElement(String id
) {
81 ICommandService commandService
=
82 (ICommandService
)PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getService(ICommandService
.class);
83 if (commandService
!= null) {
84 commandService
.refreshElements(id
, Collections
.EMPTY_MAP
);
89 private void registerEditSettingListener(MultipleAlignmentsContainer container
) {
90 container
.getEditSettings().addListener(new EditSettingsListener() {
92 public void workingModeChanged(EditSettingsChangeEvent e
) {} // Currently nothing to do
95 public void insertLeftInDataAreaChanged(EditSettingsChangeEvent e
) {
97 refreshToolbarElement(ToggleLeftRightInsertionHandler
.COMMAND_ID
);
101 public void insertChanged(EditSettingsChangeEvent e
) {
103 refreshToolbarElement(ToggleInsertOverwriteHandler
.COMMAND_ID
);
109 private AlignmentArea
createIndexArea(MultipleAlignmentsContainer container
) {
110 AlignmentArea result
= new AlignmentArea(container
);
111 result
.setAllowVerticalScrolling(false);
112 result
.getDataAreas().getTopAreas().add(new SequenceIndexArea(result
.getContentArea()));
117 private AlignmentArea
createEditableAlignmentArea(MultipleAlignmentsContainer container
, boolean allowVerticalScrolling
) {
118 AlignmentArea result
= new AlignmentArea(container
);
119 result
.setAllowVerticalScrolling(allowVerticalScrolling
);
121 TokenSet
<NucleotideCompound
> tokenSet
= new BioJavaTokenSet
<NucleotideCompound
>(new DNACompoundSet(), true);
122 SequenceDataProvider
<NucleotideCompound
> provider
= new PackedSequenceDataProvider
<NucleotideCompound
>(tokenSet
);
123 result
.setSequenceProvider(provider
, false);
129 private AlignmentArea
createConsensusHintArea(MultipleAlignmentsContainer container
,
130 SequenceDataProvider
<?
> sequenceProvider
) {
132 AlignmentArea result
= new AlignmentArea(container
);
133 result
.setAllowVerticalScrolling(false);
134 result
.getDataAreas().getBottomAreas().add(
135 new ConsensusSequenceArea(result
.getContentArea(), sequenceProvider
));
140 private MultipleAlignmentsContainer
getAlignmentsContainer() {
141 if (alignmentsContainer
== null) {
142 alignmentsContainer
= new MultipleAlignmentsContainer();
144 AlignmentAreaList list
= alignmentsContainer
.getAlignmentAreas();
145 list
.add(createIndexArea(alignmentsContainer
));
146 AlignmentArea readsArea
= createEditableAlignmentArea(alignmentsContainer
, true);
147 list
.add(readsArea
); // Make sure READS_AREA_INDEX is correct.
148 list
.add(createEditableAlignmentArea(alignmentsContainer
, false)); // Make sure COMSENSUS_AREA_INDEX is correct.
149 list
.add(createConsensusHintArea(alignmentsContainer
,
150 readsArea
.getSequenceProvider()));
152 registerEditSettingListener(alignmentsContainer
);
154 return alignmentsContainer
;
158 private AlignmentArea
getReadsArea() {
159 return getAlignmentsContainer().getAlignmentAreas().get(READS_AREA_INDEX
);
163 private AlignmentArea
getConsensusArea() {
164 return getAlignmentsContainer().getAlignmentAreas().get(CONSENSUS_AREA_INDEX
);
169 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
172 public void createPartControl(Composite parent
) {
173 getAlignmentsContainer().createSWTWidget(parent
, SWT
.NONE
);
178 addRead(new File("D:/Users/BenStoever/Documents/Studium/Projekte/Promotion/EDITor/Quelltexte/LibrAlign branch/Repository/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR430_JR-P01.ab1").toURI());
179 addRead(new File("D:/Users/BenStoever/Documents/Studium/Projekte/Promotion/EDITor/Quelltexte/LibrAlign branch/Repository/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR444_JR-P05.ab1").toURI());
181 // Add test consensus sequence:
182 SequenceDataProvider consensusProvider
= getConsensusArea().getSequenceProvider();
183 int id
= consensusProvider
.addSequence("Consensus");
184 Collection
<Object
> tokens
= new ArrayList
<Object
>(); // First save tokens in a collection to avoid GUI updated for each token.
185 tokens
.add(consensusProvider
.getTokenSet().tokenByKeyChar('A'));
186 tokens
.add(consensusProvider
.getTokenSet().tokenByKeyChar('C'));
187 tokens
.add(consensusProvider
.getTokenSet().tokenByKeyChar('G'));
188 tokens
.add(consensusProvider
.getTokenSet().tokenByKeyChar('T'));
189 consensusProvider
.insertTokensAt(id
, 0, tokens
);
191 catch (Exception e
) {
192 throw new RuntimeException(e
);
197 private void updateStatusBar() {
198 IActionBars bars
= getEditorSite().getActionBars();
199 bars
.getStatusLineManager().setMessage("Edit mode: " +
200 (getReadsArea().getEditSettings().isInsert() ?
"Insert" : "Overwrite") + " " +
201 "Insertion in pherogram: " +
202 (getReadsArea().getEditSettings().isInsertLeftInDataArea() ?
"Left" : "Right"));
207 * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
210 public void doSave(IProgressMonitor monitor
) {
211 // TODO Auto-generated method stub
217 * @see org.eclipse.ui.part.EditorPart#doSaveAs()
220 public void doSaveAs() {
221 // TODO Auto-generated method stub
227 * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
230 public void init(IEditorSite site
, IEditorInput input
) throws PartInitException
{
237 * @see org.eclipse.ui.part.EditorPart#isDirty()
240 public boolean isDirty() {
241 // TODO Auto-generated method stub
247 * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
250 public boolean isSaveAsAllowed() {
251 // TODO Auto-generated method stub
257 public void setFocus() {}
260 public boolean isInsertMode() {
261 return getAlignmentsContainer().getEditSettings().isInsert();
265 public boolean isInsertLeftInPherogram() {
266 return getAlignmentsContainer().getEditSettings().isInsertLeftInDataArea();
270 public void toggleLeftRightInsertionInPherogram() {
271 getAlignmentsContainer().getEditSettings().toggleInsertLeftInDataArea();
275 public void toggleInsertOverwrite() {
276 getAlignmentsContainer().getEditSettings().toggleInsert();
280 public static PherogramProvider
readPherogram(URI uri
) throws IOException
, UnsupportedChromatogramFormatException
{
281 PherogramProvider result
;
282 InputStream stream
= uri
.toURL().openStream();
284 result
= new BioJavaPherogramProvider(ChromatogramFactory
.create(stream
));
293 private String
newReadName() {
295 while (getReadsArea().getSequenceProvider().sequenceIDByName(DEFAULT_READ_NAME_PREFIX
+ index
)
296 != SequenceDataProvider
.NO_SEQUENCE_FOUND
) {
300 return DEFAULT_READ_NAME_PREFIX
+ index
;
304 public void addRead(URI pherogramURI
) throws IOException
, UnsupportedChromatogramFormatException
{
305 addRead(newReadName(), pherogramURI
);
309 public void addRead(String name
, URI pherogramURI
) throws IOException
, UnsupportedChromatogramFormatException
{
310 SequenceDataProvider provider
= getReadsArea().getSequenceProvider();
311 PherogramProvider pherogramProvider
= readPherogram(pherogramURI
); // Must happen before a sequence is added, because it might throw an exception.
314 provider
.addSequence(name
);
315 int id
= provider
.sequenceIDByName(name
);
317 // Copy base call sequence into alignment:
318 Collection
<Object
> tokens
= new ArrayList
<Object
>(); // First save tokens in a collection to avoid GUI updated for each token.
319 for (int i
= 0; i
< pherogramProvider
.getSequenceLength(); i
++) {
320 tokens
.add(provider
.getTokenSet().tokenByKeyChar(
321 pherogramProvider
.getBaseCall(i
).getUpperedBase().charAt(0)));
323 provider
.insertTokensAt(id
, 0, tokens
);
326 PherogramArea pherogramArea
= new PherogramArea(getReadsArea().getContentArea(), pherogramProvider
);
327 pherogramArea
.addMouseListener(new PherogramMouseListener(pherogramURI
));
328 getReadsArea().getDataAreas().getSequenceAreas(id
).add(pherogramArea
);
331 uriMap
.put(id
, pherogramURI
);