package mlproject.hmm;

import java.util.LinkedList;
import java.util.List;

public class EvidenceStateModel extends StateModel{
    private boolean[][] transitionMatrix;
    private String[] stateNames;
    private int[][] fixedCounts;
    
    public EvidenceStateModel(boolean allowATAStart){
        initialize(allowATAStart);
    }
    

    public void initialize(boolean allowATAStart) {
        stateNames = 
                new String[]{
                    "0:Intergenic",
                    "1:Plus start A",
                    "2:Plus start T",
                    "3:Plus start G/A",
                    "4:Plus exon 0 T",
                    "5:Plus exon 0 T'",
                    "6:Plus exon 1 TA",
                    "7:Plus exon 1 TA'",
                    "8:Plus exon 1 T'*",
                    "9:Plus exon 2 TA[^AG]",
                    "10:Plus exon 2 TA'*",
                    "11:Plus exon 2 T'**",
                    
                    
                    "Plus intron 0 pad 5prime 0",
                    "Plus intron 0 pad 5prime 1",
                    "Plus intron 0 pad 5prime 2",
                    "Plus intron 0 pad 5prime 3",
                    "Plus intron 0 pad 5prime 4",
                    "Plus intron 0 pad 5prime 5",
                    "Plus intron 0",
                    "Plus intron 0 pad 3prime 8",
                    "Plus intron 0 pad 3prime 7",
                    "Plus intron 0 pad 3prime 6",
                    "Plus intron 0 pad 3prime 5",
                    "Plus intron 0 pad 3prime 4",
                    "Plus intron 0 pad 3prime 3",
                    "Plus intron 0 pad 3prime 2",
                    "Plus intron 0 pad 3prime 1",
                    "Plus intron 0 pad 3prime 0",
                    
                    "Plus intron 1 T pad 5prime 0 ",
                    "Plus intron 1 T pad 5prime 1 ",
                    "Plus intron 1 T pad 5prime 2 ",
                    "Plus intron 1 T pad 5prime 3 ",
                    "Plus intron 1 T pad 5prime 4 ",
                    "Plus intron 1 T pad 5prime 5 ",
                    "Plus intron 1 T ",
                    "Plus intron 1 T pad 3prime 8 ",
                    "Plus intron 1 T pad 3prime 7 ",
                    "Plus intron 1 T pad 3prime 6 ",
                    "Plus intron 1 T pad 3prime 5 ",
                    "Plus intron 1 T pad 3prime 4 ",
                    "Plus intron 1 T pad 3prime 3 ",
                    "Plus intron 1 T pad 3prime 2 ",
                    "Plus intron 1 T pad 3prime 1 ",
                    "Plus intron 1 T pad 3prime 0 ",
                    
        "Plus intron 1 T' pad 5prime 0 ",
        "Plus intron 1 T' pad 5prime 1 ",
        "Plus intron 1 T' pad 5prime 2 ",
        "Plus intron 1 T' pad 5prime 3 ",
        "Plus intron 1 T' pad 5prime 4 ",
        "Plus intron 1 T' pad 5prime 5 ",
        "Plus intron 1 T' ",
        "Plus intron 1 T' pad 3prime 8 ",
        "Plus intron 1 T' pad 3prime 7 ",
        "Plus intron 1 T' pad 3prime 6 ",
        "Plus intron 1 T' pad 3prime 5 ",
        "Plus intron 1 T' pad 3prime 4 ",
        "Plus intron 1 T' pad 3prime 3 ",
        "Plus intron 1 T' pad 3prime 2 ",
        "Plus intron 1 T' pad 3prime 1 ",
        "Plus intron 1 T' pad 3prime 0 ",

                    "Plus intron 2 TA pad 5prime 0",
                    "Plus intron 2 TA pad 5prime 1",
                    "Plus intron 2 TA pad 5prime 2",
                    "Plus intron 2 TA pad 5prime 3",
                    "Plus intron 2 TA pad 5prime 4",
                    "Plus intron 2 TA pad 5prime 5",
                    "Plus intron 2 TA",
                    "Plus intron 2 TA pad 3prime 8",
                    "Plus intron 2 TA pad 3prime 7",
                    "Plus intron 2 TA pad 3prime 6",
                    "Plus intron 2 TA pad 3prime 5",
                    "Plus intron 2 TA pad 3prime 4",
                    "Plus intron 2 TA pad 3prime 3",
                    "Plus intron 2 TA pad 3prime 2",
                    "Plus intron 2 TA pad 3prime 1",
                    "Plus intron 2 TA pad 3prime 0",
                    
        "Plus intron 2 TA' pad 5prime 0",
        "Plus intron 2 TA' pad 5prime 1",
        "Plus intron 2 TA' pad 5prime 2",
        "Plus intron 2 TA' pad 5prime 3",
        "Plus intron 2 TA' pad 5prime 4",
        "Plus intron 2 TA' pad 5prime 5",
        "Plus intron 2 TA'",
        "Plus intron 2 TA' pad 3prime 8",
        "Plus intron 2 TA' pad 3prime 7",
        "Plus intron 2 TA' pad 3prime 6",
        "Plus intron 2 TA' pad 3prime 5",
        "Plus intron 2 TA' pad 3prime 4",
        "Plus intron 2 TA' pad 3prime 3",
        "Plus intron 2 TA' pad 3prime 2",
        "Plus intron 2 TA' pad 3prime 1",
        "Plus intron 2 TA' pad 3prime 0",
                    
        "Plus intron 2 T'* pad 5prime 0",
        "Plus intron 2 T'* pad 5prime 1",
        "Plus intron 2 T'* pad 5prime 2",
        "Plus intron 2 T'* pad 5prime 3",
        "Plus intron 2 T'* pad 5prime 4",
        "Plus intron 2 T'* pad 5prime 5",
        "Plus intron 2 T'*",
        "Plus intron 2 T'* pad 3prime 8",
        "Plus intron 2 T'* pad 3prime 7",
        "Plus intron 2 T'* pad 3prime 6",
        "Plus intron 2 T'* pad 3prime 5",
        "Plus intron 2 T'* pad 3prime 4",
        "Plus intron 2 T'* pad 3prime 3",
        "Plus intron 2 T'* pad 3prime 2",
        "Plus intron 2 T'* pad 3prime 1",
        "Plus intron 2 T'* pad 3prime 0",
                    
                    "Plus stop T",
                    "Plus stop A",
                    "Plus stop A/G",
                    
                    "111:Minus stop T/C",
                    "112:Minus stop T",
                    "113:Minus stop A",
                    "114:Minus exon 2 T/C",
                    "115:Minus exon 2 A/G",
                    "116:Minus exon 1 T/CT",
                    "117:Minus exon 1 T/CT'",
                    "118:Minus exon 1 A/G*",
                    "119:Minus exon 0 T/CTA'",
                    "120:Minus exon 0 T/CT'*",
                    "121:Minus exon 0 A/G**",
                    
                    "Minus intron 0 pad 3prime 0",
                    "Minus intron 0 pad 3prime 1",
                    "Minus intron 0 pad 3prime 2",
                    "Minus intron 0 pad 3prime 3",
                    "Minus intron 0 pad 3prime 4",
                    "Minus intron 0 pad 3prime 5",
                    "Minus intron 0 pad 3prime 6",
                    "Minus intron 0 pad 3prime 7",
                    "Minus intron 0 pad 3prime 8",
                    "Minus intron 0",
                    "Minus intron 0 pad 5prime 5",
                    "Minus intron 0 pad 5prime 4",
                    "Minus intron 0 pad 5prime 3",
                    "Minus intron 0 pad 5prime 2",
                    "Minus intron 0 pad 5prime 1",
                    "Minus intron 0 pad 5prime 0",
                    
                    "Minus intron 1 T/CT pad 3prime 0",
                    "Minus intron 1 T/CT pad 3prime 1",
                    "Minus intron 1 T/CT pad 3prime 2",
                    "Minus intron 1 T/CT pad 3prime 3",
                    "Minus intron 1 T/CT pad 3prime 4",
                    "Minus intron 1 T/CT pad 3prime 5",
                    "Minus intron 1 T/CT pad 3prime 6",
                    "Minus intron 1 T/CT pad 3prime 7",
                    "Minus intron 1 T/CT pad 3prime 8",
                    "Minus intron 1 T/CT",
                    "Minus intron 1 T/CT pad 5prime 5",
                    "Minus intron 1 T/CT pad 5prime 4",
                    "Minus intron 1 T/CT pad 5prime 3",
                    "Minus intron 1 T/CT pad 5prime 2",
                    "Minus intron 1 T/CT pad 5prime 1",
                    "Minus intron 1 T/CT pad 5prime 0",
                    
        "Minus intron 1 T/CT' pad 3prime 0",
        "Minus intron 1 T/CT' pad 3prime 1",
        "Minus intron 1 T/CT' pad 3prime 2",
        "Minus intron 1 T/CT' pad 3prime 3",
        "Minus intron 1 T/CT' pad 3prime 4",
        "Minus intron 1 T/CT' pad 3prime 5",
        "Minus intron 1 T/CT' pad 3prime 6",
        "Minus intron 1 T/CT' pad 3prime 7",
        "Minus intron 1 T/CT' pad 3prime 8",
        "Minus intron 1 T/CT'",
        "Minus intron 1 T/CT' pad 5prime 5",
        "Minus intron 1 T/CT' pad 5prime 4",
        "Minus intron 1 T/CT' pad 5prime 3",
        "Minus intron 1 T/CT' pad 5prime 2",
        "Minus intron 1 T/CT' pad 5prime 1",
        "Minus intron 1 T/CT' pad 5prime 0",
                    
        "Minus intron 1 A/G* pad 3prime 0",
        "Minus intron 1 A/G* pad 3prime 1",
        "Minus intron 1 A/G* pad 3prime 2",
        "Minus intron 1 A/G* pad 3prime 3",
        "Minus intron 1 A/G* pad 3prime 4",
        "Minus intron 1 A/G* pad 3prime 5",
        "Minus intron 1 A/G* pad 3prime 6",
        "Minus intron 1 A/G* pad 3prime 7",
        "Minus intron 1 A/G* pad 3prime 8",
        "Minus intron 1 A/G*",
        "Minus intron 1 A/G* pad 5prime 5",
        "Minus intron 1 A/G* pad 5prime 4",
        "Minus intron 1 A/G* pad 5prime 3",
        "Minus intron 1 A/G* pad 5prime 2",
        "Minus intron 1 A/G* pad 5prime 1",
        "Minus intron 1 A/G* pad 5prime 0",
                    
                    "Minus intron 2 T/C pad 3prime 0",
                    "Minus intron 2 T/C pad 3prime 1",
                    "Minus intron 2 T/C pad 3prime 2",
                    "Minus intron 2 T/C pad 3prime 3",
                    "Minus intron 2 T/C pad 3prime 4",
                    "Minus intron 2 T/C pad 3prime 5",
                    "Minus intron 2 T/C pad 3prime 6",
                    "Minus intron 2 T/C pad 3prime 7",
                    "Minus intron 2 T/C pad 3prime 8",
                    "Minus intron 2 T/C",
                    "Minus intron 2 T/C pad 5prime 5",
                    "Minus intron 2 T/C pad 5prime 4",
                    "Minus intron 2 T/C pad 5prime 3",
                    "Minus intron 2 T/C pad 5prime 2",
                    "Minus intron 2 T/C pad 5prime 1",
                    "Minus intron 2 T/C pad 5prime 0",
                    
        "Minus intron 2 A/G pad 3prime 0",
        "Minus intron 2 A/G pad 3prime 1",
        "Minus intron 2 A/G pad 3prime 2",
        "Minus intron 2 A/G pad 3prime 3",
        "Minus intron 2 A/G pad 3prime 4",
        "Minus intron 2 A/G pad 3prime 5",
        "Minus intron 2 A/G pad 3prime 6",
        "Minus intron 2 A/G pad 3prime 7",
        "Minus intron 2 A/G pad 3prime 8",
        "Minus intron 2 A/G",
        "Minus intron 2 A/G pad 5prime 5",
        "Minus intron 2 A/G pad 5prime 4",
        "Minus intron 2 A/G pad 5prime 3",
        "Minus intron 2 A/G pad 5prime 2",
        "Minus intron 2 A/G pad 5prime 1",
        "Minus intron 2 A/G pad 5prime 0",
                    
                    "Minus start C/T",
                    "Minus start A",
                    "Minus start T"
                    
                };
        
            
        transitionMatrix = new boolean[221][221];
        transitionMatrix[0][0] = true;
        transitionMatrix[0][1] = true;
        transitionMatrix[0][111] = true;
        transitionMatrix[1][2] = true;
        transitionMatrix[2][3] = true;
        transitionMatrix[3][4] = true;
        transitionMatrix[3][5] = true;
        transitionMatrix[4][6] = true;
        transitionMatrix[4][7] = true;
        transitionMatrix[4][28] = true;
        transitionMatrix[5][8] = true;
        transitionMatrix[5][44] = true;
        transitionMatrix[6][9] = true;
        transitionMatrix[6][60] = true;
        transitionMatrix[7][10] = true;
        transitionMatrix[7][76] = true;
        transitionMatrix[8][11] = true;
        transitionMatrix[8][92] = true;
        transitionMatrix[9][4] = true;
        transitionMatrix[9][5] = true;
        transitionMatrix[9][12] = true;
        transitionMatrix[9][108] = true;
        transitionMatrix[10][4] = true;
        transitionMatrix[10][5] = true;
        transitionMatrix[10][12] = true;
        transitionMatrix[10][108] = true;
        transitionMatrix[11][4] = true;
        transitionMatrix[11][5] = true;
        transitionMatrix[11][12] = true;
        transitionMatrix[11][108] = true;
        
        //intron 0
        int i = 12;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+5][i+7] = true;
        transitionMatrix[i+6][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][4] = true;
        transitionMatrix[i+15][5] = true;
        
        
        //intron 1 T
        i = 28;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+5][i+7] = true;
        transitionMatrix[i+6][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][6] = true;
        transitionMatrix[i+15][7] = true;
        
        //intron 1 T'
        i = 44;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+5][i+7] = true;
        transitionMatrix[i+6][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][8] = true;
        
        
        
        //intron 2 TA
        i = 60;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+5][i+7] = true;
        transitionMatrix[i+6][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][9] = true;
        
        //intron 2 TA'
        i = 76;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+5][i+7] = true;
        transitionMatrix[i+6][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][10] = true;
        
        //intron 2 T'*
        i = 92;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+5][i+7] = true;
        transitionMatrix[i+6][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][11] = true;
        
        
        //plus stop codon
        i=108;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][0] = true;
        
        // minus start codon + exons
        i=111;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+2][i+4] = true;
        transitionMatrix[i+3][i+5] = true;
        transitionMatrix[i+3][i+6] = true;
        transitionMatrix[i+3][186] = true;
        transitionMatrix[i+4][i+7] = true;
        transitionMatrix[i+4][202] = true;
        transitionMatrix[i+5][i+8] = true;
        transitionMatrix[i+5][138] = true;
        transitionMatrix[i+6][i+9] = true;
        transitionMatrix[i+6][154] = true;
        transitionMatrix[i+7][i+10] = true;
        transitionMatrix[i+7][170] = true;
        transitionMatrix[i+8][i+3] = true;
        transitionMatrix[i+8][i+4] = true;
        transitionMatrix[i+8][122] = true;
        transitionMatrix[i+8][218] = true;
        transitionMatrix[i+9][i+3] = true;
        transitionMatrix[i+9][i+4] = true;
        transitionMatrix[i+9][122] = true;
        transitionMatrix[i+9][218] = true;
        transitionMatrix[i+10][i+3] = true;
        transitionMatrix[i+10][i+4] = true;
        transitionMatrix[i+10][122] = true;
        transitionMatrix[i+10][218] = true;
        
        // minus intron 0
        i = 122;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+8][i+10] = true;
        transitionMatrix[i+9][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][114] = true;
        transitionMatrix[i+15][115] = true;
        
        // minus intron 1 T/CT
        i = 138;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+8][i+10] = true;
        transitionMatrix[i+9][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][119] = true;
        
        // minus intron 1 T/CT'
        i = 154;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+8][i+10] = true;
        transitionMatrix[i+9][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][120] = true;
        
        // minus intron 1 A/G*
        i = 170;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+8][i+10] = true;
        transitionMatrix[i+9][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][121] = true;
        
        // minus intron 2 T/C
        i = 186;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+8][i+10] = true;
        transitionMatrix[i+9][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][116] = true;
        transitionMatrix[i+15][117] = true;
        
        // minus intron 2 A/G
        i = 202;
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][i+3] = true;
        transitionMatrix[i+3][i+4] = true;
        transitionMatrix[i+4][i+5] = true;
        transitionMatrix[i+5][i+6] = true;
        transitionMatrix[i+6][i+7] = true;
        transitionMatrix[i+7][i+8] = true;
        transitionMatrix[i+8][i+9] = true;
        transitionMatrix[i+8][i+10] = true;
        transitionMatrix[i+9][i+9] = true;
        transitionMatrix[i+9][i+10] = true;
        transitionMatrix[i+10][i+11] = true;
        transitionMatrix[i+11][i+12] = true;
        transitionMatrix[i+12][i+13] = true;
        transitionMatrix[i+13][i+14] = true;
        transitionMatrix[i+14][i+15] = true;
        transitionMatrix[i+15][118] = true;
        
        
        i=218;       
        transitionMatrix[i][i+1] = true;
        transitionMatrix[i+1][i+2] = true;
        transitionMatrix[i+2][0] = true;
        
        
        fixedCounts = new int[221][4];
        
        fixedCounts[1][0] = COUNTS_ALL;
        fixedCounts[2][3] = COUNTS_ALL;
        
        if(allowATAStart){
            fixedCounts[3][1] = COUNTS_ZERO;
            fixedCounts[3][3] = COUNTS_ZERO;
        } else {
            fixedCounts[3][2] = COUNTS_ALL;
        }
        
        fixedCounts[4][3] = COUNTS_ALL;
        fixedCounts[5][3] = COUNTS_ZERO;
        fixedCounts[6][0] = COUNTS_ALL;
        fixedCounts[7][0] = COUNTS_ZERO;
        fixedCounts[9][0] = COUNTS_ZERO;
        fixedCounts[9][2] = COUNTS_ZERO;
        fixedCounts[108][3] = COUNTS_ALL;
        fixedCounts[109][0] = COUNTS_ALL;
        fixedCounts[110][1] = COUNTS_ZERO;
        fixedCounts[110][3] = COUNTS_ZERO;
        
        fixedCounts[111][0] = COUNTS_ZERO;
        fixedCounts[111][2] = COUNTS_ZERO;
        fixedCounts[112][3] = COUNTS_ALL;
        fixedCounts[113][0] = COUNTS_ALL;
        fixedCounts[114][0] = COUNTS_ZERO;
        fixedCounts[114][2] = COUNTS_ZERO;
        fixedCounts[115][1] = COUNTS_ZERO;
        fixedCounts[115][3] = COUNTS_ZERO;
        fixedCounts[116][3] = COUNTS_ALL;
        fixedCounts[117][3] = COUNTS_ZERO;
        fixedCounts[119][0] = COUNTS_ZERO;
        
        if(allowATAStart){
            fixedCounts[218][0] = COUNTS_ZERO;
            fixedCounts[218][2] = COUNTS_ZERO;
        } else {
            fixedCounts[218][1] = COUNTS_ALL;
        }
       
        fixedCounts[219][0] = COUNTS_ALL;
        fixedCounts[220][3] = COUNTS_ALL;
    }

    public String[] getStateNames() {
        return stateNames;
    }

    public int getNStates() {
        return 221;
    }

    public int[][] getFixedStateNucleotideCounts() {
        return fixedCounts;
    }

    public boolean[][] getTransitionMatrix() {
        return transitionMatrix;
    }

    public int[] getIntergenicStates() {
        return new int[]{0};
    }

    public int[] getPlusStartCodonStates() {
        return new int[]{1,2,3}; //dont include stop codon
    }

    public int[] getMinusStartCodonStates() {
        return new int[]{218,219,220}; //dont include stop codon
    }
    
    public int[] getPlusStopCodonStates() {
        return new int[]{108,109,110}; //dont include stop codon
    }

    public int[] getMinusStopCodonStates() {
        return new int[]{111,112,113}; //dont include stop codon
    }

    public int[] getPlusExonicStates() {
        return new int[]{1,2,3,4,5,6,7,8,9,10,11}; //dont include stop codon
    }

    public int[] getMinusExonicStates() {
        return new int[]{114,115,116,117,118,119,120,121,218,219,220}; //dont include stop codon
    }

    public int[] getPlusIntronicStates() {
        int[] intronStates = new int[16*6];
        for(int i=0;i<16*6;i++){
            intronStates[i] = i+12;
        }
        return intronStates;
    }

    public int[] getMinusIntronicStates() {
        int[] intronStates = new int[16*6];
        for(int i=0;i<16*6;i++){
            intronStates[i] = i+122;
        }
        return intronStates;
    }

    public int[] getPlusExon0States() {
        return new int[]{1,4,5,108};
    }

    public int[] getPlusExon1States() {
        return new int[]{2,6,7,8,109};
    }

    public int[] getPlusExon2States() {
        return new int[]{3,9,10,11,110};
    }

    public int[] getMinusExon0States() {
        return new int[]{113,119,120,121,220};
    }

    public int[] getMinusExon1States() {
        return new int[]{112,116,117,118,219};
    }

    public int[] getMinusExon2States() {
        return new int[]{111,114,115,218};
    }

    public int getFirstMinusState() {
        return 111;
    }
    
    
    public int[][] getJoinedEmissionStates(){
        /*
        int[] plusIntron = new int[16*3];
        for(int i=0;i<16*3;i++){
            plusIntron[i] = 17 + i; 
        }
        
        int[] minusIntron = new int[16*3];
        for(int i=0;i<16*3;i++){
            minusIntron[i] = 86 + i; 
        }
        
        return new int[][]{plusIntron,minusIntron};
        */
        LinkedList<List<Integer>> list = new LinkedList();
        
        for(int j=0;j<5;j++){
            List<Integer> joined = new LinkedList<Integer>();
            for(int i=0; i<2; i++){
                joined.add(28 + i*16 + j);
            }
            list.add(joined);
        }
        for(int j=6;j<15;j++){
            List<Integer> joined = new LinkedList<Integer>();
            for(int i=0; i<2; i++){
                joined.add(28 + i*16 + j);
            }
            list.add(joined);
        }
        
        for(int j=0;j<5;j++){
            List<Integer> joined = new LinkedList<Integer>();
            for(int i=0; i<3; i++){
                joined.add(44 + i*16 + j);
            }
            list.add(joined);
        }
        for(int j=6;j<15;j++){
            List<Integer> joined = new LinkedList<Integer>();
            for(int i=0; i<3; i++){
                joined.add(44 + i*16 + j);
            }
            list.add(joined);
        }
        
        for(int j=0;j<9;j++){
            List<Integer> joined = new LinkedList<Integer>();
            for(int i=0; i<3; i++){
                joined.add(138 + i*16 + j);
            }
            list.add(joined);
        }
        for(int j=10;j<15;j++){
            List<Integer> joined = new LinkedList<Integer>();
            for(int i=0; i<3; i++){
                joined.add(138 + i*16 + j);
            }
            list.add(joined);
        }
        
        for(int j=0;j<9;j++){
            List<Integer> joined = new LinkedList<Integer>();
            for(int i=0; i<2; i++){
                joined.add(186 + i*16 + j);
            }
            list.add(joined);
        }
        for(int j=10;j<15;j++){
            List<Integer> joined = new LinkedList<Integer>();
            for(int i=0; i<2; i++){
                joined.add(186 + i*16 + j);
            }
            list.add(joined);
        }
    
        List<Integer> joined = new LinkedList<Integer>();
        for(int i=0;i<6;i++){
            joined.add(i*16+12+5);
        }
        list.add(joined);
        
        joined = new LinkedList<Integer>();
        for(int i=0;i<6;i++){
            joined.add(i*16+122+9);
        }
        
        list.add(joined);
        
        int[][] result = new int[list.size()][];
        for(int i=0;i<list.size();i++){
            List<Integer> list2 = list.get(i);
            result[i] = new int[list2.size()];
            for(int j=0;j<list2.size();j++)
                result[i][j] = list2.get(j);
        }
         return result;
    }
    
    public int[] getPlusInitialIntronStates() {
        int[] initial = new int[6];
        for(int i=0;i<6;i++){
            initial[i] = i*16+12;
        }
        return initial;
    }

    public int[] getMinusInitialIntronStates() {
        int[] initial = new int[6];
        for(int i=0;i<6;i++){
            initial[i] = i*16+122;
        }
        return initial;
    }
}
