// File: /workspace/github_c_makefile_star2_O3/sc932[P]ALE/src/ALElike.c
// Function: applyDepthAndMatchToContig
int applyDepthAndMatchToContig(alignSet_t *alignment, assemblyT *theAssembly, double likeNormalizer, libraryParametersT *libParams) {
  assert(alignment->likelihood >= 0.0);
  double logLikelihood = validateLogLikelihood( log(alignment->likelihood) );
  double logLikelihoodInsert = validateLogLikelihood( log(alignment->likelihoodInsert) );
  double totalPositionPlaceLogLikelihood = 0.0;
  int j, i;
  int numberMapped = 0;
  double depthContribution;
  double norm = 0.5; // set default to 0.5 (paired reads will hit this function separately)

  enum MATE_ORIENTATION orientation = alignment->orientation;
  double orientationLogLikelihood = log(libParams->mateParameters[orientation].libraryFraction);

  switch(orientation) {
  case(VALID_FR):
  case(VALID_RF):
  case(VALID_FF):
  case(NOT_PROPER_FR):
  case(NOT_PROPER_RF):
  case(NOT_PROPER_FF):
      norm = 1.0; // This function will only be called once for 2 reads
  	  break;

  case(SINGLE_UNMAPPED_MATE):
  case(SINGLE_READ):
  	  orientationLogLikelihood = log(libParams->totalValidSingleFraction); break;
  case(CHIMER):
  	  orientationLogLikelihood = log(libParams->totalChimerMateFraction); break;
  default:
	  break;
  }
  double logLikelihoodPlacement = 0.0;

  // READ 1
  if (alignment->start1 >= 0 && alignment->end1 >= 0 && alignment->contigId1 >= 0 && alignment->contigId1 < theAssembly->numContigs) {
    numberMapped += 1;
    contig_t *contig1 = theAssembly->contigs[alignment->contigId1];
    assert(alignment->start1 < contig1->seqLen);
    assert(alignment->end1 <= contig1->seqLen);
    assert(alignment->start1 < alignment->end1);
    int alignmentLength = alignment->end1 - alignment->start1;
    float depthContributions[alignmentLength];
    double placeLogLikelihoods[alignmentLength];
    logLikelihood += getContributionsForPositions(alignment->bamOfAlignment1, contig1, libParams->qOff, alignmentLength, depthContributions, placeLogLikelihoods, 0);
    i = 0;
    for(j = alignment->start1; j < alignment->end1; j++){
      // DEPTH SCORE
      // discount indels
      depthContribution = depthContributions[i]; //getDepthContributionAtPositionBAM(alignment->bamOfAlignment1, qOff, i);
      contig1->depth[j] += depthContribution;
      theAssembly->overlapAvgSum += depthContribution;      
      //contig1->depth[j] += 1.0; // We picked a winner, it gets full prob

      // PLACEMENT SCORE
      // TODO make it BAM dependent
      // BAMv2 version
      logLikelihoodPlacement = orientationLogLikelihood + placeLogLikelihoods[i]; //exp(getMatchLogLikelihoodAtPosition(alignment->bamOfAlignment1, qOff, i, md1)); // + log(alignment->likelihoodInsert);
      totalPositionPlaceLogLikelihood += placeLogLikelihoods[i];
      i++;
      contig1->matchLogLikelihood[j]  += logLikelihoodPlacement; // will be validated later
      contig1->insertLogLikelihood[j] += logLikelihoodInsert;    // will be validated later
    }
    totalPositionPlaceLogLikelihood -= logzNormalizationReadQual(alignment->bamOfAlignment1, libParams->qOff);

    theAssembly->overlapAvgNorm += 1.0;
    //printf("Pplacement %lf Read1 for %s\n", logLikelihood, bam1_qname(alignment->bamOfAlignment1));
  }

  // READ 2
  // check for a valid read2 entry
  if (alignment->start2 >= 0 && alignment->end2 >= 0 && alignment->contigId2 >= 0 && alignment->contigId2 < theAssembly->numContigs && alignment->start2 != alignment->start1) {
    numberMapped += 1;
    contig_t *contig2 = theAssembly->contigs[alignment->contigId2];
    assert(alignment->start2 < contig2->seqLen);
    assert(alignment->end2 <= contig2->seqLen);
    assert(alignment->start2 < alignment->end2);
    assert(alignment->bamOfAlignment2 != NULL);
    int alignmentLength = alignment->end2 - alignment->start2;
    float depthContributions[alignmentLength];
    double placeLogLikelihoods[alignmentLength];
    logLikelihood += getContributionsForPositions(alignment->bamOfAlignment2, contig2, libParams->qOff, alignmentLength, depthContributions, placeLogLikelihoods, 0);
    i = 0;
    for(j = alignment->start2; j < alignment->end2; j++){
      // DEPTH SCORE
      // discount indels
      depthContribution = depthContributions[i]; // getDepthContributionAtPositionBAM(alignment->bamOfAlignment2, qOff, i);
      contig2->depth[j] += depthContribution;
      theAssembly->overlapAvgSum += depthContribution;
      //contig2->depth[j] += 1.0;
      
      // PLACEMENT SCORE
      // TODO make it BAM dependent
      // BAMv2 version
      logLikelihoodPlacement = orientationLogLikelihood + placeLogLikelihoods[i]; // exp(getMatchLogLikelihoodAtPosition(alignment->bamOfAlignment2, qOff, i, md2)); // + log(alignment->likelihoodInsert);
      totalPositionPlaceLogLikelihood += placeLogLikelihoods[i];
      i++;
      contig2->matchLogLikelihood[j]  += logLikelihoodPlacement; // will be validated later
      contig2->insertLogLikelihood[j] += logLikelihoodInsert;    // will be validated later
    }
    totalPositionPlaceLogLikelihood -= logzNormalizationReadQual(alignment->bamOfAlignment2, libParams->qOff);
    theAssembly->overlapAvgNorm += 1.0;
    //printf("Pplacement %lf Read2 for %s\n", logLikelihood, bam1_qname(alignment->bamOfAlignment2));
  }
  // TOTAL SCORE
  // apply match likelihood to total likelihood
  if(numberMapped == 0){
	  logLikelihood = getMinLogLike();
  } else if (norm != 1.0) {
	  // This function is called once per read.... not per pair for this orientation
	  logLikelihood *= norm;
	  logLikelihoodInsert *= norm;
  }
  // printf("perbase vs perread placement: %lf %lf\n", validateLogLikelihood(totalPositionPlaceLogLikelihood + orientationLogLikelihood), tmpLogLike);
  // mated reads and single reads both only hit the total score once
  theAssembly->totalScore += logLikelihood; // match contribution to totalScore from placement
  theAssembly->placeAvgSum += logLikelihood;
  theAssembly->placeAvgNorm += norm;
  
  // this happens whether double, single or unmapped
  theAssembly->totalScore += logLikelihoodInsert; // match contribution to totalScore from insert
  theAssembly->insertAvgSum += logLikelihoodInsert;
  theAssembly->insertAvgNorm += norm;

  //printf("totalScore: %lf %lf\n", theAssembly->totalScore, theAssembly->insertAvgSum);
  return numberMapped;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movsd (%rdi), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x793d
movq %rdx, %r13
movq %rsi, %rbx
movq %rdi, %r15
callq 0x3290
callq 0xab52
movapd %xmm0, -0x50(%rbp)
movsd 0x8(%r15), %xmm0
callq 0x3290
callq 0xab52
movaps %xmm0, -0x70(%rbp)
movl 0x40(%r15), %r14d
movq %r14, %rax
shlq $0x6, %rax
movsd 0x18(%r13,%rax), %xmm0
callq 0x3290
movsd 0x1651e(%rip), %xmm5    # 0x1da48
cmpq $0xb, %r14
ja 0x756b
leaq 0x1664d(%rip), %rax     # 0x1db84
movslq (%rax,%r14,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movsd 0x164e8(%rip), %xmm5    # 0x1da30
jmp 0x756b
movsd 0x390(%r13), %xmm0
jmp 0x755e
movsd 0x3a0(%r13), %xmm0
callq 0x3290
movsd 0x164dd(%rip), %xmm5    # 0x1da48
movl 0x10(%r15), %edx
movl $0x1, %r12d
movb $0x1, %al
testl %edx, %edx
js 0x7710
movl 0x18(%r15), %ecx
testl %ecx, %ecx
js 0x7710
movslq 0x20(%r15), %rsi
testq %rsi, %rsi
js 0x7710
cmpl (%rbx), %esi
jge 0x7710
movq 0xa0(%rbx), %rax
movq (%rax,%rsi,8), %r14
movl 0x8(%r14), %eax
cmpl %eax, %edx
jge 0x795c
cmpl %eax, %ecx
ja 0x797b
movsd %xmm0, -0x38(%rbp)
movq %r13, -0x30(%rbp)
movapd %xmm5, -0x60(%rbp)
subl %edx, %ecx
jbe 0x799a
movq %rsp, -0x40(%rbp)
leaq 0xf(,%rcx,4), %rax
andq $-0x10, %rax
movq %rsp, %r12
subq %rax, %r12
movq %r12, %rsp
leaq 0xf(,%rcx,8), %rax
andq $-0x10, %rax
movq %rsp, %r13
subq %rax, %r13
movq %r13, %rsp
movq 0x30(%r15), %rdi
movq -0x30(%rbp), %rax
movl 0x3b0(%rax), %edx
subq $0x8, %rsp
movq %r14, %rsi
movq %r12, %r8
movq %r13, %r9
pushq $0x0
callq 0x5e6b
addq $0x10, %rsp
movslq 0x10(%r15), %rax
movl 0x18(%r15), %ecx
cmpl %eax, %ecx
jle 0x76c6
movsd 0x68(%rbx), %xmm1
subl %eax, %ecx
shlq $0x2, %rax
movq 0x30(%r14), %rdx
addq %rax, %rdx
movq 0x38(%r14), %rsi
addq %rax, %rsi
addq 0x40(%r14), %rax
xorl %edi, %edi
movapd -0x70(%rbp), %xmm5
movsd -0x38(%rbp), %xmm6
movss (%r12,%rdi,4), %xmm2
xorps %xmm3, %xmm3
cvtss2sd %xmm2, %xmm3
addss (%rdx,%rdi,4), %xmm2
movss %xmm2, (%rdx,%rdi,4)
movsd (%r13,%rdi,8), %xmm2
xorps %xmm4, %xmm4
cvtss2sd (%rsi,%rdi,4), %xmm4
addsd %xmm6, %xmm2
addsd %xmm2, %xmm4
xorps %xmm2, %xmm2
cvtsd2ss %xmm4, %xmm2
movss %xmm2, (%rsi,%rdi,4)
xorps %xmm2, %xmm2
cvtss2sd (%rax,%rdi,4), %xmm2
addsd %xmm3, %xmm1
addsd %xmm5, %xmm2
cvtsd2ss %xmm2, %xmm2
movss %xmm2, (%rax,%rdi,4)
leaq 0x1(%rdi), %r8
movq %r8, %rdi
cmpq %r8, %rcx
jne 0x7662
movsd %xmm1, 0x68(%rbx)
movapd -0x50(%rbp), %xmm1
addsd %xmm0, %xmm1
movapd %xmm1, -0x50(%rbp)
movq 0x30(%r15), %rdi
movq -0x30(%rbp), %r13
movl 0x3b0(%r13), %esi
callq 0x7a35
movsd 0x70(%rbx), %xmm0
addsd 0x1633b(%rip), %xmm0    # 0x1da30
movsd %xmm0, 0x70(%rbx)
movl $0x2, %r12d
xorl %eax, %eax
movq -0x40(%rbp), %rsp
movapd -0x60(%rbp), %xmm5
movsd -0x38(%rbp), %xmm0
movl 0x14(%r15), %edx
testl %edx, %edx
js 0x7733
movl 0x1c(%r15), %ecx
testl %ecx, %ecx
js 0x7733
movslq 0x24(%r15), %rsi
testq %rsi, %rsi
js 0x7733
cmpl (%rbx), %esi
jge 0x7733
cmpl 0x10(%r15), %edx
jne 0x775f
movl $0x1, %r12d
testb %al, %al
je 0x78d0
xorl %r12d, %r12d
xorl %eax, %eax
movapd %xmm5, -0x60(%rbp)
callq 0xab49
movapd -0x60(%rbp), %xmm5
movapd -0x70(%rbp), %xmm3
jmp 0x78f5
movq 0xa0(%rbx), %rax
movq (%rax,%rsi,8), %rsi
movl 0x8(%rsi), %eax
cmpl %eax, %edx
jge 0x79b9
cmpl %eax, %ecx
ja 0x79d8
subl %edx, %ecx
jbe 0x79f7
movsd %xmm0, -0x38(%rbp)
movq %r13, -0x30(%rbp)
movapd %xmm5, -0x60(%rbp)
cmpq $0x0, 0x38(%r15)
je 0x7a16
movq %rsp, -0x40(%rbp)
leaq 0xf(,%rcx,4), %rax
andq $-0x10, %rax
movq %rsp, %r13
subq %rax, %r13
movq %r13, %rsp
leaq 0xf(,%rcx,8), %rax
andq $-0x10, %rax
movq %rsp, %r14
subq %rax, %r14
movq %r14, %rsp
movq 0x38(%r15), %rdi
movq -0x30(%rbp), %rax
movl 0x3b0(%rax), %edx
subq $0x8, %rsp
movq %rsi, -0x78(%rbp)
movq %r13, %r8
movq %r14, %r9
pushq $0x0
callq 0x5e6b
addq $0x10, %rsp
movslq 0x14(%r15), %rax
movl 0x1c(%r15), %ecx
cmpl %eax, %ecx
jle 0x7894
movsd 0x68(%rbx), %xmm1
subl %eax, %ecx
shlq $0x2, %rax
movq -0x78(%rbp), %rdi
movq 0x30(%rdi), %rdx
addq %rax, %rdx
movq 0x38(%rdi), %rsi
addq %rax, %rsi
addq 0x40(%rdi), %rax
xorl %edi, %edi
movapd -0x70(%rbp), %xmm5
movsd -0x38(%rbp), %xmm6
movss (%r13,%rdi,4), %xmm2
xorps %xmm3, %xmm3
cvtss2sd %xmm2, %xmm3
addss (%rdx,%rdi,4), %xmm2
movss %xmm2, (%rdx,%rdi,4)
movsd (%r14,%rdi,8), %xmm2
xorps %xmm4, %xmm4
cvtss2sd (%rsi,%rdi,4), %xmm4
addsd %xmm6, %xmm2
addsd %xmm2, %xmm4
xorps %xmm2, %xmm2
cvtsd2ss %xmm4, %xmm2
movss %xmm2, (%rsi,%rdi,4)
xorps %xmm2, %xmm2
cvtss2sd (%rax,%rdi,4), %xmm2
addsd %xmm3, %xmm1
addsd %xmm5, %xmm2
cvtsd2ss %xmm2, %xmm2
movss %xmm2, (%rax,%rdi,4)
leaq 0x1(%rdi), %r8
movq %r8, %rdi
cmpq %r8, %rcx
jne 0x7830
movsd %xmm1, 0x68(%rbx)
movapd -0x50(%rbp), %xmm1
addsd %xmm0, %xmm1
movapd %xmm1, -0x50(%rbp)
movq 0x38(%r15), %rdi
movq -0x30(%rbp), %rax
movl 0x3b0(%rax), %esi
callq 0x7a35
movsd 0x70(%rbx), %xmm0
addsd 0x1616e(%rip), %xmm0    # 0x1da30
movsd %xmm0, 0x70(%rbx)
movq -0x40(%rbp), %rsp
movapd -0x60(%rbp), %xmm5
ucomisd 0x16158(%rip), %xmm5    # 0x1da30
movapd -0x70(%rbp), %xmm3
jne 0x78e1
jnp 0x78f0
movapd -0x50(%rbp), %xmm0
mulsd %xmm5, %xmm0
mulsd %xmm5, %xmm3
jmp 0x78f5
movapd -0x50(%rbp), %xmm0
movsd 0x10(%rbx), %xmm4
addsd %xmm0, %xmm4
unpcklpd %xmm5, %xmm0            # xmm0 = xmm0[0],xmm5[0]
movupd 0x28(%rbx), %xmm1
addpd %xmm0, %xmm1
movupd 0x38(%rbx), %xmm2
movupd %xmm1, 0x28(%rbx)
addsd %xmm3, %xmm4
movsd %xmm4, 0x10(%rbx)
unpcklpd %xmm5, %xmm3            # xmm3 = xmm3[0],xmm5[0]
addpd %xmm2, %xmm3
movupd %xmm3, 0x38(%rbx)
movl %r12d, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1a845(%rip), %rdi     # 0x22189
leaq 0x1a41a(%rip), %rsi     # 0x21d65
leaq 0x1a854(%rip), %rcx     # 0x221a6
movl $0x448, %edx            # imm = 0x448
callq 0x3230
leaq 0x1a89b(%rip), %rdi     # 0x221fe
leaq 0x1a3fb(%rip), %rsi     # 0x21d65
leaq 0x1a835(%rip), %rcx     # 0x221a6
movl $0x46c, %edx            # imm = 0x46C
callq 0x3230
leaq 0x1a8a0(%rip), %rdi     # 0x22222
leaq 0x1a3dc(%rip), %rsi     # 0x21d65
leaq 0x1a816(%rip), %rcx     # 0x221a6
movl $0x46d, %edx            # imm = 0x46D
callq 0x3230
leaq 0x1a8a4(%rip), %rdi     # 0x22245
leaq 0x1a3bd(%rip), %rsi     # 0x21d65
leaq 0x1a7f7(%rip), %rcx     # 0x221a6
movl $0x46e, %edx            # imm = 0x46E
callq 0x3230
leaq 0x1a8a9(%rip), %rdi     # 0x22269
leaq 0x1a39e(%rip), %rsi     # 0x21d65
leaq 0x1a7d8(%rip), %rcx     # 0x221a6
movl $0x490, %edx            # imm = 0x490
callq 0x3230
leaq 0x1a8ae(%rip), %rdi     # 0x2228d
leaq 0x1a37f(%rip), %rsi     # 0x21d65
leaq 0x1a7b9(%rip), %rcx     # 0x221a6
movl $0x491, %edx            # imm = 0x491
callq 0x3230
leaq 0x1a8b2(%rip), %rdi     # 0x222b0
leaq 0x1a360(%rip), %rsi     # 0x21d65
leaq 0x1a79a(%rip), %rcx     # 0x221a6
movl $0x492, %edx            # imm = 0x492
callq 0x3230
leaq 0x1a8b7(%rip), %rdi     # 0x222d4
leaq 0x1a341(%rip), %rsi     # 0x21d65
leaq 0x1a77b(%rip), %rcx     # 0x221a6
movl $0x493, %edx            # imm = 0x493
callq 0x3230