// File: tedsharpe[P]ORFCall/ORFCall.cc
// Function: (anonymous namespace)::Reference::readRefSeq(char const*)
void Reference::readRefSeq( char const* refFile )
{
    std::ifstream ifs(refFile,std::ios_base::in|
                                std::ios_base::binary|
                                std::ios_base::ate);
    if ( !ifs )
        FatalErr("Can't open reference file: " << refFile);
    mRefSeq.reserve(ifs.tellg());
    ifs.seekg(0);
    std::string line;
    if ( !std::getline(ifs,line) )
        FatalErr("Can't read reference file.");
    if ( line.empty() || line[0] != '>' )
        FatalErr("Reference file doesn't begin with a fasta comment.");
    unsigned lineNo = 0;
    bool inORF = false;
    while ( std::getline(ifs,line) )
    {
        ++lineNo;
        for ( char chr : line )
        {
            if ( std::isspace(chr) )
                continue;

            switch (chr)
            {
            case 'a': case 'A': mRefSeq.push_back(0); break;
            case 'c': case 'C': mRefSeq.push_back(1); break;
            case 'g': case 'G': mRefSeq.push_back(2); break;
            case 't': case 'T':
            case 'u': case 'U': mRefSeq.push_back(3); break;
            case '[':
                if ( inORF )
                    FatalErr("Nested ORF segment at line " << lineNo);
                inORF=true; mORF.push_back(Exon{mRefSeq.size(),0}); break;
            case ']':
                if ( !inORF )
                    FatalErr("Unopened ORF segment at line " << lineNo);
                inORF=false; mORF.back().mEnd = mRefSeq.size(); break;
            default:
                FatalErr("Gibberish in reference file line " << lineNo << ":\n"
                        << line);
            }
        }
    }
    if ( inORF )
        FatalErr("Unclosed ORF segment.");
    if ( mORF.empty() )
    {
        std::cerr << "No ORF marked -- using entire reference sequence as ORF"
                << std::endl;
        mORF.push_back(Exon{0,mRefSeq.size()});
    }
    if ( !ifs.eof() )
        FatalErr("Failed to read reference file to the end.");

    if ( mRefSeq.size() < mK )
        FatalErr("There are only " << mRefSeq.size()
                    << "bases in the reference file.  K is too big.");

    // add sentinel
    mORF.push_back(Exon{mRefSeq.size(),mRefSeq.size()});

    size_t orfSize = 0ul;
    for ( Exon const& exon : mORF )
        orfSize += exon.size();
    if ( orfSize % 3 )
        FatalErr("There are " << orfSize <<
                " bases in the ORF, which isn't divisible by 3.");

    Sequence orfSeq;
    orfSeq.reserve(orfSize);
    for ( Exon const& exon : mORF )
        std::copy(mRefSeq.begin()+exon.mBegin,mRefSeq.begin()+exon.mEnd,
                    std::back_inserter(orfSeq) );

    size_t nCodons = orfSize / 3;
    mWTCodons.reserve(nCodons);
    for ( Kmer itr(orfSeq.begin()), end(orfSeq.end()); itr < end; itr += 3 )
        mWTCodons.push_back(codonFor(itr));
}

