// File: /workspace/github_cpp_makefile_star2_O3/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 %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x18(%rdi), %r14
movq 0x18(%rdi), %r12
movq 0x20(%rdi), %r13
cmpq %r13, %r12
je 0x464b3
movq %r13, %rax
subq %r12, %rax
sarq $0x5, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %r12, %rdi
movq %r13, %rsi
callq 0x4be71
movq %r12, %rdi
movq %r13, %rsi
callq 0x4bf45
movq (%r14), %r12
movzwl (%r12), %eax
movw %ax, 0xc(%rbx)
movzwl 0x20(%r12), %ecx
movw %cx, 0xe(%rbx)
movq 0x10(%r12), %rsi
movq 0x30(%r12), %rdx
subq 0x8(%r12), %rsi
shrq $0x2, %rsi
subq 0x28(%r12), %rdx
shrq $0x2, %rdx
addl %esi, %edx
je 0x468d8
movq 0x50(%r12), %rsi
subq 0x48(%r12), %rsi
movq 0x70(%r12), %rdi
shrq $0x2, %rsi
subq 0x68(%r12), %rdi
shrq $0x2, %rdi
movq 0x90(%r12), %r8
subq 0x88(%r12), %r8
addl %esi, %edi
movq 0xb0(%r12), %rsi
subq 0xa8(%r12), %rsi
shrq $0x2, %r8
shrq $0x2, %rsi
addl %r8d, %esi
addl %edi, %esi
movq 0xd0(%r12), %rdi
subq 0xc8(%r12), %rdi
shrq $0x2, %rdi
movq 0xf0(%r12), %r8
subq 0xe8(%r12), %r8
shrq $0x2, %r8
addl %edi, %r8d
addl %esi, %r8d
cvtsi2sd %r8, %xmm1
movl %edx, %edx
cvtsi2sd %rdx, %xmm0
divsd %xmm0, %xmm1
ucomisd 0x490c5(%rip), %xmm1    # 0x8f640
jbe 0x46671
movq 0x48a58(%rip), %r12     # 0x8efe0
leaq 0x2cdf5(%rip), %rsi     # 0x73384
movl $0x9, %edx
movq %r12, %rdi
movsd %xmm1, 0x20(%rsp)
callq 0x276b0
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq %r12, %rdi
callq 0x276b0
movq %rax, %r15
leaq 0x2cdd3(%rip), %rsi     # 0x7338e
movl $0x2b, %edx
movq %rax, %rdi
callq 0x276b0
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 0x2cdc1(%rip), %rsi     # 0x733ba
movl $0x38, %edx
movq %rax, %rdi
callq 0x276b0
movq %r15, %rdi
movsd 0x20(%rsp), %xmm0
callq 0x279d0
movq %rax, %r15
leaq 0x2cdd5(%rip), %rsi     # 0x733f3
movl $0x15, %edx
movq %rax, %rdi
callq 0x276b0
movsd 0x4900d(%rip), %xmm0    # 0x8f640
movq %r15, %rdi
callq 0x279d0
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
movb $0x1, 0x10(%rbx)
movzwl 0xc(%rbx), %eax
movzwl 0xe(%rbx), %ecx
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 0x467ab
orb %r8b, %dil
orb %r10b, %r9b
andb %dil, %r9b
jne 0x467ab
orb %sil, %dl
orb %cl, %al
andb %dl, %al
jne 0x467ab
movq 0x488e0(%rip), %r15     # 0x8efe0
leaq 0x2cd02(%rip), %rsi     # 0x73409
movl $0x3d, %edx
movq %r15, %rdi
callq 0x276b0
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 0x2cd02(%rip), %rsi     # 0x73447
movl $0x20, %edx
movq %rax, %rdi
callq 0x276b0
movzwl 0xc(%rbx), %esi
movq %r15, %rdi
callq 0x27400
movq %rax, %r15
leaq 0x2be33(%rip), %rsi     # 0x7259b
movl $0x3, %edx
movq %rax, %rdi
callq 0x276b0
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 0x4a9ca
movq %rsp, %rdi
movq 0x8(%rdi), %rsi
movq (%r14), %rax
movq 0x8(%rax), %rdx
movq 0x10(%rax), %rcx
callq 0x4c708
movq %rsp, %rdi
movq 0x8(%rdi), %rsi
movq (%r14), %rax
movq 0x28(%rax), %rdx
movq 0x30(%rax), %rcx
callq 0x4c708
movq (%rsp), %r15
movq 0x8(%rsp), %r12
cmpq %r12, %r15
je 0x4684a
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 0x4c8bc
movq %r15, %rdi
movq %r12, %rsi
callq 0x4c99f
movq %r14, %rdi
callq 0x4aa58
movq (%rsp), %rdi
movq 0x8(%rsp), %rax
cmpq %rax, %rdi
je 0x468ca
movb $0x1, 0x11(%rbx)
subq %rdi, %rax
shrq $0x2, %rax
movsd 0x2c7b5(%rip), %xmm0    # 0x73028
movapd %xmm0, %xmm1
subsd 0x48db9(%rip), %xmm1    # 0x8f638
movsd 0x2c7a9(%rip), %xmm2    # 0x73030
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 0x468d3
movb $0x0, 0x11(%rbx)
testq %rdi, %rdi
je 0x468d8
callq 0x27560
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x468f8
callq 0x27560
movq %rbx, %rdi
callq 0x27b10