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 */
021package org.biojava.nbio.alignment;
022
023import org.biojava.nbio.alignment.template.AbstractScorer;
024import org.biojava.nbio.alignment.template.PairwiseSequenceScorer;
025import org.biojava.nbio.core.alignment.template.SequencePair;
026import org.biojava.nbio.core.alignment.template.SubstitutionMatrix;
027import org.biojava.nbio.core.sequence.template.Compound;
028import org.biojava.nbio.core.sequence.template.Sequence;
029
030/**
031 * Scores using a substitution matrix. Specifically, the score is the sum of the substitution matrix entries
032 * corresponding to the alignment. Gaps are scored according to the substitution matrix, just as matches and mismatches.
033 * @author dmyersturnbull
034 *
035 * @param <S>
036 * @param <C>
037 */
038public class SubstitutionMatrixScorer<S extends Sequence<C>, C extends Compound> extends AbstractScorer
039implements PairwiseSequenceScorer<S, C> {
040
041        private final SubstitutionMatrix<C> matrix;
042
043        private S query;
044        private S target;
045        private double score;
046
047        public SubstitutionMatrixScorer(SequencePair<S, C> pair, SubstitutionMatrix<C> matrix) {
048                super();
049                this.query = pair.getQuery().getOriginalSequence();
050                this.target = pair.getTarget().getOriginalSequence();
051                this.matrix = matrix;
052                for (int i = 1; i <= pair.getLength(); i++) {
053                        C query = pair.getCompoundAt(1, i);
054                        C target = pair.getCompoundAt(2, i);
055                        score += matrix.getValue(query, target);
056                }
057        }
058
059        /**
060         * @return The maximum score the query could be assigned when aligned against any target sequence.
061         */
062        @Override
063        public double getMaxScore() {
064                // assume nothing about the matrix
065                double score = 0;
066                for (C queryC : query.getAsList()) {
067                        short max = Short.MIN_VALUE;
068                        for (Short value : matrix.getRow(queryC).values()) {
069                                if (value > max) max = value;
070                        }
071                        score += max;
072                }
073                return score;
074        }
075
076        /**
077         * @return The minimum score the query could be assigned when aligned against any target sequence.
078         */
079        @Override
080        public double getMinScore() {
081                // assume nothing about the matrix
082                double score = 0;
083                for (C queryC : query.getAsList()) {
084                        short min = Short.MAX_VALUE;
085                        for (Short value : matrix.getRow(queryC).values()) {
086                                if (value < min) min = value;
087                        }
088                        score += min;
089                }
090                return score;
091        }
092
093        @Override
094        public double getScore() {
095                return score;
096        }
097
098        @Override
099        public S getQuery() {
100                return query;
101        }
102
103        @Override
104        public S getTarget() {
105                return target;
106        }
107
108}