// File: /workspace/github_c_makefile_star2_O3/PoulinV[P]AxiCLASS/build/../source/transfer.c
// Function: transfer_selection_function
int transfer_selection_function(
                                struct precision * ppr,
                                struct perturbations * ppt,
                                struct transfer * ptr,
                                int bin,
                                double z,
                                double * selection) {

  double x;
  double dNdz;
  double dln_dNdz_dz;
  int last_index;

  /* trivial dirac case */
  if (ppt->selection==dirac) {

    *selection=1.;

    return _SUCCESS_;
  }

  /* difference between z and the bin center (we can take the absolute
     value as long as all selection functions are symmetric around
     x=0) */
  x=fabs(z-ppt->selection_mean[bin]);

  /* gaussian case (the function is anyway normalized later
     automatically, but could not resist to normalize it already
     here) */
  if (ppt->selection==gaussian) {

    *selection = exp(-0.5*pow(x/ppt->selection_width[bin],2))
      /ppt->selection_width[bin]/sqrt(2.*_PI_);

    if ((ptr->has_nz_file == _TRUE_) || (ptr->has_nz_analytic == _TRUE_)) {

      if (ptr->has_nz_file == _TRUE_) {

        class_test((z<ptr->nz_z[0]) || (z>ptr->nz_z[ptr->nz_size-1]),
                   ptr->error_message,
                   "Your input file for the selection function only covers the redshift range [%f : %f]. However, your input for the selection function requires z=%f",
                   ptr->nz_z[0],
                   ptr->nz_z[ptr->nz_size-1],
                   z);

        class_call(array_interpolate_spline(
                                            ptr->nz_z,
                                            ptr->nz_size,
                                            ptr->nz_nz,
                                            ptr->nz_ddnz,
                                            1,
                                            z,
                                            &last_index,
                                            &dNdz,
                                            1,
                                            ptr->error_message),
                   ptr->error_message,
                   ptr->error_message);
      }
      else {

        class_call(transfer_dNdz_analytic(ptr,
                                          z,
                                          &dNdz,
                                          &dln_dNdz_dz),
                   ptr->error_message,
                   ptr->error_message);
      }

      *selection *= dNdz;
    }

    return _SUCCESS_;
  }

  /* top-hat case, with smoothed edges. The problem with sharp edges
     is that the final result will be affected by random
     noise. Indeed, the values of k at which the transfer functions
     Delta_l(k) are sampled will never coincide with the actual edges
     of the true transfer function (computed with or even without the
     Limber approximation). Hence the integral Cl=\int dk
     Delta_l(k)**2 (...) will be imprecise and will fluctuate randomly
     with the resolution along k. With smooth edges, the problem is
     solved, and the final Cls become mildly dependent on the
     resolution along k. */

  if (ppt->selection==tophat) {

    /* selection function, centered on z=mean (i.e. on x=0), equal to
       one around x=0, with tanh step centered on x=width, of width
       delta x = 0.1*width
    */
    *selection=(1.-tanh((x-ppt->selection_width[bin])/(ppr->selection_tophat_edge*ppt->selection_width[bin])))/2.;

    if ((ptr->has_nz_file == _TRUE_) || (ptr->has_nz_analytic == _TRUE_)) {

      if (ptr->has_nz_file == _TRUE_) {

        class_call(array_interpolate_spline(
                                            ptr->nz_z,
                                            ptr->nz_size,
                                            ptr->nz_nz,
                                            ptr->nz_ddnz,
                                            1,
                                            z,
                                            &last_index,
                                            &dNdz,
                                            1,
                                            ptr->error_message),
                   ptr->error_message,
                   ptr->error_message);
      }
      else {

        class_call(transfer_dNdz_analytic(ptr,
                                          z,
                                          &dNdz,
                                          &dln_dNdz_dz),
                   ptr->error_message,
                   ptr->error_message);
      }

      *selection *= dNdz;
    }

    return _SUCCESS_;
  }

  /* get here only if selection type was recognized */
  class_stop(ptr->error_message,
             "invalid choice of selection function");

  return _SUCCESS_;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x1020, %rsp           # imm = 0x1020
movq %r8, %rbx
movl 0x68(%rsi), %eax
cmpl $0x2, %eax
jne 0xad1e3
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, (%rbx)
jmp 0xad4d0
movapd %xmm0, %xmm1
movq %rdx, %r14
movq %rsi, %r15
movslq %ecx, %r12
subsd 0x70(%rsi,%r12,8), %xmm0
andpd 0x41041(%rip), %xmm0    # 0xee240
cmpl $0x1, %eax
je 0xad30f
testl %eax, %eax
jne 0xad46e
movsd %xmm1, 0x8(%rsp)
divsd 0x390(%r15,%r12,8), %xmm0
mulsd %xmm0, %xmm0
mulsd 0x4424c(%rip), %xmm0    # 0xf1478
callq 0x8670
divsd 0x390(%r15,%r12,8), %xmm0
divsd 0x5d85d(%rip), %xmm0    # 0x10aaa0
movsd %xmm0, (%rbx)
cmpw $0x1, 0x658(%r14)
jne 0xad3fc
movq 0x760(%r14), %rdi
movsd (%rdi), %xmm0
leaq 0x96a(%r14), %r15
movsd 0x8(%rsp), %xmm2
ucomisd %xmm2, %xmm0
movslq 0x75c(%r14), %rsi
movsd -0x8(%rdi,%rsi,8), %xmm1
ja 0xad4d4
ucomisd %xmm1, %xmm2
ja 0xad4d4
movq 0x768(%r14), %rdx
movq 0x770(%r14), %rcx
subq $0x8, %rsp
leaq 0x28(%rsp), %rax
movl $0x1, %ebp
leaq 0x24(%rsp), %r9
movl $0x1, %r8d
movapd %xmm2, %xmm0
pushq %r15
pushq $0x1
pushq %rax
callq 0x18071
addq $0x20, %rsp
cmpl $0x1, %eax
jne 0xad4c2
leaq 0x41118(%rip), %rsi     # 0xee3f0
leaq 0x725ba(%rip), %rdx     # 0x11f899
leaq 0x820(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rcx
xorl %eax, %eax
callq 0x30af0
leaq 0x40d39(%rip), %rsi     # 0xee034
leaq 0x7257b(%rip), %rdx     # 0x11f87d
movq %r15, %rdi
movl $0xa8b, %ecx            # imm = 0xA8B
jmp 0xad3ed
movsd %xmm1, 0x8(%rsp)
movsd 0x390(%r15,%r12,8), %xmm1
subsd %xmm1, %xmm0
mulsd 0x828(%rdi), %xmm1
divsd %xmm1, %xmm0
callq 0x80d0
movsd 0x40f24(%rip), %xmm1    # 0xee260
subsd %xmm0, %xmm1
mulsd 0x41988(%rip), %xmm1    # 0xeecd0
movsd %xmm1, (%rbx)
cmpw $0x1, 0x658(%r14)
jne 0xad3fc
movq 0x760(%r14), %rdi
movl 0x75c(%r14), %esi
movq 0x768(%r14), %rdx
movq 0x770(%r14), %rcx
addq $0x96a, %r14            # imm = 0x96A
subq $0x8, %rsp
leaq 0x28(%rsp), %rax
movl $0x1, %ebp
leaq 0x24(%rsp), %r9
movl $0x1, %r8d
movsd 0x10(%rsp), %xmm0
pushq %r14
pushq $0x1
pushq %rax
callq 0x18071
addq $0x20, %rsp
cmpl $0x1, %eax
jne 0xad4c2
leaq 0x41035(%rip), %rsi     # 0xee3f0
leaq 0x724d7(%rip), %rdx     # 0x11f899
leaq 0x820(%rsp), %rbx
movq %rbx, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x30af0
leaq 0x40c56(%rip), %rsi     # 0xee034
leaq 0x72498(%rip), %rdx     # 0x11f87d
movq %r14, %rdi
movl $0xac0, %ecx            # imm = 0xAC0
movq %rbx, %r8
xorl %eax, %eax
callq 0x30af0
jmp 0xad532
cmpw $0x1, 0x65a(%r14)
movsd 0x8(%rsp), %xmm0
jne 0xad4d0
divsd 0x70f37(%rip), %xmm0    # 0x11e350
movsd %xmm0, 0x8(%rsp)
movapd %xmm0, %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
movsd 0x43b93(%rip), %xmm1    # 0xf0fc8
callq 0x8620
xorpd 0x40dee(%rip), %xmm0    # 0xee230
callq 0x8670
mulsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x8(%rsp), %xmm0
movsd 0x43b67(%rip), %xmm1    # 0xf0fc8
callq 0x8620
movsd 0x10(%rsp), %xmm0
jmp 0xad4c8
leaq 0x724a2(%rip), %rsi     # 0x11f917
leaq 0x820(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x30af0
leaq 0x410f7(%rip), %rsi     # 0xee585
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x30af0
addq $0x96a, %r14            # imm = 0x96A
leaq 0x40b86(%rip), %rsi     # 0xee034
leaq 0x723c8(%rip), %rdx     # 0x11f87d
movq %r14, %rdi
movl $0xad4, %ecx            # imm = 0xAD4
movq %r15, %r8
jmp 0xad526
movsd 0x20(%rsp), %xmm0
mulsd (%rbx), %xmm0
movsd %xmm0, (%rbx)
xorl %ebp, %ebp
jmp 0xad532
leaq 0x722de(%rip), %rsi     # 0x11f7b9
leaq 0x820(%rsp), %rbx
movq %rbx, %rdi
movb $0x3, %al
callq 0x30af0
leaq 0x40b8e(%rip), %rsi     # 0xee082
leaq 0x72350(%rip), %rdx     # 0x11f84b
leaq 0x20(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x30af0
leaq 0x40b20(%rip), %rsi     # 0xee034
leaq 0x72362(%rip), %rdx     # 0x11f87d
movq %r15, %rdi
movl $0xa7d, %ecx            # imm = 0xA7D
movq %r14, %r8
xorl %eax, %eax
callq 0x30af0
movl $0x1, %ebp
movl %ebp, %eax
addq $0x1020, %rsp           # imm = 0x1020
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq