Actions for creating and updating the consensus sequence in AlignmentEditor implemented.
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / molecular / AlignmentEditor.java
index 087b59c220582dabb73919dc781f16c851915cc5..440bc7e070b9401d3047644daec4edd1d1a6a230 100644 (file)
@@ -91,8 +91,10 @@ public class AlignmentEditor extends EditorPart {
     public static final String ID = "eu.etaxonomy.taxeditor.editor.molecular.AlignmentEditor";
 
        public static final int READS_AREA_INDEX = 1;
-       public static final int CONSENSUS_AREA_INDEX = READS_AREA_INDEX + 1;
+    public static final int EDITABLE_CONSENSUS_AREA_INDEX = READS_AREA_INDEX + 1;
+    public static final int CONSENSUS_HINT_AREA_INDEX = EDITABLE_CONSENSUS_AREA_INDEX + 1;
        public static final int PHEROGRAM_AREA_INDEX = 0;
+       public static final int CONSENSUS_DATA_AREA_INDEX = 0;
        public static final String DEFAULT_READ_NAME_PREFIX = "Read ";
        public static final String CONSENSUS_NAME = "Consensus";
 
@@ -204,7 +206,7 @@ public class AlignmentEditor extends EditorPart {
 
                AlignmentAreaList list = alignmentsContainer.getAlignmentAreas();
                AlignmentArea readsArea = createEditableAlignmentArea(alignmentsContainer, true);
-        list.add(createIndexArea(alignmentsContainer, readsArea));
+           list.add(createIndexArea(alignmentsContainer, readsArea));
                list.add(readsArea);  // Make sure READS_AREA_INDEX is correct.
                list.add(createEditableAlignmentArea(alignmentsContainer, false));  // Make sure COMSENSUS_AREA_INDEX is correct.
                list.add(createConsensusHintArea(alignmentsContainer, readsArea));
@@ -220,13 +222,21 @@ public class AlignmentEditor extends EditorPart {
     }
 
 
-    private AlignmentArea getConsensusArea() {
-       return getAlignmentsContainer().getAlignmentAreas().get(CONSENSUS_AREA_INDEX);
+    private AlignmentArea getEditableConsensusArea() {
+       return getAlignmentsContainer().getAlignmentAreas().get(EDITABLE_CONSENSUS_AREA_INDEX);
     }
 
 
     private PherogramArea getPherogramArea(int sequenceID) {
-       return (PherogramArea)getReadsArea().getDataAreas().getSequenceAreas(sequenceID).get(PHEROGRAM_AREA_INDEX);
+       return (PherogramArea)getReadsArea().getDataAreas().getSequenceAreas(sequenceID).get(
+               PHEROGRAM_AREA_INDEX);
+    }
+
+
+    private ConsensusSequenceArea getConsensusHintDataArea() {
+        return (ConsensusSequenceArea)getAlignmentsContainer().getAlignmentAreas().
+                get(CONSENSUS_HINT_AREA_INDEX).getDataAreas().getBottomAreas().
+                get(CONSENSUS_DATA_AREA_INDEX);
     }
 
 
@@ -237,14 +247,14 @@ public class AlignmentEditor extends EditorPart {
                        addRead(new File("D:/Users/BenStoever/ownCloud/Dokumente/Projekte/EDITor/Quelltexte/LibrAlign branch/Repository/eu.etaxonomy.taxeditor.editor/src/main/resources/AlignmentTestData/JR444_JR-P05.ab1").toURI(), false);
 
                        // Add test consensus sequence:
-                       AlignmentModel consensusProvider = getConsensusArea().getAlignmentModel();
-                       int id = consensusProvider.addSequence(CONSENSUS_NAME);
+                       AlignmentModel consensusModel = getEditableConsensusArea().getAlignmentModel();
+                       int id = consensusModel.addSequence(CONSENSUS_NAME);
                        Collection<Object> tokens = new ArrayList<Object>();  // First save tokens in a collection to avoid GUI updated for each token.
-                       tokens.add(consensusProvider.getTokenSet().tokenByKeyChar('A'));
-                       tokens.add(consensusProvider.getTokenSet().tokenByKeyChar('C'));
-                       tokens.add(consensusProvider.getTokenSet().tokenByKeyChar('G'));
-                       tokens.add(consensusProvider.getTokenSet().tokenByKeyChar('T'));
-                       consensusProvider.insertTokensAt(id, 0, tokens);
+                       tokens.add(consensusModel.getTokenSet().tokenByKeyChar('A'));
+                       tokens.add(consensusModel.getTokenSet().tokenByKeyChar('C'));
+                       tokens.add(consensusModel.getTokenSet().tokenByKeyChar('G'));
+                       tokens.add(consensusModel.getTokenSet().tokenByKeyChar('T'));
+                       consensusModel.insertTokensAt(id, 0, tokens);
                }
                catch (Exception e) {
                        throw new RuntimeException(e);
@@ -275,7 +285,7 @@ public class AlignmentEditor extends EditorPart {
                }
 
                // Set consensus sequence:
-               AlignmentModel consensusProvider = getConsensusArea().getAlignmentModel();
+               AlignmentModel consensusProvider = getEditableConsensusArea().getAlignmentModel();
                int id = consensusProvider.addSequence(CONSENSUS_NAME);
                consensusProvider.insertTokensAt(id, 0, AlignmentModelUtils.charSequenceToTokenList(
                                sequenceNode.getConsensusSequence().getString(), consensusProvider.getTokenSet()));
@@ -311,7 +321,7 @@ public class AlignmentEditor extends EditorPart {
        }
 
 
-  private void updateStatusBar() {
+    private void updateStatusBar() {
         IActionBars bars = getEditorSite().getActionBars();
         bars.getStatusLineManager().setMessage("Edit mode: " +
                        (getReadsArea().getEditSettings().isInsert() ? "Insert" : "Overwrite") + "  " +
@@ -342,12 +352,12 @@ public class AlignmentEditor extends EditorPart {
             monitor.beginTask(taskName, 3);
 
                Sequence sequenceNode = ((AlignmentEditorInput)getEditorInput()).getSequenceNode();
-               StringAdapter stringProvider = new StringAdapter(getConsensusArea().getAlignmentModel(), false);  // Throws an exception if a token has more than one character.
+               StringAdapter stringProvider = new StringAdapter(getEditableConsensusArea().getAlignmentModel(), false);  // Throws an exception if a token has more than one character.
 
                // Write consensus sequence:
                SequenceString consensusSequenceObj = sequenceNode.getConsensusSequence();
                String newConsensusSequence = stringProvider.getSequence(
-                               getConsensusArea().getAlignmentModel().sequenceIDByName(CONSENSUS_NAME));
+                               getEditableConsensusArea().getAlignmentModel().sequenceIDByName(CONSENSUS_NAME));
                if (consensusSequenceObj == null) {
                        sequenceNode.setConsensusSequence(SequenceString.NewInstance(newConsensusSequence));
                }
@@ -519,6 +529,61 @@ public class AlignmentEditor extends EditorPart {
     }
 
 
+    /**
+     * Recreates the whole consensus sequence from all single read sequences. The previous consensus
+     * sequence is overwritte.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> void createConsensusSequence() {
+        ConsensusSequenceArea area = getConsensusHintDataArea();
+        AlignmentModel<T> model = (AlignmentModel<T>)getEditableConsensusArea().getAlignmentModel();
+        int sequenceID = model.sequenceIDIterator().next();  // There is always one sequence contained.
+        int length = getReadsArea().getAlignmentModel().getMaxSequenceLength();
+
+        Collection<T> tokens = new ArrayList<T>(length);
+        for (int column = 0; column < length; column++) {
+            tokens.add(model.getTokenSet().tokenByRepresentation(area.getConsensusToken(column)));
+        }
+
+        model.removeTokensAt(sequenceID, 0, model.getSequenceLength(sequenceID));
+        model.insertTokensAt(sequenceID, 0, tokens);
+    }
+
+
+    /**
+     * Updates the current consensus sequence by replacing gaps by the according consensus tokens
+     * calculated from the single read sequences and extends the consensus sequence if necessary.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> void updateConsensusSequence() {
+        ConsensusSequenceArea area = getConsensusHintDataArea();
+        AlignmentModel<T> model = (AlignmentModel<T>)getEditableConsensusArea().getAlignmentModel();
+        TokenSet<T> tokenSet = model.getTokenSet();
+        int sequenceID = model.sequenceIDIterator().next();  // There is always one sequence contained.
+        int currentConsensusLength = model.getSequenceLength(sequenceID);
+        int overallLength = getReadsArea().getAlignmentModel().getMaxSequenceLength();
+
+        // Replace gaps by new information:
+        for (int column = 0; column < currentConsensusLength; column++) {
+            if (tokenSet.isGapToken(model.getTokenAt(sequenceID, column))) {
+                T newToken = tokenSet.tokenByRepresentation(area.getConsensusToken(column));
+                if (!tokenSet.isGapToken(newToken)) {
+                    model.setTokenAt(sequenceID, column, newToken);
+                }
+            }
+        }
+
+        // Append additional tokens:
+        if (overallLength > currentConsensusLength) {
+            Collection<T> tokens = new ArrayList<T>(overallLength);
+            for (int column = currentConsensusLength; column < overallLength; column++) {
+                tokens.add(tokenSet.tokenByRepresentation(area.getConsensusToken(column)));
+            }
+            model.appendTokens(sequenceID, tokens);
+        }
+    }
+
+
        public static PherogramModel readPherogram(URI uri) throws IOException, UnsupportedChromatogramFormatException {
                PherogramModel result;
                InputStream stream = uri.toURL().openStream();