// File: /workspace/github_cpp_makefile_star2_O2/zeeev[P]DASVC/bamtools/src/toolkit/bamtools_resolve.cpp
// Function: ReadGroupResolver::DetermineTopModels(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void ReadGroupResolver::DetermineTopModels(const string& readGroupName) {

    // sort models (from most common to least common)
    sort( Models.begin(), Models.end(), std::greater<ModelType>() );

    // store top 2 models for later
    TopModelId     = Models[0].ID;
    NextTopModelId = Models[1].ID;

    // make sure that the 2 most common models are some threshold more common
    // than the remaining models
    const unsigned int activeModelCountSum = Models[0].size() + Models[1].size();
    if ( activeModelCountSum == 0 ) return; // skip if no data in this read group
    const unsigned int unusedModelCountSum = Models[2].size() + Models[3].size() +
                                             Models[4].size() + Models[5].size() +
                                             Models[6].size() + Models[7].size();    
    const double unusedPercentage = (double)unusedModelCountSum / (double)activeModelCountSum;
    if ( unusedPercentage > UnusedModelThreshold ) {
        cerr << "WARNING: " << readGroupName << " does not have clearly defined 'top models'" << endl
             << "         The fraction of alignments in bottom 6 models (" << unusedPercentage
             << ") exceeds threshold: " << UnusedModelThreshold << endl;
        IsAmbiguous = true;
    }

    // emit a warning if the best alignment models are non-standard
    const bool isModel1Top = (TopModelId == 1) || (NextTopModelId == 1);
    const bool isModel2Top = (TopModelId == 2) || (NextTopModelId == 2);
    const bool isModel4Top = (TopModelId == 4) || (NextTopModelId == 4);
    const bool isModel5Top = (TopModelId == 5) || (NextTopModelId == 5);
    const bool isModel6Top = (TopModelId == 6) || (NextTopModelId == 6);
    const bool isModel8Top = (TopModelId == 8) || (NextTopModelId == 8);

    bool isMatePair  = ( isModel4Top && isModel5Top ? true : false );
    bool isPairedEnd = ( isModel2Top && isModel6Top ? true : false );
    bool isSolidPair = ( isModel1Top && isModel8Top ? true : false );

    if ( !isMatePair && !isPairedEnd && !isSolidPair ) {
        cerr << "WARNING: Found a non-standard alignment model configuration. " << endl
             << "         Using alignment models " << TopModelId << " & " << NextTopModelId
             << endl;
    }

    // store only the fragments from the best alignment models, then sort
    vector<int32_t> fragments;
    fragments.reserve( Models[0].size() + Models[1].size() );
    fragments.insert( fragments.end(), Models[0].begin(), Models[0].end() );
    fragments.insert( fragments.end(), Models[1].begin(), Models[1].end() );
    sort ( fragments.begin(), fragments.end() );

    // clear out Model fragment data, not needed anymore
    Models.clear();

    // skip if no fragments found for this read group
    if ( fragments.empty() ) {
        HasData = false;
        return;
    } else
        HasData = true;

    // calculate & store the min,median, & max fragment lengths
    const unsigned int numFragmentLengths = fragments.size();
    const double halfNonConfidenceInterval = (1.0 - ReadGroupResolver::ConfidenceInterval)/2.0;
    const unsigned int minIndex    = (unsigned int)(numFragmentLengths * halfNonConfidenceInterval);
    const unsigned int medianIndex = (unsigned int)(numFragmentLengths * 0.5);
    const unsigned int maxIndex    = (unsigned int)(numFragmentLengths * (1.0-halfNonConfidenceInterval));

    MinFragmentLength    = fragments[minIndex];
    MedianFragmentLength = fragments[medianIndex];
    MaxFragmentLength    = fragments[maxIndex];
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x20, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movq 0x18(%rdi), %rdi
movq 0x20(%rbx), %rsi
callq 0x52abb
movq 0x18(%rbx), %rsi
movzwl (%rsi), %eax
movw %ax, 0xc(%rbx)
movzwl 0x20(%rsi), %ecx
movw %cx, 0xe(%rbx)
movq 0x10(%rsi), %rdi
movq 0x30(%rsi), %rdx
subq 0x8(%rsi), %rdi
shrq $0x2, %rdi
subq 0x28(%rsi), %rdx
shrq $0x2, %rdx
addl %edi, %edx
je 0x4ea15
movq 0x50(%rsi), %rdi
subq 0x48(%rsi), %rdi
movq 0x70(%rsi), %r8
shrq $0x2, %rdi
subq 0x68(%rsi), %r8
shrq $0x2, %r8
movq 0x90(%rsi), %r9
subq 0x88(%rsi), %r9
addl %edi, %r8d
movq 0xb0(%rsi), %rdi
subq 0xa8(%rsi), %rdi
shrq $0x2, %r9
shrq $0x2, %rdi
addl %r9d, %edi
addl %r8d, %edi
movq 0xd0(%rsi), %r8
subq 0xc8(%rsi), %r8
shrq $0x2, %r8
movq 0xf0(%rsi), %r9
subq 0xe8(%rsi), %r9
shrq $0x2, %r9
addl %r8d, %r9d
addl %edi, %r9d
cvtsi2sd %r9, %xmm1
movl %edx, %edx
cvtsi2sd %rdx, %xmm0
divsd %xmm0, %xmm1
ucomisd 0x46ecf(%rip), %xmm1    # 0x95680
jbe 0x4e842
movq 0x46822(%rip), %rdi     # 0x94fe0
leaq 0x24b37(%rip), %rsi     # 0x732fc
movsd %xmm1, 0x18(%rsp)
callq 0x355b0
movq %rax, %rdi
movq %r14, %rsi
callq 0x35510
leaq 0x24b24(%rip), %rsi     # 0x73306
movq %rax, %rdi
callq 0x355b0
movq %rax, %rdi
callq 0x35300
leaq 0x24b39(%rip), %rsi     # 0x73332
movq %rax, %rdi
callq 0x355b0
movq %rax, %rdi
movsd 0x18(%rsp), %xmm0
callq 0x35a00
leaq 0x24b55(%rip), %rsi     # 0x7336b
movq %rax, %rdi
callq 0x355b0
movsd 0x46e5a(%rip), %xmm0    # 0x95680
movq %rax, %rdi
callq 0x35a00
movq %rax, %rdi
callq 0x35300
movb $0x1, 0x10(%rbx)
movzwl 0xc(%rbx), %eax
movzwl 0xe(%rbx), %ecx
leaq 0x18(%rbx), %r14
cmpw $0x1, %ax
sete %dl
cmpw $0x1, %cx
sete %sil
cmpw $0x2, %ax
sete %dil
cmpw $0x2, %cx
sete %r8b
cmpw $0x4, %ax
sete %r9b
cmpw $0x4, %cx
sete %r11b
orb %r9b, %r11b
cmpw $0x5, %ax
sete %r9b
cmpw $0x5, %cx
sete %bpl
orb %r9b, %bpl
cmpw $0x6, %ax
sete %r9b
cmpw $0x6, %cx
sete %r10b
cmpw $0x8, %ax
sete %al
cmpw $0x8, %cx
sete %cl
testb %bpl, %r11b
jne 0x4e91b
orb %r8b, %dil
orb %r10b, %r9b
andb %dil, %r9b
jne 0x4e91b
orb %sil, %dl
orb %cl, %al
andb %dl, %al
jne 0x4e91b
movq 0x46717(%rip), %rdi     # 0x94fe0
leaq 0x24ab1(%rip), %rsi     # 0x73381
callq 0x355b0
movq %rax, %rdi
callq 0x35300
leaq 0x24adb(%rip), %rsi     # 0x733bf
movq %rax, %rdi
callq 0x355b0
movzwl 0xc(%rbx), %esi
movq %rax, %rdi
callq 0x35a90
leaq 0x23c29(%rip), %rsi     # 0x72528
movq %rax, %rdi
callq 0x355b0
movzwl 0xe(%rbx), %esi
movq %rax, %rdi
callq 0x35a90
movq %rax, %rdi
callq 0x35300
movq %rsp, %rdi
andq $0x0, 0x10(%rdi)
xorpd %xmm0, %xmm0
movapd %xmm0, (%rdi)
movq (%r14), %rax
movq 0x10(%rax), %rcx
movq 0x30(%rax), %rsi
subq 0x8(%rax), %rcx
sarq $0x2, %rcx
subq 0x28(%rax), %rsi
sarq $0x2, %rsi
addq %rcx, %rsi
callq 0x519c2
movq %rsp, %rdi
movq 0x8(%rdi), %rsi
movq (%r14), %rax
movq 0x8(%rax), %rdx
movq 0x10(%rax), %rcx
callq 0x5335e
movq %rsp, %rdi
movq 0x8(%rdi), %rsi
movq (%r14), %rax
movq 0x28(%rax), %rdx
movq 0x30(%rax), %rcx
callq 0x5335e
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x53504
movq %r14, %rdi
callq 0x51a3c
movq (%rsp), %rax
movq 0x8(%rsp), %rcx
cmpq %rcx, %rax
je 0x4ea08
subq %rax, %rcx
shrq $0x2, %rcx
movsd 0x245f1(%rip), %xmm0    # 0x72fa0
movapd %xmm0, %xmm1
subsd 0x46cbd(%rip), %xmm1    # 0x95678
movsd 0x245e5(%rip), %xmm2    # 0x72fa8
mulsd %xmm2, %xmm1
movl %ecx, %ecx
cvtsi2sd %rcx, %xmm3
subsd %xmm1, %xmm0
mulsd %xmm3, %xmm1
cvttsd2si %xmm1, %rcx
mulsd %xmm3, %xmm2
cvttsd2si %xmm2, %rdx
mulsd %xmm3, %xmm0
cvttsd2si %xmm0, %rsi
movl %ecx, %ecx
movl (%rax,%rcx,4), %ecx
movl %ecx, (%rbx)
movl %edx, %ecx
movl (%rax,%rcx,4), %ecx
movl %ecx, 0x4(%rbx)
movl %esi, %ecx
movl (%rax,%rcx,4), %eax
movl %eax, 0x8(%rbx)
movb $0x1, %al
jmp 0x4ea0a
xorl %eax, %eax
movb %al, 0x11(%rbx)
movq %rsp, %rdi
callq 0x52412
addq $0x20, %rsp
popq %rbx
popq %r14
popq %rbp
retq
movq %rax, %rbx
movq %rsp, %rdi
callq 0x52412
movq %rbx, %rdi
callq 0x35b50
movq %rax, %rdi
callq 0x3a198
nop