// File: /workspace/github_c_makefile_star2_O2/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 0x5ac7
movq %rdx, %r13
movq %rsi, %rbx
movq %rdi, %r15
callq 0x3290
callq 0x8a4e
movapd %xmm0, -0x50(%rbp)
movsd 0x8(%r15), %xmm0
callq 0x3290
callq 0x8a4e
movaps %xmm0, -0x70(%rbp)
movl 0x40(%r15), %r14d
movq %r14, %rax
shlq $0x6, %rax
movsd 0x18(%r13,%rax), %xmm0
callq 0x3290
movsd 0x1434e(%rip), %xmm5    # 0x19a48
cmpq $0xb, %r14
ja 0x573b
leaq 0x1444d(%rip), %rax     # 0x19b54
movslq (%rax,%r14,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movsd 0x14318(%rip), %xmm5    # 0x19a30
jmp 0x573b
movsd 0x390(%r13), %xmm0
jmp 0x572e
movsd 0x3a0(%r13), %xmm0
callq 0x3290
movsd 0x1430d(%rip), %xmm5    # 0x19a48
movl 0x10(%r15), %edx
pushq $0x1
popq %rdi
movb $0x1, %al
testl %edx, %edx
js 0x58bb
movl 0x18(%r15), %ecx
testl %ecx, %ecx
js 0x58bb
movslq 0x20(%r15), %rsi
testq %rsi, %rsi
js 0x58bb
cmpl (%rbx), %esi
jge 0x58bb
movq 0xa0(%rbx), %rax
movq (%rax,%rsi,8), %r12
movl 0x8(%r12), %eax
cmpl %eax, %edx
jge 0x5ae6
cmpl %eax, %ecx
ja 0x5b05
movsd %xmm0, -0x38(%rbp)
movq %r13, -0x30(%rbp)
movapd %xmm5, -0x60(%rbp)
subl %edx, %ecx
jbe 0x5b24
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 0x30(%r15), %rdi
movq -0x30(%rbp), %rax
movl 0x3b0(%rax), %edx
subq $0x8, %rsp
movq %r12, %rsi
movq %r13, %r8
movq %r14, %r9
pushq $0x0
callq 0x451c
addq $0x10, %rsp
movslq 0x10(%r15), %rax
movslq 0x18(%r15), %rcx
xorl %edx, %edx
movapd -0x70(%rbp), %xmm3
movsd -0x38(%rbp), %xmm4
cmpq %rcx, %rax
jge 0x5874
movss (%r13,%rdx,4), %xmm1
cvtss2sd %xmm1, %xmm2
movq 0x30(%r12), %rsi
addss (%rsi,%rax,4), %xmm1
movss %xmm1, (%rsi,%rax,4)
addsd 0x68(%rbx), %xmm2
movsd %xmm2, 0x68(%rbx)
movsd (%r14,%rdx,8), %xmm1
addsd %xmm4, %xmm1
incq %rdx
movq 0x38(%r12), %rsi
cvtss2sd (%rsi,%rax,4), %xmm2
addsd %xmm1, %xmm2
cvtsd2ss %xmm2, %xmm1
movss %xmm1, (%rsi,%rax,4)
movq 0x40(%r12), %rsi
cvtss2sd (%rsi,%rax,4), %xmm1
addsd %xmm3, %xmm1
cvtsd2ss %xmm1, %xmm1
movss %xmm1, (%rsi,%rax,4)
incq %rax
jmp 0x580b
movapd -0x50(%rbp), %xmm1
addsd %xmm0, %xmm1
movapd %xmm1, -0x50(%rbp)
movq 0x30(%r15), %rdi
movq -0x30(%rbp), %r13
movl 0x3b0(%r13), %esi
callq 0x5bbf
movsd -0x38(%rbp), %xmm0
movsd 0x70(%rbx), %xmm1
addsd 0x14188(%rip), %xmm1    # 0x19a30
movsd %xmm1, 0x70(%rbx)
pushq $0x2
popq %rdi
xorl %eax, %eax
movq -0x40(%rbp), %rsp
movapd -0x60(%rbp), %xmm5
movl 0x14(%r15), %edx
testl %edx, %edx
js 0x58e2
movl 0x1c(%r15), %ecx
testl %ecx, %ecx
js 0x58e2
movslq 0x24(%r15), %rsi
testq %rsi, %rsi
js 0x58e2
cmpl (%rbx), %esi
jge 0x58e2
cmpl 0x10(%r15), %edx
jne 0x5972
testb %al, %al
je 0x5901
xorl %r14d, %r14d
xorl %eax, %eax
movapd %xmm5, -0x60(%rbp)
callq 0x8a45
movapd -0x60(%rbp), %xmm5
movapd -0x70(%rbp), %xmm3
jmp 0x592a
pushq $0x1
popq %r14
ucomisd 0x14123(%rip), %xmm5    # 0x19a30
movapd -0x70(%rbp), %xmm3
jne 0x5916
jnp 0x5925
movapd -0x50(%rbp), %xmm0
mulsd %xmm5, %xmm0
mulsd %xmm5, %xmm3
jmp 0x592a
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 %r14d, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r13, -0x30(%rbp)
movq 0xa0(%rbx), %rax
movq (%rax,%rsi,8), %r13
movl 0x8(%r13), %eax
cmpl %eax, %edx
jge 0x5b43
cmpl %eax, %ecx
ja 0x5b62
subl %edx, %ecx
jbe 0x5b81
movl %edi, -0x40(%rbp)
movsd %xmm0, -0x38(%rbp)
movapd %xmm5, -0x60(%rbp)
cmpq $0x0, 0x38(%r15)
je 0x5ba0
movq %rsp, -0x78(%rbp)
leaq 0xf(,%rcx,4), %rax
andq $-0x10, %rax
movq %rsp, %r14
subq %rax, %r14
movq %r14, %rsp
leaq 0xf(,%rcx,8), %rax
andq $-0x10, %rax
movq %rsp, %r12
subq %rax, %r12
movq %r12, %rsp
movq 0x38(%r15), %rdi
movq -0x30(%rbp), %rax
movl 0x3b0(%rax), %edx
subq $0x8, %rsp
movq %r13, %rsi
movq %r14, %r8
movq %r12, %r9
pushq $0x0
callq 0x451c
addq $0x10, %rsp
movslq 0x14(%r15), %rax
movslq 0x1c(%r15), %rcx
xorl %edx, %edx
movapd -0x70(%rbp), %xmm3
movsd -0x38(%rbp), %xmm4
cmpq %rcx, %rax
jge 0x5a82
movss (%r14,%rdx,4), %xmm1
cvtss2sd %xmm1, %xmm2
movq 0x30(%r13), %rsi
addss (%rsi,%rax,4), %xmm1
movss %xmm1, (%rsi,%rax,4)
addsd 0x68(%rbx), %xmm2
movsd %xmm2, 0x68(%rbx)
movsd (%r12,%rdx,8), %xmm1
addsd %xmm4, %xmm1
incq %rdx
movq 0x38(%r13), %rsi
cvtss2sd (%rsi,%rax,4), %xmm2
addsd %xmm1, %xmm2
cvtsd2ss %xmm2, %xmm1
movss %xmm1, (%rsi,%rax,4)
movq 0x40(%r13), %rsi
cvtss2sd (%rsi,%rax,4), %xmm1
addsd %xmm3, %xmm1
cvtsd2ss %xmm1, %xmm1
movss %xmm1, (%rsi,%rax,4)
incq %rax
jmp 0x5a1d
movapd -0x50(%rbp), %xmm1
addsd %xmm0, %xmm1
movapd %xmm1, -0x50(%rbp)
movq 0x38(%r15), %rdi
movq -0x30(%rbp), %rax
movl 0x3b0(%rax), %esi
callq 0x5bbf
movsd 0x70(%rbx), %xmm0
addsd 0x13f80(%rip), %xmm0    # 0x19a30
movsd %xmm0, 0x70(%rbx)
movq -0x78(%rbp), %rsp
movapd -0x60(%rbp), %xmm5
movl -0x40(%rbp), %r14d
jmp 0x5905
leaq 0x1868b(%rip), %rdi     # 0x1e159
leaq 0x18260(%rip), %rsi     # 0x1dd35
leaq 0x1869a(%rip), %rcx     # 0x1e176
movl $0x448, %edx            # imm = 0x448
callq 0x3230
leaq 0x186e1(%rip), %rdi     # 0x1e1ce
leaq 0x18241(%rip), %rsi     # 0x1dd35
leaq 0x1867b(%rip), %rcx     # 0x1e176
movl $0x46c, %edx            # imm = 0x46C
callq 0x3230
leaq 0x186e6(%rip), %rdi     # 0x1e1f2
leaq 0x18222(%rip), %rsi     # 0x1dd35
leaq 0x1865c(%rip), %rcx     # 0x1e176
movl $0x46d, %edx            # imm = 0x46D
callq 0x3230
leaq 0x186ea(%rip), %rdi     # 0x1e215
leaq 0x18203(%rip), %rsi     # 0x1dd35
leaq 0x1863d(%rip), %rcx     # 0x1e176
movl $0x46e, %edx            # imm = 0x46E
callq 0x3230
leaq 0x186ef(%rip), %rdi     # 0x1e239
leaq 0x181e4(%rip), %rsi     # 0x1dd35
leaq 0x1861e(%rip), %rcx     # 0x1e176
movl $0x490, %edx            # imm = 0x490
callq 0x3230
leaq 0x186f4(%rip), %rdi     # 0x1e25d
leaq 0x181c5(%rip), %rsi     # 0x1dd35
leaq 0x185ff(%rip), %rcx     # 0x1e176
movl $0x491, %edx            # imm = 0x491
callq 0x3230
leaq 0x186f8(%rip), %rdi     # 0x1e280
leaq 0x181a6(%rip), %rsi     # 0x1dd35
leaq 0x185e0(%rip), %rcx     # 0x1e176
movl $0x492, %edx            # imm = 0x492
callq 0x3230
leaq 0x186fd(%rip), %rdi     # 0x1e2a4
leaq 0x18187(%rip), %rsi     # 0x1dd35
leaq 0x185c1(%rip), %rcx     # 0x1e176
movl $0x493, %edx            # imm = 0x493
callq 0x3230