// File: /workspace/github_cpp_makefile_star2_O2/zeeev[P]DASVC/bamtools/src/toolkit/bamtools_resolve.cpp
// Function: BamTools::ResolveTool::ResolveToolPrivate::MakeStats()
bool ResolveTool::ResolveToolPrivate::MakeStats(void) {

    // pull resolver settings from command-line settings
    ReadGroupResolver::SetConfidenceInterval(m_settings->ConfidenceInterval);
    ReadGroupResolver::SetUnusedModelThreshold(m_settings->UnusedModelThreshold);

    // open our BAM reader
    BamReader bamReader;
    if ( !bamReader.Open(m_settings->InputBamFilename) ) {
        cerr << "bamtools resolve ERROR: could not open input BAM file: "
             << m_settings->InputBamFilename << endl;
        return false;
    }

    // retrieve header & parse for read groups
    const SamHeader& header = bamReader.GetHeader();
    ParseHeader(header);

    // open ReadNamesFileWriter
    ResolveTool::ReadNamesFileWriter readNamesWriter;
    if ( !readNamesWriter.Open(m_settings->ReadNamesFilename) ) {
        cerr << "bamtools resolve ERROR: could not open (temp) output read names file: "
             << m_settings->ReadNamesFilename << endl;
        bamReader.Close();
        return false;
    }

    // read through BAM file
    BamAlignment al;
    string readGroup("");
    map<string, ReadGroupResolver>::iterator rgIter;
    map<string, bool>::iterator readNameIter;
    while ( bamReader.GetNextAlignmentCore(al) ) {

        // skip if alignment is not paired, mapped, nor mate is mapped
        if ( !al.IsPaired() || !al.IsMapped() || !al.IsMateMapped() )
            continue;

        // skip if alignment & mate not on same reference sequence
        if ( al.RefID != al.MateRefID ) continue;

        // flesh out the char data, so we can retrieve its read group ID
        al.BuildCharData();

        // get read group from alignment (OK if empty)
        readGroup.clear();
        al.GetTag(READ_GROUP_TAG, readGroup);

        // look up resolver for read group
        rgIter = m_readGroups.find(readGroup);
        if ( rgIter == m_readGroups.end() )  {
            cerr << "bamtools resolve ERROR - unable to calculate stats, unknown read group encountered: "
                 << readGroup << endl;
            bamReader.Close();
            return false;
        }
        ReadGroupResolver& resolver = (*rgIter).second;

        // determine unique-ness of current alignment
        const bool isCurrentMateUnique = ( al.MapQuality >= m_settings->MinimumMapQuality );

        // look up read name
        readNameIter = resolver.ReadNames.find(al.Name);

        // if read name found (current alignment's mate already parsed)
        if ( readNameIter != resolver.ReadNames.end() ) {

            // if both unique mates are unique, store read name & insert size for later
            const bool isStoredMateUnique  = (*readNameIter).second;
            if ( isCurrentMateUnique && isStoredMateUnique ) {

                // save read name in temp file as candidates for later pair marking
                readNamesWriter.Write(readGroup, al.Name);

                // determine model type & store fragment length for stats calculation
                const uint16_t currentModelType = CalculateModelType(al);
                assert( currentModelType != ModelType::DUMMY_ID );
                resolver.Models[currentModelType].push_back( abs(al.InsertSize) );
            }

            // unique or not, remove read name from map
            resolver.ReadNames.erase(readNameIter);
        }

        // if read name not found, store new entry
        else resolver.ReadNames.insert( make_pair<string, bool>(al.Name, isCurrentMateUnique) );
    }

    // close files
    readNamesWriter.Close();
    bamReader.Close();

    // iterate back through read groups
    map<string, ReadGroupResolver>::iterator rgEnd  = m_readGroups.end();
    for ( rgIter = m_readGroups.begin(); rgIter != rgEnd; ++rgIter ) {
        const string& name = (*rgIter).first;
        ReadGroupResolver& resolver = (*rgIter).second;

        // calculate acceptable orientation & insert sizes for this read group
        resolver.DetermineTopModels(name);

        // clear out left over read names
        // (these have mates that did not pass filters or were already removed as non-unique)
        resolver.ReadNames.clear();
    }

    // if we get here, return success
    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x568, %rsp            # imm = 0x568
movq %rdi, %rbx
movq (%rdi), %rax
movsd 0x90(%rax), %xmm0
movsd %xmm0, 0x45915(%rip)    # 0x95678
movsd 0xa0(%rax), %xmm0
movsd %xmm0, 0x4590d(%rip)    # 0x95680
leaq 0x8(%rsp), %r14
movq %r14, %rdi
callq 0x353f0
movq (%rbx), %rsi
addq $0x10, %rsi
movq %r14, %rdi
callq 0x357b0
testb %al, %al
je 0x4ffb7
leaq 0x410(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x357e0
leaq 0x410(%rsp), %rsi
movq %rbx, %rdi
callq 0x501a0
leaq 0x210(%rsp), %rdi
callq 0x35ae0
movq (%rbx), %rsi
addq $0x70, %rsi
leaq 0x210(%rsp), %rdi
callq 0x4ec98
testb %al, %al
je 0x4ffe9
leaq 0xb8(%rsp), %rdi
callq 0x35200
leaq 0x26a01(%rip), %rsi     # 0x767f7
leaq 0x20(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x35280
leaq 0x8(%rbx), %rax
movq %rax, 0x40(%rsp)
movq %rbx, 0x18(%rsp)
leaq 0x10(%rbx), %r15
leaq 0xb8(%rsp), %r12
leaq 0x70(%rsp), %rbx
leaq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0x35a70
movl %eax, %r13d
testb %al, %al
je 0x50025
movq %r12, %rdi
callq 0x35320
testb %al, %al
je 0x4fe24
movq %r12, %rdi
callq 0x350c0
testb %al, %al
je 0x4fe24
movq %r12, %rdi
callq 0x356d0
testb %al, %al
je 0x4fe24
movl 0x160(%rsp), %eax
cmpl 0x188(%rsp), %eax
jne 0x4fe24
movq %r12, %rdi
callq 0x355e0
andq $0x0, 0x28(%rsp)
movq 0x20(%rsp), %rax
movb $0x0, (%rax)
movq %r12, %rdi
leaq 0x45c60(%rip), %rsi     # 0x95af0
leaq 0x20(%rsp), %rdx
callq 0x4ac46
movq 0x40(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x539f2
movq %rax, %r14
cmpq %r15, %rax
je 0x5006d
movzwl 0x16a(%rsp), %ebp
movq 0x18(%rsp), %rax
movq (%rax), %rax
movzwl 0x98(%rax), %r13d
leaq 0x70(%r14), %rdi
movq %rdi, 0x10(%rsp)
movq %r12, %rsi
callq 0x53e72
leaq 0x78(%r14), %rdx
cmpq %rdx, %rax
je 0x4ff56
cmpw %r13w, %bp
leaq 0x48(%rsp), %r13
movq %rax, %rbp
jb 0x4ff44
cmpb $0x1, 0x40(%rbp)
jne 0x4ff44
leaq 0x210(%rsp), %rdi
leaq 0x20(%rsp), %rsi
movq %r12, %rdx
callq 0x4ecce
movq %r12, %rdi
callq 0x4e4db
movq 0x58(%r14), %rcx
movl 0x190(%rsp), %edx
movl %edx, %esi
negl %esi
cmovsl %edx, %esi
movl %esi, 0x48(%rsp)
movzwl %ax, %eax
shll $0x5, %eax
leaq (%rcx,%rax), %rdi
addq $0x8, %rdi
movq %r13, %rsi
callq 0x526f8
movq 0x10(%rsp), %rdi
movq %rbp, %rsi
callq 0x53ee8
jmp 0x4fe24
movq %rbx, %rdi
movq %r12, %rsi
callq 0x35810
xorl %edx, %edx
cmpw %r13w, %bp
setae %dl
leaq 0x90(%rsp), %r13
movq %r13, %rdi
movq %rbx, %rsi
callq 0x51b04
leaq 0x48(%rsp), %r14
movq %r14, %rdi
movq %r13, %rsi
callq 0x51b22
movq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x53a68
movq %r14, %rdi
callq 0x35730
movq %r13, %rdi
callq 0x35730
movq %rbx, %rdi
callq 0x35730
jmp 0x4fe24
movq 0x45022(%rip), %rdi     # 0x94fe0
leaq 0x23885(%rip), %rsi     # 0x7384a
callq 0x355b0
movq (%rbx), %rsi
addq $0x10, %rsi
movq %rax, %rdi
callq 0x35510
movq %rax, %rdi
callq 0x35300
xorl %r13d, %r13d
jmp 0x500d4
movq 0x44ff0(%rip), %rdi     # 0x94fe0
leaq 0x2388b(%rip), %rsi     # 0x73882
callq 0x355b0
movq (%rbx), %rsi
addq $0x70, %rsi
movq %rax, %rdi
callq 0x35510
movq %rax, %rdi
callq 0x35300
leaq 0x8(%rsp), %rdi
callq 0x350a0
xorl %r13d, %r13d
jmp 0x500ba
leaq 0x210(%rsp), %rdi
callq 0x4ec7c
leaq 0x8(%rsp), %rdi
callq 0x350a0
movq 0x18(%rsp), %rax
movq 0x20(%rax), %rbx
cmpq %r15, %rbx
je 0x5009f
leaq 0x20(%rbx), %rsi
leaq 0x40(%rbx), %rdi
callq 0x4e6dc
leaq 0x70(%rbx), %rdi
callq 0x53f0c
movq %rbx, %rdi
callq 0x35410
movq %rax, %rbx
jmp 0x50045
movq 0x44f6c(%rip), %rdi     # 0x94fe0
leaq 0x2384e(%rip), %rsi     # 0x738c9
callq 0x355b0
leaq 0x20(%rsp), %rsi
movq %rax, %rdi
callq 0x35510
movq %rax, %rdi
callq 0x35300
leaq 0x8(%rsp), %rdi
callq 0x350a0
leaq 0x20(%rsp), %rdi
callq 0x35730
leaq 0xb8(%rsp), %rdi
callq 0x35940
xorb $0x1, %r13b
leaq 0x210(%rsp), %rdi
callq 0x51cc0
leaq 0x410(%rsp), %rdi
callq 0x355a0
leaq 0x8(%rsp), %rdi
callq 0x35620
movl %r13d, %eax
addq $0x568, %rsp            # imm = 0x568
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x50151
jmp 0x50151
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x35730
jmp 0x50117
jmp 0x50108
movq %rax, %rbx
jmp 0x5015e
jmp 0x50151
movq %rax, %rbx
jmp 0x50124
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x35730
leaq 0x70(%rsp), %rdi
callq 0x35730
jmp 0x50154
jmp 0x50151
jmp 0x50151
jmp 0x50151
jmp 0x5014a
jmp 0x50145
jmp 0x50140
jmp 0x5014a
jmp 0x50151
movq %rax, %rbx
jmp 0x50178
movq %rax, %rbx
jmp 0x5016b
movq %rax, %rbx
jmp 0x50185
jmp 0x50151
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x35730
leaq 0xb8(%rsp), %rdi
callq 0x35940
leaq 0x210(%rsp), %rdi
callq 0x51cc0
leaq 0x410(%rsp), %rdi
callq 0x355a0
leaq 0x8(%rsp), %rdi
callq 0x35620
movq %rbx, %rdi
callq 0x35b50
movq %rax, %rdi
callq 0x3a198
nop