// Assembly:
subq $0x508, %rsp            # imm = 0x508
movq %rdi, 0x500(%rsp)
movq %rsi, 0x4f8(%rsp)
movq 0x500(%rsp), %rax
movq %rax, 0x168(%rsp)
movq 0x4f8(%rsp), %rax
movq %rax, 0x170(%rsp)
movl $0x8, %edi
movl $0x4, %esi
callq 0x17350
movl %eax, %edi
movl $0x2, %esi
callq 0x17350
movq 0x170(%rsp), %rsi
movl %eax, %edx
leaq 0x2f0(%rsp), %rdi
callq 0x4540
movq 0x2f0(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x2f0(%rsp,%rax), %rdi
callq 0x4150
movb %al, 0x17f(%rsp)
jmp 0x7a8b
movb 0x17f(%rsp), %al
testb $0x1, %al
jne 0x7a98
jmp 0x7b0d
movq 0x25551(%rip), %rdi     # 0x2cff0
leaq 0x19c13(%rip), %rsi     # 0x216b9
callq 0x4290
movq %rax, 0x160(%rsp)
jmp 0x7ab5
movq 0x160(%rsp), %rdi
movq 0x4f8(%rsp), %rsi
callq 0x4290
movq %rax, 0x158(%rsp)
jmp 0x7ad4
movq 0x158(%rsp), %rdi
movq 0x254c5(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x7aea
movl $0x1, %edi
callq 0x42f0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2e8(%rsp)
movl %eax, 0x2e4(%rsp)
jmp 0x871a
movq 0x168(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x140(%rsp)
leaq 0x2f0(%rsp), %rdi
callq 0x44f0
movq %rdx, 0x148(%rsp)
movq %rax, 0x150(%rsp)
jmp 0x7b40
movq 0x148(%rsp), %rax
movq 0x150(%rsp), %rcx
movq %rcx, 0x2d0(%rsp)
movq %rax, 0x2d8(%rsp)
leaq 0x2d0(%rsp), %rdi
callq 0x17470
movq %rax, 0x138(%rsp)
jmp 0x7b77
movq 0x138(%rsp), %rsi
movq 0x140(%rsp), %rdi
callq 0x17370
jmp 0x7b8e
xorl %eax, %eax
movl %eax, %esi
leaq 0x2c0(%rsp), %rdi
callq 0x17480
jmp 0x7ba1
movq 0x2c0(%rsp), %rsi
movq 0x2c8(%rsp), %rdx
leaq 0x2f0(%rsp), %rdi
callq 0x4310
jmp 0x7bc0
leaq 0x2a0(%rsp), %rdi
movq %rdi, 0x128(%rsp)
callq 0x43a0
movq 0x128(%rsp), %rsi
leaq 0x2f0(%rsp), %rdi
callq 0x4050
movq %rax, 0x130(%rsp)
jmp 0x7bf4
movq 0x130(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x4150
movb %al, 0x127(%rsp)
jmp 0x7c14
movb 0x127(%rsp), %al
testb $0x1, %al
jne 0x7c21
jmp 0x7c77
movq 0x253c8(%rip), %rdi     # 0x2cff0
leaq 0x19aa6(%rip), %rsi     # 0x216d5
callq 0x4290
movq %rax, 0x118(%rsp)
jmp 0x7c3e
movq 0x118(%rsp), %rdi
movq 0x2535b(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x7c54
movl $0x1, %edi
callq 0x42f0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2e8(%rsp)
movl %eax, 0x2e4(%rsp)
jmp 0x870d
leaq 0x2a0(%rsp), %rdi
callq 0x44a0
testb $0x1, %al
jne 0x7cb3
xorl %eax, %eax
movl %eax, %esi
leaq 0x2a0(%rsp), %rdi
callq 0x45b0
movq %rax, 0x110(%rsp)
jmp 0x7ca3
movq 0x110(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x3e, %eax
je 0x7cf0
movq 0x25336(%rip), %rdi     # 0x2cff0
leaq 0x19a2f(%rip), %rsi     # 0x216f0
callq 0x4290
movq %rax, 0x108(%rsp)
jmp 0x7cd0
movq 0x108(%rsp), %rdi
movq 0x252c9(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x7ce6
movl $0x1, %edi
callq 0x42f0
movl $0x0, 0x29c(%rsp)
movb $0x0, 0x29b(%rsp)
leaq 0x2f0(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
callq 0x4050
movq %rax, 0x100(%rsp)
jmp 0x7d22
movq 0x100(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x4300
movb %al, 0xff(%rsp)
jmp 0x7d42
movb 0xff(%rsp), %al
testb $0x1, %al
jne 0x7d52
jmp 0x80d4
movl 0x29c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x29c(%rsp)
leaq 0x2a0(%rsp), %rax
movq %rax, 0x290(%rsp)
movq 0x290(%rsp), %rdi
callq 0x4230
movq %rax, 0x288(%rsp)
movq 0x290(%rsp), %rdi
callq 0x41a0
movq %rax, 0x280(%rsp)
leaq 0x288(%rsp), %rdi
leaq 0x280(%rsp), %rsi
callq 0x174b0
testb $0x1, %al
jne 0x7dbb
jmp 0x80cf
leaq 0x288(%rsp), %rdi
callq 0x174f0
movb (%rax), %al
movb %al, 0x27f(%rsp)
movsbl 0x27f(%rsp), %edi
callq 0x4030
cmpl $0x0, %eax
je 0x7de8
jmp 0x80bd
movsbl 0x27f(%rsp), %eax
addl $-0x41, %eax
movl %eax, %ecx
movq %rcx, 0xf0(%rsp)
subl $0x34, %eax
ja 0x8023
movq 0xf0(%rsp), %rax
leaq 0x192cb(%rip), %rcx     # 0x210e0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x168(%rsp), %rdi
addq $0x8, %rdi
movb $0x0, 0x27e(%rsp)
leaq 0x27e(%rsp), %rsi
callq 0x17500
jmp 0x7e41
jmp 0x80bb
movq 0x168(%rsp), %rdi
addq $0x8, %rdi
movb $0x1, 0x27d(%rsp)
leaq 0x27d(%rsp), %rsi
callq 0x17500
jmp 0x7e69
jmp 0x80bb
movq 0x168(%rsp), %rdi
addq $0x8, %rdi
movb $0x2, 0x27c(%rsp)
leaq 0x27c(%rsp), %rsi
callq 0x17500
jmp 0x7e91
jmp 0x80bb
movq 0x168(%rsp), %rdi
addq $0x8, %rdi
movb $0x3, 0x27b(%rsp)
leaq 0x27b(%rsp), %rsi
callq 0x17500
jmp 0x7eb9
jmp 0x80bb
testb $0x1, 0x29b(%rsp)
je 0x7f23
movq 0x25121(%rip), %rdi     # 0x2cff0
leaq 0x1984d(%rip), %rsi     # 0x21723
callq 0x4290
movq %rax, 0xe8(%rsp)
jmp 0x7ee5
movq 0xe8(%rsp), %rdi
movl 0x29c(%rsp), %esi
callq 0x4350
movq %rax, 0xe0(%rsp)
jmp 0x7f03
movq 0xe0(%rsp), %rdi
movq 0x25096(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x7f19
movl $0x1, %edi
callq 0x42f0
movq 0x168(%rsp), %rdi
movb $0x1, 0x29b(%rsp)
movq %rdi, %rax
addq $0x78, %rax
movq %rax, 0xd8(%rsp)
addq $0x8, %rdi
callq 0x17530
movq 0xd8(%rsp), %rdi
movq %rax, 0x268(%rsp)
movq $0x0, 0x270(%rsp)
leaq 0x268(%rsp), %rsi
callq 0x9db0
jmp 0x7f76
jmp 0x80bb
testb $0x1, 0x29b(%rsp)
jne 0x7fe0
movq 0x25064(%rip), %rdi     # 0x2cff0
leaq 0x197ac(%rip), %rsi     # 0x2173f
callq 0x4290
movq %rax, 0xd0(%rsp)
jmp 0x7fa2
movq 0xd0(%rsp), %rdi
movl 0x29c(%rsp), %esi
callq 0x4350
movq %rax, 0xc8(%rsp)
jmp 0x7fc0
movq 0xc8(%rsp), %rdi
movq 0x24fd9(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x7fd6
movl $0x1, %edi
callq 0x42f0
movq 0x168(%rsp), %rdi
movb $0x0, 0x29b(%rsp)
addq $0x8, %rdi
callq 0x17530
movq 0x168(%rsp), %rdi
movq %rax, 0xc0(%rsp)
addq $0x78, %rdi
callq 0x9de0
movq 0xc0(%rsp), %rcx
movq %rcx, 0x8(%rax)
jmp 0x80bb
movq 0x24fc6(%rip), %rdi     # 0x2cff0
leaq 0x1972c(%rip), %rsi     # 0x2175d
callq 0x4290
movq %rax, 0xb8(%rsp)
jmp 0x8040
movq 0xb8(%rsp), %rdi
movl 0x29c(%rsp), %esi
callq 0x4350
movq %rax, 0xb0(%rsp)
jmp 0x805e
movq 0xb0(%rsp), %rdi
leaq 0x19877(%rip), %rsi     # 0x218e4
callq 0x4290
movq %rax, 0xa8(%rsp)
jmp 0x807c
movq 0xa8(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
callq 0x4260
movq %rax, 0xa0(%rsp)
jmp 0x809b
movq 0xa0(%rsp), %rdi
movq 0x24efe(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x80b1
movl $0x1, %edi
callq 0x42f0
jmp 0x80bd
leaq 0x288(%rsp), %rdi
callq 0x17550
jmp 0x7d9d
jmp 0x7d03
testb $0x1, 0x29b(%rsp)
je 0x811b
movq 0x24f0b(%rip), %rdi     # 0x2cff0
leaq 0x19693(%rip), %rsi     # 0x2177f
callq 0x4290
movq %rax, 0x98(%rsp)
jmp 0x80fb
movq 0x98(%rsp), %rdi
movq 0x24e9e(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x8111
movl $0x1, %edi
callq 0x42f0
movq 0x168(%rsp), %rdi
addq $0x78, %rdi
callq 0x9e20
testb $0x1, %al
jne 0x8135
jmp 0x81b5
movq 0x24eb4(%rip), %rdi     # 0x2cff0
leaq 0x19652(%rip), %rsi     # 0x21795
callq 0x4290
movq %rax, 0x90(%rsp)
jmp 0x8152
movq 0x90(%rsp), %rdi
movq 0x24e47(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x8168
movq 0x168(%rsp), %rdi
movq %rdi, %rax
addq $0x78, %rax
movq %rax, 0x88(%rsp)
movq $0x0, 0x258(%rsp)
addq $0x8, %rdi
callq 0x17530
movq 0x88(%rsp), %rdi
movq %rax, 0x260(%rsp)
leaq 0x258(%rsp), %rsi
callq 0x9db0
jmp 0x81b3
jmp 0x81b5
movq 0x2f0(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x2f0(%rsp,%rax), %rdi
callq 0x4550
movb %al, 0x87(%rsp)
jmp 0x81d7
movb 0x87(%rsp), %al
testb $0x1, %al
jne 0x821b
jmp 0x81e4
movq 0x24e05(%rip), %rdi     # 0x2cff0
leaq 0x195db(%rip), %rsi     # 0x217cd
callq 0x4290
movq %rax, 0x78(%rsp)
jmp 0x81fe
movq 0x78(%rsp), %rdi
movq 0x24d9e(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x8211
movl $0x1, %edi
callq 0x42f0
movq 0x168(%rsp), %rdi
addq $0x8, %rdi
callq 0x17530
movq 0x168(%rsp), %rcx
movl (%rcx), %ecx
cmpq %rcx, %rax
jae 0x82af
movq 0x24dae(%rip), %rdi     # 0x2cff0
leaq 0x195ae(%rip), %rsi     # 0x217f7
callq 0x4290
movq %rax, 0x70(%rsp)
jmp 0x8255
movq 0x168(%rsp), %rdi
addq $0x8, %rdi
callq 0x17530
movq 0x70(%rsp), %rdi
movq %rax, %rsi
callq 0x4070
movq %rax, 0x68(%rsp)
jmp 0x827a
movq 0x68(%rsp), %rdi
leaq 0x19581(%rip), %rsi     # 0x21807
callq 0x4290
movq %rax, 0x60(%rsp)
jmp 0x8292
movq 0x60(%rsp), %rdi
movq 0x24d0a(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x82a5
movl $0x1, %edi
callq 0x42f0
movq 0x168(%rsp), %rdi
movq %rdi, %rax
addq $0x78, %rax
movq %rax, 0x58(%rsp)
addq $0x8, %rdi
movq %rdi, 0x50(%rsp)
callq 0x17530
movq 0x50(%rsp), %rdi
movq %rax, 0x248(%rsp)
callq 0x17530
movq 0x58(%rsp), %rdi
movq %rax, 0x250(%rsp)
leaq 0x248(%rsp), %rsi
callq 0x9db0
jmp 0x82ff
movq 0x168(%rsp), %rax
movq $0x0, 0x240(%rsp)
addq $0x78, %rax
movq %rax, 0x238(%rsp)
movq 0x238(%rsp), %rdi
callq 0x9e70
movq %rax, 0x230(%rsp)
movq 0x238(%rsp), %rdi
callq 0x9ea0
movq %rax, 0x228(%rsp)
leaq 0x230(%rsp), %rdi
leaq 0x228(%rsp), %rsi
callq 0x9ed0
testb $0x1, %al
jne 0x8364
jmp 0x83b1
leaq 0x230(%rsp), %rdi
callq 0x9f10
movq %rax, 0x220(%rsp)
movq 0x220(%rsp), %rdi
callq 0x9f20
movq %rax, 0x48(%rsp)
jmp 0x838d
movq 0x48(%rsp), %rax
addq 0x240(%rsp), %rax
movq %rax, 0x240(%rsp)
leaq 0x230(%rsp), %rdi
callq 0x9f40
jmp 0x8349
movq 0x240(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
cmpq $0x0, %rdx
je 0x8431
movq 0x24c20(%rip), %rdi     # 0x2cff0
leaq 0x1945c(%rip), %rsi     # 0x21833
callq 0x4290
movq %rax, 0x40(%rsp)
jmp 0x83e3
movq 0x40(%rsp), %rdi
movq 0x240(%rsp), %rsi
callq 0x4070
movq %rax, 0x38(%rsp)
jmp 0x83fc
movq 0x38(%rsp), %rdi
leaq 0x19436(%rip), %rsi     # 0x2183e
callq 0x4290
movq %rax, 0x30(%rsp)
jmp 0x8414
movq 0x30(%rsp), %rdi
movq 0x24b88(%rip), %rsi     # 0x2cfa8
callq 0x42b0
jmp 0x8427
movl $0x1, %edi
callq 0x42f0
leaq 0x208(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x16e80
movq 0x28(%rsp), %rdi
movq 0x240(%rsp), %rsi
callq 0x17370
jmp 0x8457
movq 0x168(%rsp), %rax
addq $0x78, %rax
movq %rax, 0x200(%rsp)
movq 0x200(%rsp), %rdi
callq 0x9e70
movq %rax, 0x1f8(%rsp)
movq 0x200(%rsp), %rdi
callq 0x9ea0
movq %rax, 0x1f0(%rsp)
leaq 0x1f8(%rsp), %rdi
leaq 0x1f0(%rsp), %rsi
callq 0x9ed0
testb $0x1, %al
jne 0x84b3
jmp 0x85c3
leaq 0x1f8(%rsp), %rdi
callq 0x9f10
movq 0x168(%rsp), %rdi
movq %rax, 0x1e8(%rsp)
addq $0x8, %rdi
movq %rdi, 0x18(%rsp)
callq 0x175e0
movq %rax, 0x1d8(%rsp)
movq 0x1e8(%rsp), %rax
movq (%rax), %rsi
leaq 0x1d8(%rsp), %rdi
callq 0x17610
movq 0x18(%rsp), %rdi
movq %rax, 0x1e0(%rsp)
callq 0x175e0
movq %rax, 0x1c8(%rsp)
movq 0x1e8(%rsp), %rax
movq 0x8(%rax), %rsi
leaq 0x1c8(%rsp), %rdi
callq 0x17610
movq %rax, 0x1d0(%rsp)
leaq 0x208(%rsp), %rdi
callq 0x17650
movq %rax, 0x20(%rsp)
jmp 0x854d
movq 0x20(%rsp), %rax
movq %rax, 0x1c0(%rsp)
movq 0x1e0(%rsp), %rdi
movq 0x1d0(%rsp), %rsi
movq 0x1c0(%rsp), %rdx
callq 0x17570
movq %rax, 0x10(%rsp)
jmp 0x857e
movq 0x10(%rsp), %rax
movq %rax, 0x1b8(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x9f40
jmp 0x8495
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2e8(%rsp)
movl %eax, 0x2e4(%rsp)
leaq 0x208(%rsp), %rdi
callq 0x16f70
jmp 0x870d
movq 0x168(%rsp), %rdi
movq 0x240(%rsp), %rdx
movabsq $-0x5555555555555555, %rax # imm = 0xAAAAAAAAAAAAAAAB
mulxq %rax, %rax, %rax
shrq %rax
movq %rax, 0x1b0(%rsp)
addq $0x90, %rdi
movq 0x1b0(%rsp), %rsi
callq 0x17680
jmp 0x8603
leaq 0x208(%rsp), %rdi
callq 0x175e0
movq %rax, 0x1a0(%rsp)
leaq 0x1a8(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x17790
leaq 0x208(%rsp), %rdi
callq 0x177d0
movq %rax, 0x190(%rsp)
leaq 0x198(%rsp), %rdi
leaq 0x190(%rsp), %rsi
callq 0x17790
leaq 0x1a8(%rsp), %rdi
leaq 0x198(%rsp), %rsi
callq 0x17800
testb $0x1, %al
jne 0x8672
jmp 0x86de
movq 0x168(%rsp), %rax
addq $0x90, %rax
movq %rax, (%rsp)
movq 0x1a8(%rsp), %rax
movq %rax, 0x180(%rsp)
movq 0x180(%rsp), %rdi
callq 0x9f60
movl %eax, 0xc(%rsp)
jmp 0x86a7
movq (%rsp), %rdi
movl 0xc(%rsp), %eax
movl %eax, 0x18c(%rsp)
leaq 0x18c(%rsp), %rsi
callq 0x17840
jmp 0x86c5
jmp 0x86c7
leaq 0x1a8(%rsp), %rdi
movl $0x3, %esi
callq 0x17870
jmp 0x8657
leaq 0x208(%rsp), %rdi
callq 0x16f70
leaq 0x2a0(%rsp), %rdi
callq 0x41b0
leaq 0x2f0(%rsp), %rdi
callq 0x4080
addq $0x508, %rsp            # imm = 0x508
retq
leaq 0x2a0(%rsp), %rdi
callq 0x41b0
leaq 0x2f0(%rsp), %rdi
callq 0x4080
movq 0x2e8(%rsp), %rdi
callq 0x4510
nopw %cs:(%rax,%rax)