// File: /workspace/github_c_makefile_star2_O2/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 $0x1010, %rsp           # imm = 0x1010
movq %r8, %rbx
movl 0x68(%rsi), %eax
cmpl $0x2, %eax
jne 0xa7a8c
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, (%rbx)
jmp 0xa7cc4
movapd %xmm0, %xmm1
movq %rdx, %r14
movq %rsi, %r15
movslq %ecx, %r12
subsd 0x70(%rsi,%r12,8), %xmm0
andpd 0x3d798(%rip), %xmm0    # 0xe5240
cmpl $0x1, %eax
je 0xa7bb1
testl %eax, %eax
jne 0xa7ccb
movsd %xmm1, (%rsp)
divsd 0x390(%r15,%r12,8), %xmm0
mulsd %xmm0, %xmm0
mulsd 0x40964(%rip), %xmm0    # 0xe8438
callq 0x86a0
divsd 0x390(%r15,%r12,8), %xmm0
divsd 0x59e7d(%rip), %xmm0    # 0x101968
movsd %xmm0, (%rbx)
cmpw $0x1, 0x658(%r14)
jne 0xa7c94
movq 0x760(%r14), %rdi
movsd (%rdi), %xmm0
leaq 0x96a(%r14), %r15
movsd (%rsp), %xmm2
ucomisd %xmm2, %xmm0
movslq 0x75c(%r14), %rsi
movsd -0x8(%rdi,%rsi,8), %xmm1
ja 0xa7d1f
ucomisd %xmm1, %xmm2
ja 0xa7d1f
movq 0x768(%r14), %rdx
movq 0x770(%r14), %rcx
subq $0x8, %rsp
leaq 0x18(%rsp), %rax
pushq $0x1
popq %rbp
leaq 0x14(%rsp), %r9
movl %ebp, %r8d
movapd %xmm2, %xmm0
pushq %r15
pushq $0x1
pushq %rax
callq 0x1604b
addq $0x20, %rsp
cmpl $0x1, %eax
jne 0xa7cb6
leaq 0x3d876(%rip), %rsi     # 0xe53f0
leaq 0x6eba8(%rip), %rdx     # 0x116729
leaq 0x810(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rcx
xorl %eax, %eax
callq 0x2e014
leaq 0x3d497(%rip), %rsi     # 0xe5034
leaq 0x6eb69(%rip), %rdx     # 0x11670d
movq %r15, %rdi
movl $0xa8b, %ecx            # imm = 0xA8B
jmp 0xa7c85
movsd %xmm1, (%rsp)
movsd 0x390(%r15,%r12,8), %xmm1
subsd %xmm1, %xmm0
mulsd 0x828(%rdi), %xmm1
divsd %xmm1, %xmm0
callq 0x80d0
movsd 0x3d683(%rip), %xmm1    # 0xe5260
subsd %xmm0, %xmm1
mulsd 0x3e0c7(%rip), %xmm1    # 0xe5cb0
movsd %xmm1, (%rbx)
cmpw $0x1, 0x658(%r14)
jne 0xa7c94
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 0x18(%rsp), %rax
pushq $0x1
popq %rbp
leaq 0x14(%rsp), %r9
movl %ebp, %r8d
movsd 0x8(%rsp), %xmm0
pushq %r14
pushq $0x1
pushq %rax
callq 0x1604b
addq $0x20, %rsp
cmpl $0x1, %eax
jne 0xa7cb6
leaq 0x3d79d(%rip), %rsi     # 0xe53f0
leaq 0x6eacf(%rip), %rdx     # 0x116729
leaq 0x810(%rsp), %rbx
movq %rbx, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x2e014
leaq 0x3d3be(%rip), %rsi     # 0xe5034
leaq 0x6ea90(%rip), %rdx     # 0x11670d
movq %r14, %rdi
movl $0xac0, %ecx            # imm = 0xAC0
movq %rbx, %r8
xorl %eax, %eax
callq 0x2e014
jmp 0xa7d7b
cmpw $0x1, 0x65a(%r14)
movsd (%rsp), %xmm0
jne 0xa7cc4
leaq 0x10(%rsp), %rsi
leaq 0x810(%rsp), %rdx
callq 0xa7d8d
movsd 0x10(%rsp), %xmm0
mulsd (%rbx), %xmm0
movsd %xmm0, (%rbx)
xorl %ebp, %ebp
jmp 0xa7d7b
leaq 0x6ead5(%rip), %rsi     # 0x1167a7
leaq 0x810(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2e014
leaq 0x3d89a(%rip), %rsi     # 0xe5585
leaq 0x10(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x2e014
addq $0x96a, %r14            # imm = 0x96A
leaq 0x3d329(%rip), %rsi     # 0xe5034
leaq 0x6e9fb(%rip), %rdx     # 0x11670d
movq %r14, %rdi
movl $0xad4, %ecx            # imm = 0xAD4
movq %r15, %r8
jmp 0xa7d71
leaq 0x6e923(%rip), %rsi     # 0x116649
leaq 0x810(%rsp), %rbx
movq %rbx, %rdi
movb $0x3, %al
callq 0x2e014
leaq 0x3d343(%rip), %rsi     # 0xe5082
leaq 0x6e995(%rip), %rdx     # 0x1166db
leaq 0x10(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x2e014
leaq 0x3d2d5(%rip), %rsi     # 0xe5034
leaq 0x6e9a7(%rip), %rdx     # 0x11670d
movq %r15, %rdi
movl $0xa7d, %ecx            # imm = 0xA7D
movq %r14, %r8
xorl %eax, %eax
callq 0x2e014
pushq $0x1
popq %rbp
movl %ebp, %eax
addq $0x1010, %rsp           # imm = 0x1010
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq