<commit_before>package org.broadinstitute.sting.secondarybase;

import org.broadinstitute.sting.utils.QualityUtils;
import org.broadinstitute.sting.utils.Utils;

/**
 * FourProb represents four base hypotheses, their probabilities, and the ranking among one another.
 *
 * @author <NAME>
 */
public class FourProb {
    private double[] baseProbs;
    private int[] baseIndices;

    /**
     * Constructor for FourProb.
     *
     * @param baseLikes  the unsorted base hypothesis probabilities (in ACGT order).
     */
    public FourProb(double[][] baseLikes) {
        double[] baseProbs = new double[4];
        for (int baseCurIndex = 0; baseCurIndex < 4; baseCurIndex++) {
            for (int basePrevIndex = 0; basePrevIndex < baseLikes.length; basePrevIndex++) {
                baseProbs[baseCurIndex] += baseLikes[basePrevIndex][baseCurIndex];
            }
        }

        int[] baseIndices = {0, 1, 2, 3};
        
        Integer[] perm = Utils.SortPermutation(baseProbs);
        double[] ascendingBaseProbs = Utils.PermuteArray(baseProbs, perm);
        int[] ascendingBaseIndices = Utils.PermuteArray(baseIndices, perm);

        this.baseProbs = new double[4];
        this.baseIndices = new int[4];

        for (int i = 0; i < 4; i++) {
            this.baseProbs[i] = ascendingBaseProbs[3 - i];
            this.baseIndices[i] = ascendingBaseIndices[3 - i];
        }
    }

    /**
     * Returns the index of the base at the specified rank.
     *
     * @param rank (0 = best, 3 = worst) the rank of the base whose index should be returned
     * @return the index (0, 1, 2, 3).
     */
    public int indexAtRank(int rank) { return baseIndices[rank]; }

    /**
     * Returns the base label of the base at the specified rank.
     *
     * @param rank (0 = best, 3 = worst) the rank of the base whose index should be returned
     * @return the base label (A, C, G, T).
     */
    public char baseAtRank(int rank) { return baseIndexToBase(indexAtRank(rank)); }

    /**
     * Returns the probability of the base at the specified rank.
     *
     * @param rank (0 = best, 3 = worst) the rank of the base whose index should be returned
     * @return the probability of the base (0.0-1.0)
     */
    public double probAtRank(int rank) { return baseProbs[rank]; }

    /**
     * Returns the quality score of the base at the specified rank.
     *
     * @param rank (0 = best, 3 = worst) the rank of the base whose index should be returned
     * @return the quality score of the base (0-40)
     */
    public byte qualAtRank(int rank) { return QualityUtils.probToQual(probAtRank(rank)); }

    /**
     * A utility method to convert a base index into a base label.
     *
     * @param baseIndex the index of the base (0, 1, 2, 3).
     * @return A, C, G, T, or '.' if the base index can't be understood.
     */
    private char baseIndexToBase(int baseIndex) {
        switch (baseIndex) {
            case 0: return 'A';
            case 1: return 'C';
            case 2: return 'G';
            case 3: return 'T';
            default: return '.';
        }
    }

    /**
     * Prettily formats the FourProb info.
     * 
     * @return a prettily formatted Sting containing the base and quality score in rank order.
     */
    public String toString() {
        return (
                "[" + baseAtRank(0) + ":" + qualAtRank(0) + " "
                    + baseAtRank(1) + ":" + qualAtRank(1) + " "
                    + baseAtRank(2) + ":" + qualAtRank(2) + " "
                    + baseAtRank(3) + ":" + qualAtRank(3) + "]"
               );
    }
}<commit_msg>Replaced an expensive sort with an inexpensive direct computation.<commit_after>package org.broadinstitute.sting.secondarybase;

import org.broadinstitute.sting.utils.QualityUtils;
import org.broadinstitute.sting.utils.Utils;
import org.broadinstitute.sting.utils.BaseUtils;

/**
 * FourProb represents four base hypotheses, their probabilities, and the ranking among one another.
 *
 * @author <NAME>
 */
public class FourProb {
    private int[] baseIndices;
    private double[] baseProbs;

    /**
     * Constructor for FourProb.
     *
     * @param baseLikes  the unsorted base hypothesis probabilities (in ACGT order).
     */
    public FourProb(double[][] baseLikes) {
        double[] baseProbs = new double[4];
        for (int baseCurIndex = 0; baseCurIndex < 4; baseCurIndex++) {
            for (int basePrevIndex = 0; basePrevIndex < baseLikes.length; basePrevIndex++) {
                baseProbs[baseCurIndex] += baseLikes[basePrevIndex][baseCurIndex];
            }
        }

        this.baseProbs = new double[4];
        this.baseIndices = new int[4];

        // store this information in sorted form
        for (int i = 0; i < 4; i++) {
            if (baseProbs[i] > this.baseProbs[0]) {
                this.baseProbs[1] = this.baseProbs[0];
                this.baseIndices[1] = this.baseIndices[0];

                this.baseProbs[0] = baseProbs[i];
                this.baseIndices[0] = i;
            } else if (baseProbs[i] > this.baseProbs[1]) {
                this.baseProbs[2] = this.baseProbs[1];
                this.baseIndices[2] = this.baseIndices[1];

                this.baseProbs[1] = baseProbs[i];
                this.baseIndices[1] = i;
            } else if (baseProbs[i] > this.baseProbs[2]) {
                this.baseProbs[3] = this.baseProbs[2];
                this.baseIndices[3] = this.baseIndices[2];

                this.baseProbs[2] = baseProbs[i];
                this.baseIndices[2] = i;
            } else {
                this.baseProbs[3] = baseProbs[i];
                this.baseIndices[3] = i;
            }
        }
    }

    /**
     * Returns the index of the base at the specified rank.
     *
     * @param rank (0 = best, 3 = worst) the rank of the base whose index should be returned
     * @return the index (0, 1, 2, 3).
     */
    public int indexAtRank(int rank) { return baseIndices[rank]; }

    /**
     * Returns the base label of the base at the specified rank.
     *
     * @param rank (0 = best, 3 = worst) the rank of the base whose index should be returned
     * @return the base label (A, C, G, T).
     */
    //public char baseAtRank(int rank) { return baseIndexToBase(indexAtRank(rank)); }
    public char baseAtRank(int rank) { return BaseUtils.baseIndexToSimpleBase(indexAtRank(rank)); }

    /**
     * Returns the probability of the base at the specified rank.
     *
     * @param rank (0 = best, 3 = worst) the rank of the base whose index should be returned
     * @return the probability of the base (0.0-1.0)
     */
    public double probAtRank(int rank) { return baseProbs[rank]; }

    /**
     * Returns the quality score of the base at the specified rank.
     *
     * @param rank (0 = best, 3 = worst) the rank of the base whose index should be returned
     * @return the quality score of the base (0-40)
     */
    public byte qualAtRank(int rank) { return QualityUtils.probToQual(probAtRank(rank)); }

    /**
     * Prettily formats the FourProb info.
     * 
     * @return a prettily formatted Sting containing the base and quality score in rank order.
     */
    public String toString() {
        return (
                "[" + baseAtRank(0) + ":" + probAtRank(0) + " "
                    + baseAtRank(1) + ":" + probAtRank(1) + " "
                    + baseAtRank(2) + ":" + probAtRank(2) + " "
                    + baseAtRank(3) + ":" + probAtRank(3) + "]"
               );
    }
}
{'fraction_non_alphanumeric': 0.11626978847944659, 'fraction_numerical': 0.014234402022083278, 'mean_word_length': 2.1456066945606693, 'pattern_counts': {'":': 8, '<': 11, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5105793', 'n_tokens_mistral': 2342, 'n_tokens_neox': 2248, 'n_words': 685}