001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 * Created on June 14, 2010
021 * Author: Mark Chapman
022 */
023
024package org.biojava.nbio.core.alignment;
025
026import org.biojava.nbio.core.alignment.template.AlignedSequence;
027import org.biojava.nbio.core.alignment.template.AlignedSequence.Step;
028import org.biojava.nbio.core.alignment.template.Profile;
029import org.biojava.nbio.core.alignment.template.SequencePair;
030import org.biojava.nbio.core.sequence.compound.AminoAcidCompound;
031import org.biojava.nbio.core.sequence.template.Compound;
032import org.biojava.nbio.core.sequence.template.Sequence;
033
034import java.util.List;
035
036/**
037 * Implements a data structure for the results of pairwise sequence alignment.
038 *
039 * @author Mark Chapman
040 * @author Paolo Pavan
041 * @param <S> each element of the alignment {@link Profile} is of type S
042 * @param <C> each element of an {@link AlignedSequence} is a {@link Compound} of type C
043 */
044public class SimpleSequencePair<S extends Sequence<C>, C extends Compound> extends SimpleProfile<S, C>
045implements SequencePair<S, C> {
046
047
048        private static final long serialVersionUID = 1L;
049
050        private int identicals = -1, similars = -1;
051
052        /**
053         * Creates a pair profile for the given already aligned sequences.
054         *
055         * @param query the first sequence of the pair
056         * @param target the second sequence of the pair
057         * @throws IllegalArgumentException if sequences differ in size
058         */
059        public SimpleSequencePair(AlignedSequence<S, C> query, AlignedSequence<S, C> target) {
060                super(query, target);
061        }
062
063        /**
064         * Creates a pair profile for the given sequences with a global alignment.
065         *
066         * @param query the first sequence of the pair
067         * @param target the second sequence of the pair
068         * @param sx lists whether the query sequence aligns a {@link Compound} or gap at each index of the alignment
069         * @param sy lists whether the target sequence aligns a {@link Compound} or gap at each index of the alignment
070         * @throws IllegalArgumentException if alignments differ in size or given sequences do not fit in alignments
071         */
072        public SimpleSequencePair(S query, S target, List<Step> sx, List<Step> sy) {
073                this(query, target, sx, 0, 0, sy, 0, 0);
074        }
075
076        /**
077         * Creates a pair profile for the given sequences with a local alignment.
078         *
079         * @param query the first sequence of the pair
080         * @param target the second sequence of the pair
081         * @param sx lists whether the query sequence aligns a {@link Compound} or gap at each index of the alignment
082         * @param xb number of {@link Compound}s skipped in the query sequence before the aligned region
083         * @param xa number of {@link Compound}s skipped in the query sequence after the aligned region
084         * @param sy lists whether the target sequence aligns a {@link Compound} or gap at each index of the alignment
085         * @param yb number of {@link Compound}s skipped in the target sequence before the aligned region
086         * @param ya number of {@link Compound}s skipped in the target sequence after the aligned region
087         * @throws IllegalArgumentException if alignments differ in size or given sequences do not fit in alignments
088         */
089        public SimpleSequencePair(S query, S target, List<Step> sx, int xb, int xa, List<Step> sy, int yb, int ya) {
090                super(query, target, sx, xb, xa, sy, yb, ya);
091        }
092
093        @Override
094        public C getCompoundInQueryAt(int alignmentIndex) {
095                return getAlignedSequence(1).getCompoundAt(alignmentIndex);
096        }
097
098        @Override
099        public C getCompoundInTargetAt(int alignmentIndex) {
100                return getAlignedSequence(2).getCompoundAt(alignmentIndex);
101        }
102
103        @Override
104        public int getIndexInQueryAt(int alignmentIndex) {
105                return getAlignedSequence(1).getSequenceIndexAt(alignmentIndex);
106        }
107
108        @Override
109        public int getIndexInQueryForTargetAt(int targetIndex) {
110                return getAlignedSequence(1).getSequenceIndexAt(getAlignedSequence(2).getAlignmentIndexAt(targetIndex));
111        }
112
113        @Override
114        public int getIndexInTargetAt(int alignmentIndex) {
115                return getAlignedSequence(2).getSequenceIndexAt(alignmentIndex);
116        }
117
118        @Override
119        public int getIndexInTargetForQueryAt(int queryIndex) {
120                return getAlignedSequence(2).getSequenceIndexAt(getAlignedSequence(1).getAlignmentIndexAt(queryIndex));
121        }
122
123        @Override
124        public int getNumIdenticals() {
125                if (identicals == -1) {
126                        identicals = 0;
127                        for (int i = 1; i <= getLength(); i++) {
128                                if (getCompoundInQueryAt(i).equalsIgnoreCase(getCompoundInTargetAt(i))) {
129                                        identicals++;
130                                }
131                        }
132                        getQuery().clearCache();
133                        getTarget().clearCache();
134                }
135                return identicals;
136        }
137
138        @Override
139        public int getNumSimilars() {
140                if (similars == -1) {
141                        similars = 0;
142                        for (int i = 1; i <= getLength(); i++) {
143
144                                C c1 = getCompoundInQueryAt(i);
145                                C c2 = getCompoundInTargetAt(i);
146
147                                if ( c1 instanceof AminoAcidCompound && c2 instanceof AminoAcidCompound) {
148                                        short value = matrix.getValue((AminoAcidCompound)c1, (AminoAcidCompound)c2);
149                                        if ( value > 0)
150                                                similars++;
151                                } else {
152
153                                        if (getCompoundSet().compoundsEquivalent(c1,c2)) {
154                                                similars++;
155                                        }
156                                }
157                        }
158                        getQuery().clearCache();
159                        getTarget().clearCache();
160                }
161                return similars;
162        }
163
164        @Override
165        public AlignedSequence<S, C> getQuery() {
166                return getAlignedSequence(1);
167        }
168
169        @Override
170        public AlignedSequence<S, C> getTarget() {
171                return getAlignedSequence(2);
172        }
173
174}