// File: /workspace/github_c_makefile_star2_O2/radforddc[P]icpc_siggen/calc_signal.c
// Function: get_signal
int get_signal(point pt, float *signal_out, MJD_Siggen_Setup *setup) {
  static float *signal, *sum, *tmp;
  static int tsteps = 0;
  float w, x, y;
  char  tmpstr[MAX_LINE];
  int   j, k, l, dt, err, comp_f;

  /* first time -- allocate signal and sum arrays */
  if (tsteps != setup->time_steps_calc) {
    tsteps = setup->time_steps_calc;
    if ((signal = (float *) malloc(tsteps*sizeof(*signal))) == NULL ||
	(tmp    = (float *) malloc(tsteps*sizeof(*tmp))) == NULL ||
	(sum    = (float *) malloc(tsteps*sizeof(*sum))) == NULL) {
      error("malloc failed in get_signal\n");
      return -1;
    }
  }

  for (j = 0; j < tsteps; j++) signal[j] = 0.0;

  if (outside_detector(pt, setup)) {
    TELL_CHATTY("Point %s is outside detector!\n", pt_to_str(tmpstr, MAX_LINE, pt));
    return -1;
  }
  TELL_CHATTY("Calculating signal for %s...\n", pt_to_str(tmpstr, MAX_LINE, pt));

  memset(setup->dpath_e, 0, tsteps*sizeof(point));
  memset(setup->dpath_h, 0, tsteps*sizeof(point));

  err = make_signal(pt, signal, ELECTRON_CHARGE, setup);
  err = make_signal(pt, signal, HOLE_CHARGE, setup);
  /* make_signal returns 1 for success; require hole signal but not electron */

  /* change from current signal to charge signal, i.e.
     each time step contains the summed signals of all previous time steps */
  for (j = 1; j < tsteps; j++) signal[j] += signal[j-1];

  if (signal_out != NULL) {

    if (setup->charge_cloud_size > 0.001 || setup->use_diffusion) {
      /* convolute with a Gaussian to correct for charge cloud size
	 and initial velocity
	 charge_cloud_size = initial FWHM of charge cloud, in mm,
	 NOTE this uses initial velocity of holes only;
	 this may not be quite right if electron signal is strong */
      /* difference in time between center and edge of charge cloud */
      dt = (int) (1.5f + setup->charge_cloud_size /
		  (setup->step_time_calc * setup->initial_vel));
      if (setup->initial_vel < 0.00001f) dt = 0;
      TELL_CHATTY("Initial vel, size, dt = %f mm/ns, %f mm, %d steps\n",
		  setup->initial_vel, setup->charge_cloud_size, dt);
      if (setup->use_diffusion) {
	dt = (int) (1.5f + setup->final_charge_size /
		    (setup->step_time_calc * setup->final_vel));
	TELL_CHATTY("  Final vel, size, dt = %f mm/ns, %f mm, %d steps\n",
		    setup->final_vel, setup->final_charge_size, dt);
      }
      if (dt > 1) {
	/* Gaussian */
	w = ((float) dt) / 2.355;
	l = dt/10;     // use l to speed up convolution of waveform with gaussian;
	if (l < 1) {   // instead of using every 1-ns step, use steps of FWHM/10
	  l = 1;
	} else if (setup->step_time_out > setup->preamp_tau) {
	  if (l > setup->step_time_out/setup->step_time_calc)
	    l = setup->step_time_out/setup->step_time_calc;
	} else {
	  if (l > setup->preamp_tau/setup->step_time_calc)
	    l = setup->preamp_tau/setup->step_time_calc;
	}
	// TELL_CHATTY(">> l: %d\n", l);
	for (j = 0; j < tsteps; j++) {
	  sum[j] = 1.0;
	  tmp[j] = signal[j];
	}
	for (k = l; k < 2*dt; k+=l) {
	  x = ((float) k)/w;
	  y = exp(-x*x/2.0);
	  for (j = 0; j < tsteps - k; j++){
	    sum[j] += y;
	    tmp[j] += signal[j+k] * y;
	    sum[j+k] += y;
	    tmp[j+k] += signal[j] * y;
	  }
	}
        for (j = 0; j < tsteps; j++){
          signal[j] = tmp[j]/sum[j];
        }
      }
    }

    /* now, compress the signal and place it in the signal_out array;
       truncate the signal if time_steps_calc % ntsteps_out != 0 */
    comp_f = setup->time_steps_calc/setup->ntsteps_out;
    for (j = 0; j < setup->ntsteps_out; j++) signal_out[j] = 0;
    for (j = 0; j < setup->ntsteps_out*comp_f; j++)
      signal_out[j/comp_f] += signal[j]/comp_f;

    /* do RC integration for preamp risetime */
    if (setup->preamp_tau/setup->step_time_out >= 0.1f)
      rc_integrate(signal_out, signal_out,
		   setup->preamp_tau/setup->step_time_out, setup->ntsteps_out);
  }

  /* make_signal returns 1 for success; require hole signal but not electron */
  if (err) return -1;
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x238, %rsp            # imm = 0x238
movq %rsi, %r13
movq %rdi, %rbx
movss %xmm1, 0xc(%rsp)
movaps %xmm0, 0x10(%rsp)
movl 0xcbf3(%rip), %eax      # 0xf210
movl 0x390(%rsi), %r14d
cmpl %r14d, %eax
jne 0x26a6
movq 0xcbc8(%rip), %r15      # 0xf1f8
movl %eax, %r14d
xorl %eax, %eax
testl %r14d, %r14d
cmovlel %eax, %r14d
cmpq %rax, %r14
je 0x264b
andl $0x0, (%r15,%rax,4)
incq %rax
jmp 0x263c
movaps 0x10(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
movq %r13, %rdi
callq 0x3874
movl (%r13), %ecx
testl %eax, %eax
je 0x270d
pushq $-0x1
popq %rbx
cmpl $0x2, %ecx
jl 0x2ae6
leaq 0x30(%rsp), %rdi
movl $0x200, %esi            # imm = 0x200
movaps 0x10(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
callq 0x5c68
leaq 0x5b3f(%rip), %rdi      # 0x81d6
movq %rax, %rsi
xorl %eax, %eax
callq 0x24d5
jmp 0x2ae6
movslq %r14d, %r12
movl %r14d, 0xcb60(%rip)     # 0xf210
shlq $0x2, %r12
movq %r12, %rdi
callq 0x20d0
movq %rax, 0xcb35(%rip)      # 0xf1f8
testq %rax, %rax
je 0x26f7
movq %rax, %r15
movq %r12, %rdi
callq 0x20d0
movq %rax, 0xcb2e(%rip)      # 0xf208
testq %rax, %rax
je 0x26f7
movq %r12, %rdi
callq 0x20d0
movq %rax, 0xcb12(%rip)      # 0xf200
testq %rax, %rax
jne 0x2633
leaq 0x5abb(%rip), %rdi      # 0x81b9
xorl %eax, %eax
callq 0x255d
pushq $-0x1
popq %rbx
jmp 0x2ae6
cmpl $0x2, %ecx
jl 0x273d
leaq 0x30(%rsp), %rdi
movl $0x200, %esi            # imm = 0x200
movaps 0x10(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
callq 0x5c68
leaq 0x5ac2(%rip), %rdi      # 0x81f5
movq %rax, %rsi
xorl %eax, %eax
callq 0x24d5
movq 0x1580(%r13), %rdi
movslq 0xcac5(%rip), %rax      # 0xf210
imulq $0xc, %rax, %r15
xorl %esi, %esi
movq %r15, %rdx
callq 0x2050
movq 0x1588(%r13), %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x2050
movq 0xca87(%rip), %rdi      # 0xf1f8
movss 0x588b(%rip), %xmm2     # 0x8004
movaps 0x10(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
movq %r13, %rsi
callq 0x2b4a
movq 0xca65(%rip), %rdi      # 0xf1f8
movss 0x586d(%rip), %xmm2     # 0x8008
movaps 0x10(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
movq %r13, %rsi
callq 0x2b4a
movl %eax, %ebp
movslq 0xca59(%rip), %rax      # 0xf210
movq 0xca3a(%rip), %rcx      # 0xf1f8
pushq $0x1
popq %rdx
cmpq %rax, %rdx
jge 0x27db
movss -0x4(%rcx,%rdx,4), %xmm0
addss (%rcx,%rdx,4), %xmm0
movss %xmm0, (%rcx,%rdx,4)
incq %rdx
jmp 0x27c1
testq %rbx, %rbx
je 0x2add
movss 0x39c(%r13), %xmm2
cvtss2sd %xmm2, %xmm1
ucomisd 0x5827(%rip), %xmm1     # 0x8020
ja 0x2809
cmpl $0x0, 0x3a0(%r13)
je 0x2a48
movss 0x1594(%r13), %xmm0
movss 0x394(%r13), %xmm3
mulss %xmm0, %xmm3
divss %xmm3, %xmm2
addss 0x57e1(%rip), %xmm2     # 0x800c
cvttss2si %xmm2, %eax
xorl %r15d, %r15d
movss 0x57d6(%rip), %xmm2     # 0x8010
ucomiss %xmm0, %xmm2
cmovbel %eax, %r15d
cmpl $0x2, (%r13)
jl 0x285d
cvtss2sd %xmm0, %xmm0
leaq 0x59c0(%rip), %rdi      # 0x8213
movl %r15d, %esi
movb $0x2, %al
callq 0x24d5
cmpl $0x0, 0x3a0(%r13)
je 0x28bb
movsd 0x15a8(%r13), %xmm1
movss 0x1598(%r13), %xmm0
movss 0x394(%r13), %xmm2
mulss %xmm0, %xmm2
cvtss2sd %xmm2, %xmm2
movapd %xmm1, %xmm3
divsd %xmm2, %xmm3
addsd 0x578e(%rip), %xmm3     # 0x8028
cvttsd2si %xmm3, %r15d
cmpl $0x2, (%r13)
jl 0x28bb
cvtss2sd %xmm0, %xmm0
leaq 0x5995(%rip), %rdi      # 0x8246
movl %r15d, %esi
movb $0x2, %al
callq 0x24d5
cmpl $0x2, %r15d
jl 0x2a48
cvtsi2ss %r15d, %xmm0
cvtss2sd %xmm0, %xmm0
divsd 0x575a(%rip), %xmm0     # 0x8030
xorl %r8d, %r8d
pushq $0xa
popq %rcx
movl %r15d, %eax
xorl %edx, %edx
divl %ecx
cmpl $0xa, %r15d
jae 0x2afa
pushq $0x1
popq %rax
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xc(%rsp)
movl 0xc910(%rip), %ecx      # 0xf210
movq 0xc8f9(%rip), %rdx      # 0xf200
movq 0xc8ea(%rip), %rsi      # 0xf1f8
movq 0xc8f3(%rip), %rdi      # 0xf208
testl %ecx, %ecx
movl $0x0, %r9d
cmovgl %ecx, %r9d
cmpq %r8, %r9
je 0x293f
movl $0x3f800000, (%rdx,%r8,4) # imm = 0x3F800000
movss (%rsi,%r8,4), %xmm0
movss %xmm0, (%rdi,%r8,4)
incq %r8
jmp 0x2921
movl %ebp, 0x2c(%rsp)
movq %r13, 0x10(%rsp)
addl %r15d, %r15d
movslq %eax, %r14
leaq (,%r14,4), %rbp
movq %rbp, %r13
movq %r14, %r12
cmpq %r15, %r12
jge 0x2a1f
cvtsi2ss %r12d, %xmm0
divss 0xc(%rsp), %xmm0
mulss %xmm0, %xmm0
cvtss2sd %xmm0, %xmm0
mulsd 0x56b8(%rip), %xmm0     # 0x8038
callq 0x2070
cvtsd2ss %xmm0, %xmm0
movslq 0xc880(%rip), %rcx      # 0xf210
movq %rcx, %rax
subq %r12, %rax
movq 0xc863(%rip), %rdx      # 0xf200
movq 0xc854(%rip), %rsi      # 0xf1f8
movq 0xc85d(%rip), %rdi      # 0xf208
movq %rdx, %r8
movq %rdi, %r9
movq %rsi, %r10
xorl %r11d, %r11d
cmpq %rax, %r11
jge 0x2a14
movss (%r8), %xmm1
addss %xmm0, %xmm1
movss %xmm1, (%r8)
movss (%r10,%r13), %xmm1
mulss %xmm0, %xmm1
addss (%r9), %xmm1
movss %xmm1, (%r9)
movss (%r8,%r13), %xmm1
addss %xmm0, %xmm1
movss %xmm1, (%r8,%r13)
movss (%r10), %xmm1
mulss %xmm0, %xmm1
addss (%r9,%r13), %xmm1
movss %xmm1, (%r9,%r13)
incq %r11
addq $0x4, %r10
addq $0x4, %r9
addq $0x4, %r8
jmp 0x29b7
addq %r14, %r12
addq %rbp, %r13
jmp 0x295c
xorl %eax, %eax
testl %ecx, %ecx
cmovlel %eax, %ecx
movq 0x10(%rsp), %r13
movl 0x2c(%rsp), %ebp
cmpq %rax, %rcx
je 0x2a48
movss (%rdi,%rax,4), %xmm0
divss (%rdx,%rax,4), %xmm0
movss %xmm0, (%rsi,%rax,4)
incq %rax
jmp 0x2a2f
movl 0x390(%r13), %eax
movl 0x3ac(%r13), %ecx
xorl %edx, %edx
testl %ecx, %ecx
movl $0x0, %esi
cmovgl %ecx, %esi
cmpq %rdx, %rsi
je 0x2a70
andl $0x0, (%rbx,%rdx,4)
incq %rdx
jmp 0x2a62
cltd
idivl %ecx
movl %eax, %esi
cvtsi2ss %eax, %xmm0
movq 0xc778(%rip), %r8       # 0xf1f8
movl %eax, %r9d
imull %ecx, %r9d
xorl %edi, %edi
testl %r9d, %r9d
cmovlel %edi, %r9d
cmpq %rdi, %r9
je 0x2ab5
movss (%r8,%rdi,4), %xmm1
divss %xmm0, %xmm1
movl %edi, %eax
cltd
idivl %esi
cltq
addss (%rbx,%rax,4), %xmm1
movss %xmm1, (%rbx,%rax,4)
incq %rdi
jmp 0x2a90
movss 0x38c(%r13), %xmm0
divss 0x398(%r13), %xmm0
ucomiss 0x5546(%rip), %xmm0     # 0x8014
jb 0x2add
movq %rbx, %rdi
movq %rbx, %rsi
movl %ecx, %edx
callq 0x35fd
xorl %ebx, %ebx
negl %ebp
sbbl %ebx, %ebx
orl $0x1, %ebx
movl %ebx, %eax
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movss 0x398(%r13), %xmm1
movss 0x38c(%r13), %xmm2
ucomiss %xmm2, %xmm1
movss 0x394(%r13), %xmm4
cvtsi2ss %eax, %xmm3
jbe 0x2b34
divss %xmm4, %xmm1
ucomiss %xmm1, %xmm3
jbe 0x28f0
cvttss2si %xmm1, %eax
jmp 0x28f0
divss %xmm4, %xmm2
ucomiss %xmm2, %xmm3
jbe 0x28f0
cvttss2si %xmm2, %eax
jmp 0x28f0