// File: /workspace/github_c_makefile_star2_O1/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 $0x38, %rsp
movsd (%rdi), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x75e6
movq %rdx, %r13
movq %rsi, %rbx
movq %rdi, %r15
callq 0x3290
callq 0xa88a
movsd %xmm0, -0x30(%rbp)
movsd 0x8(%r15), %xmm0
callq 0x3290
callq 0xa88a
movsd %xmm0, -0x38(%rbp)
movl 0x40(%r15), %r14d
movq %r14, %rax
shlq $0x6, %rax
movsd 0x18(%r13,%rax), %xmm0
callq 0x3290
movsd 0x168a8(%rip), %xmm4    # 0x1da68
cmpq $0xb, %r14
ja 0x7201
leaq 0x16967(%rip), %rax     # 0x1db34
movslq (%rax,%r14,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movsd 0x1685a(%rip), %xmm4    # 0x1da38
jmp 0x7201
movsd 0x390(%r13), %xmm0
jmp 0x71f4
movsd 0x3a0(%r13), %xmm0
callq 0x3290
movsd 0x16867(%rip), %xmm4    # 0x1da68
movl 0x10(%r15), %eax
xorl %r12d, %r12d
testl %eax, %eax
movsd -0x38(%rbp), %xmm2
js 0x73a9
movl 0x18(%r15), %ecx
testl %ecx, %ecx
js 0x73a9
movslq 0x20(%r15), %rdx
testq %rdx, %rdx
js 0x73a9
cmpl (%rbx), %edx
jge 0x73a9
movq 0xa0(%rbx), %rsi
movq (%rsi,%rdx,8), %r14
movl 0x8(%r14), %edx
cmpl %edx, %eax
jge 0x7605
cmpl %edx, %ecx
jg 0x7624
movsd %xmm0, -0x50(%rbp)
movq %r13, -0x40(%rbp)
movsd %xmm4, -0x48(%rbp)
subl %eax, %ecx
jle 0x7643
movq %rsp, -0x58(%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 -0x40(%rbp), %rax
movl 0x3b0(%rax), %edx
subq $0x8, %rsp
movq %r14, %rsi
movq %r12, %r8
movq %r13, %r9
pushq $0x0
callq 0x5c84
addq $0x10, %rsp
movslq 0x10(%r15), %rax
movl 0x18(%r15), %ecx
cmpl %eax, %ecx
jle 0x735c
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
movsd -0x38(%rbp), %xmm5
movsd -0x50(%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 0x72f8
movsd %xmm1, 0x68(%rbx)
movsd -0x30(%rbp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, -0x30(%rbp)
movq 0x30(%r15), %rdi
movq -0x40(%rbp), %r13
movl 0x3b0(%r13), %esi
callq 0x76de
movsd 0x70(%rbx), %xmm0
addsd 0x166ad(%rip), %xmm0    # 0x1da38
movsd %xmm0, 0x70(%rbx)
movl $0x1, %r12d
movq -0x58(%rbp), %rsp
movsd -0x38(%rbp), %xmm2
movsd -0x48(%rbp), %xmm4
movsd -0x50(%rbp), %xmm0
movl 0x14(%r15), %eax
testl %eax, %eax
js 0x7559
movl 0x1c(%r15), %ecx
testl %ecx, %ecx
js 0x7559
movslq 0x24(%r15), %rdx
testq %rdx, %rdx
js 0x7559
cmpl (%rbx), %edx
jge 0x7559
cmpl 0x10(%r15), %eax
je 0x7559
movq 0xa0(%rbx), %rsi
movq (%rsi,%rdx,8), %rsi
movl 0x8(%rsi), %edx
cmpl %edx, %eax
jge 0x7662
cmpl %edx, %ecx
jg 0x7681
subl %eax, %ecx
jle 0x76a0
movsd %xmm0, -0x50(%rbp)
movq %r13, -0x40(%rbp)
movsd %xmm4, -0x48(%rbp)
cmpq $0x0, 0x38(%r15)
je 0x76bf
movq %rsp, -0x58(%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 -0x40(%rbp), %rax
movl 0x3b0(%rax), %edx
subq $0x8, %rsp
movq %rsi, -0x60(%rbp)
movq %r13, %r8
movq %r14, %r9
pushq $0x0
callq 0x5c84
addq $0x10, %rsp
movslq 0x14(%r15), %rax
movl 0x1c(%r15), %ecx
cmpl %eax, %ecx
jle 0x7515
movsd 0x68(%rbx), %xmm1
subl %eax, %ecx
shlq $0x2, %rax
movq -0x60(%rbp), %rdi
movq 0x30(%rdi), %rdx
addq %rax, %rdx
movq 0x38(%rdi), %rsi
addq %rax, %rsi
addq 0x40(%rdi), %rax
xorl %edi, %edi
movsd -0x38(%rbp), %xmm5
movsd -0x50(%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 0x74b1
movsd %xmm1, 0x68(%rbx)
incl %r12d
movsd -0x30(%rbp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, -0x30(%rbp)
movq 0x38(%r15), %rdi
movq -0x40(%rbp), %rax
movl 0x3b0(%rax), %esi
callq 0x76de
movsd 0x70(%rbx), %xmm0
addsd 0x164f2(%rip), %xmm0    # 0x1da38
movsd %xmm0, 0x70(%rbx)
movq -0x58(%rbp), %rsp
movsd -0x38(%rbp), %xmm2
movsd -0x48(%rbp), %xmm4
testl %r12d, %r12d
je 0x7579
ucomisd 0x164d2(%rip), %xmm4    # 0x1da38
jne 0x756a
jnp 0x7591
movsd -0x30(%rbp), %xmm0
mulsd %xmm4, %xmm0
mulsd %xmm4, %xmm2
jmp 0x7596
xorl %eax, %eax
movsd %xmm4, -0x48(%rbp)
callq 0xa881
movsd -0x48(%rbp), %xmm4
movsd -0x38(%rbp), %xmm2
jmp 0x7596
movsd -0x30(%rbp), %xmm0
movsd 0x10(%rbx), %xmm3
addsd %xmm0, %xmm3
addsd 0x28(%rbx), %xmm0
movsd %xmm0, 0x28(%rbx)
movsd 0x30(%rbx), %xmm1
addsd %xmm4, %xmm1
movsd %xmm1, 0x30(%rbx)
addsd %xmm2, %xmm3
movsd %xmm3, 0x10(%rbx)
addsd 0x38(%rbx), %xmm2
movsd %xmm2, 0x38(%rbx)
addsd 0x40(%rbx), %xmm4
movsd %xmm4, 0x40(%rbx)
movl %r12d, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1ab3c(%rip), %rdi     # 0x22129
leaq 0x1a711(%rip), %rsi     # 0x21d05
leaq 0x1ab4b(%rip), %rcx     # 0x22146
movl $0x448, %edx            # imm = 0x448
callq 0x3230
leaq 0x1ab92(%rip), %rdi     # 0x2219e
leaq 0x1a6f2(%rip), %rsi     # 0x21d05
leaq 0x1ab2c(%rip), %rcx     # 0x22146
movl $0x46c, %edx            # imm = 0x46C
callq 0x3230
leaq 0x1ab97(%rip), %rdi     # 0x221c2
leaq 0x1a6d3(%rip), %rsi     # 0x21d05
leaq 0x1ab0d(%rip), %rcx     # 0x22146
movl $0x46d, %edx            # imm = 0x46D
callq 0x3230
leaq 0x1ab9b(%rip), %rdi     # 0x221e5
leaq 0x1a6b4(%rip), %rsi     # 0x21d05
leaq 0x1aaee(%rip), %rcx     # 0x22146
movl $0x46e, %edx            # imm = 0x46E
callq 0x3230
leaq 0x1aba0(%rip), %rdi     # 0x22209
leaq 0x1a695(%rip), %rsi     # 0x21d05
leaq 0x1aacf(%rip), %rcx     # 0x22146
movl $0x490, %edx            # imm = 0x490
callq 0x3230
leaq 0x1aba5(%rip), %rdi     # 0x2222d
leaq 0x1a676(%rip), %rsi     # 0x21d05
leaq 0x1aab0(%rip), %rcx     # 0x22146
movl $0x491, %edx            # imm = 0x491
callq 0x3230
leaq 0x1aba9(%rip), %rdi     # 0x22250
leaq 0x1a657(%rip), %rsi     # 0x21d05
leaq 0x1aa91(%rip), %rcx     # 0x22146
movl $0x492, %edx            # imm = 0x492
callq 0x3230
leaq 0x1abae(%rip), %rdi     # 0x22274
leaq 0x1a638(%rip), %rsi     # 0x21d05
leaq 0x1aa72(%rip), %rcx     # 0x22146
movl $0x493, %edx            # imm = 0x493
callq 0x3230