// File: /workspace/github_cpp_makefile_star2_O1/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 %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x20, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movq 0x18(%rdi), %r15
movq 0x20(%rdi), %r12
cmpq %r12, %r15
je 0x465c2
movq %r12, %rax
subq %r15, %rax
sarq $0x5, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %r15, %rdi
movq %r12, %rsi
callq 0x4bf55
movq %r15, %rdi
movq %r12, %rsi
callq 0x4c039
movq 0x18(%rbx), %rcx
movzwl (%rcx), %eax
movw %ax, 0xc(%rbx)
movzwl 0x20(%rcx), %eax
movw %ax, 0xe(%rbx)
movq 0x10(%rcx), %rdx
movq 0x30(%rcx), %rax
subq 0x8(%rcx), %rdx
shrq $0x2, %rdx
subq 0x28(%rcx), %rax
shrq $0x2, %rax
addl %edx, %eax
je 0x469e0
movq 0x50(%rcx), %rdx
subq 0x48(%rcx), %rdx
movq 0x70(%rcx), %rsi
shrq $0x2, %rdx
subq 0x68(%rcx), %rsi
shrq $0x2, %rsi
movq 0x90(%rcx), %rdi
subq 0x88(%rcx), %rdi
addl %edx, %esi
movq 0xb0(%rcx), %rdx
subq 0xa8(%rcx), %rdx
shrq $0x2, %rdi
shrq $0x2, %rdx
addl %edi, %edx
addl %esi, %edx
movq 0xd0(%rcx), %rsi
subq 0xc8(%rcx), %rsi
shrq $0x2, %rsi
movq 0xf0(%rcx), %rdi
subq 0xe8(%rcx), %rdi
shrq $0x2, %rdi
addl %esi, %edi
addl %edx, %edi
cvtsi2sd %rdi, %xmm1
movl %eax, %eax
cvtsi2sd %rax, %xmm0
divsd %xmm0, %xmm1
ucomisd 0x49fd1(%rip), %xmm1    # 0x90648
jbe 0x46765
movq 0x4995c(%rip), %r15     # 0x8ffe0
leaq 0x2dce1(%rip), %rsi     # 0x7436c
movl $0x9, %edx
movq %r15, %rdi
movsd %xmm1, 0x18(%rsp)
callq 0x276c0
movq (%r14), %rsi
movq 0x8(%r14), %rdx
movq %r15, %rdi
callq 0x276c0
movq %rax, %r14
leaq 0x2dcbf(%rip), %rsi     # 0x74376
movl $0x2b, %edx
movq %rax, %rdi
callq 0x276c0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x27590
movsbl %al, %esi
movq %r14, %rdi
callq 0x27040
movq %rax, %rdi
callq 0x27410
movq %rax, %r14
leaq 0x2dcad(%rip), %rsi     # 0x743a2
movl $0x38, %edx
movq %rax, %rdi
callq 0x276c0
movq %r14, %rdi
movsd 0x18(%rsp), %xmm0
callq 0x279e0
movq %rax, %r14
leaq 0x2dcc1(%rip), %rsi     # 0x743db
movl $0x15, %edx
movq %rax, %rdi
callq 0x276c0
movsd 0x49f19(%rip), %xmm0    # 0x90648
movq %r14, %rdi
callq 0x279e0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x27590
movsbl %al, %esi
movq %r14, %rdi
callq 0x27040
movq %rax, %rdi
callq 0x27410
movb $0x1, 0x10(%rbx)
leaq 0x18(%rbx), %r14
movzwl 0xc(%rbx), %edi
movzwl 0xe(%rbx), %r8d
cmpw $0x1, %di
sete %al
cmpw $0x1, %r8w
sete %cl
cmpw $0x2, %di
sete %dl
cmpw $0x2, %r8w
sete %sil
cmpw $0x4, %di
sete %r9b
cmpw $0x4, %r8w
sete %r11b
orb %r9b, %r11b
cmpw $0x5, %di
sete %r9b
cmpw $0x5, %r8w
sete %bpl
orb %r9b, %bpl
cmpw $0x6, %di
sete %r9b
cmpw $0x6, %r8w
sete %r10b
cmpw $0x8, %di
sete %dil
cmpw $0x8, %r8w
sete %r8b
testb %bpl, %r11b
jne 0x468b3
orb %sil, %dl
orb %r10b, %r9b
andb %dl, %r9b
jne 0x468b3
orb %cl, %al
orb %r8b, %dil
andb %al, %dil
jne 0x468b3
movq 0x497d8(%rip), %r15     # 0x8ffe0
leaq 0x2dbe2(%rip), %rsi     # 0x743f1
movl $0x3d, %edx
movq %r15, %rdi
callq 0x276c0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x27590
movsbl %al, %esi
movq %r15, %rdi
callq 0x27040
movq %rax, %rdi
callq 0x27410
movq %rax, %r15
leaq 0x2dbe2(%rip), %rsi     # 0x7442f
movl $0x20, %edx
movq %rax, %rdi
callq 0x276c0
movzwl 0xc(%rbx), %esi
movq %r15, %rdi
callq 0x27400
movq %rax, %r15
leaq 0x2cd2b(%rip), %rsi     # 0x7359b
movl $0x3, %edx
movq %rax, %rdi
callq 0x276c0
movzwl 0xe(%rbx), %esi
movq %r15, %rdi
callq 0x27400
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x27590
movsbl %al, %esi
movq %r15, %rdi
callq 0x27040
movq %rax, %rdi
callq 0x27410
xorpd %xmm0, %xmm0
movq %rsp, %rdi
movapd %xmm0, (%rdi)
movq $0x0, 0x10(%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 0x4aac0
movq %rsp, %rdi
movq 0x8(%rdi), %rsi
movq (%r14), %rax
movq 0x8(%rax), %rdx
movq 0x10(%rax), %rcx
callq 0x4c7fe
movq %rsp, %rdi
movq 0x8(%rdi), %rsi
movq (%r14), %rax
movq 0x28(%rax), %rdx
movq 0x30(%rax), %rcx
callq 0x4c7fe
movq (%rsp), %r15
movq 0x8(%rsp), %r12
cmpq %r12, %r15
je 0x46952
movq %r12, %rax
subq %r15, %rax
sarq $0x2, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %r15, %rdi
movq %r12, %rsi
callq 0x4c9ea
movq %r15, %rdi
movq %r12, %rsi
callq 0x4cacd
movq %r14, %rdi
callq 0x4ab4e
movq (%rsp), %rdi
movq 0x8(%rsp), %rax
cmpq %rax, %rdi
je 0x469d2
movb $0x1, 0x11(%rbx)
subq %rdi, %rax
shrq $0x2, %rax
movsd 0x2d695(%rip), %xmm0    # 0x74010
movapd %xmm0, %xmm1
subsd 0x49cb9(%rip), %xmm1    # 0x90640
movsd 0x2d689(%rip), %xmm2    # 0x74018
mulsd %xmm2, %xmm1
movl %eax, %eax
cvtsi2sd %rax, %xmm3
subsd %xmm1, %xmm0
mulsd %xmm3, %xmm1
cvttsd2si %xmm1, %rax
mulsd %xmm3, %xmm2
cvttsd2si %xmm2, %rcx
mulsd %xmm3, %xmm0
cvttsd2si %xmm0, %rdx
movl %eax, %eax
movl (%rdi,%rax,4), %eax
movl %eax, (%rbx)
movl %ecx, %eax
movl (%rdi,%rax,4), %eax
movl %eax, 0x4(%rbx)
movl %edx, %eax
movl (%rdi,%rax,4), %eax
movl %eax, 0x8(%rbx)
jmp 0x469d6
movb $0x0, 0x11(%rbx)
testq %rdi, %rdi
je 0x469e0
callq 0x27560
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x469fe
callq 0x27560
movq %rbx, %rdi
callq 0x27b20