323 #include <uves_extract_profile.h>
325 #include <uves_extract_iterate.h>
326 #include <uves_error.h>
332 uves_extract_profile *
333 uves_extract_profile_new_constant(
double slit_length)
335 uves_extract_profile *p = NULL;
337 p = cpl_malloc(
sizeof(uves_extract_profile));
340 p->slit_length = slit_length;
367 uves_extract_profile *
368 uves_extract_profile_new(
int (*f) (
const double x[],
const double a[],
double *result),
369 int (*dfda)(
const double x[],
const double a[],
double result[]),
374 uves_extract_profile *p = NULL;
376 p = cpl_malloc(
sizeof(uves_extract_profile));
387 p->y0 = cpl_calloc(
sizeof(
polynomial *), 100);
388 p->sigma = cpl_calloc(
sizeof(
polynomial *), 100);
389 p->red_chisq = cpl_calloc(
sizeof(
polynomial *), 100);
398 p->sampling_factor = 0;
399 p->is_zero_degree = NULL;
402 p->current_profile = NULL;
403 p->current_ypos = NULL;
404 p->current_interpolated = NULL;
409 p->spatial_bins = uves_extract_profile_get_nbins(slit_length, sampling_factor);
410 p->slit_length = slit_length;
411 p->sampling_factor = sampling_factor;
412 p->spatial_bins = uves_extract_profile_get_nbins(slit_length, sampling_factor);
413 p->is_zero_degree = cpl_calloc(p->spatial_bins,
sizeof(
bool));
414 p->dy_poly = cpl_calloc(p->spatial_bins,
sizeof(
polynomial *));
415 p->dy_double = cpl_calloc(p->spatial_bins,
sizeof(
double));
416 p->current_profile = cpl_calloc(p->spatial_bins,
sizeof(
double));
417 p->current_ypos = cpl_calloc(p->spatial_bins,
sizeof(
double));
418 p->current_interpolated = cpl_calloc(slit_length + 3,
sizeof(
double));
441 uves_extract_profile_delete(uves_extract_profile **p)
443 if (*p == NULL)
return;
449 else if((*p)->f != NULL)
463 for (i = 0; i < (*p)->spatial_bins; i++)
467 cpl_free((*p)->is_zero_degree);
468 cpl_free((*p)->dy_poly);
469 cpl_free((*p)->dy_double);
470 cpl_free((*p)->current_profile);
471 cpl_free((*p)->current_ypos);
472 cpl_free((*p)->current_interpolated);
488 uves_extract_profile_get_nbins(
double slit_length,
int sampling_factor)
490 return uves_round_double(slit_length + 3) * sampling_factor;
506 uves_extract_profile_get_y(uves_iterate_position *pos,
510 return bin*1.0/sampling_factor + (pos->ycenter - pos->sg.length/2 - 1);
526 uves_extract_profile_get_bin(
const uves_iterate_position *pos,
529 return sampling_factor*(pos->y - (pos->ycenter - pos->sg.length/2 - 1));
552 uves_extract_profile_set(
const uves_extract_profile *p,
553 uves_iterate_position *pos,
557 ((uves_extract_profile *)p)->current_area = pos->yhigh - pos->ylow + 1;
559 else if (p->f != NULL)
562 double min_sigma = 0.1;
566 check( ((uves_extract_profile *)p)->current_y0 =
569 "Error evaluating polynomial");
571 check( ((uves_extract_profile *)p)->current_y0 =
573 "Error evaluating polynomial");
577 check( ((uves_extract_profile *)p)->current_sigma =
579 "Error evaluating polynomial");
581 check( ((uves_extract_profile *)p)->current_sigma =
583 "Error evaluating polynomial");
592 if (p->current_sigma < min_sigma)
595 if (warnings != NULL && *warnings == 0)
599 "%e pixels at (order, x) = (%d, %d). "
600 "Setting sigma = %.2f pixels",
601 p->current_sigma, pos->order, pos->x, min_sigma);
604 ((uves_extract_profile *)p)->current_sigma = min_sigma;
620 ((uves_extract_profile *)p)->current_area = 1;
623 for (pos->y = pos->ylow; pos->y <= pos->yhigh; pos->y++)
640 area += uves_extract_profile_evaluate(p, pos);
652 ((uves_extract_profile *)p)->current_area = area;
658 ((uves_extract_profile *)p)->current_area = 1;
668 for (i = 0; i < p->spatial_bins; i++)
671 if (p->is_zero_degree[i])
673 prof = uves_max_double(0, p->dy_double[i]);
678 prof = uves_max_double(
684 p->current_ypos[i] = uves_extract_profile_get_y(pos, i, p->sampling_factor);
685 p->current_profile[i] = prof;
692 for (pos->y = pos->ylow; pos->y <= pos->yhigh; pos->y++)
698 double bin = uves_extract_profile_get_bin(pos, p->sampling_factor);
699 pint = p->current_profile[uves_round_double(bin)];
715 double bin = uves_extract_profile_get_bin(pos,
718 int bin_lower = (int) bin;
719 int bin_upper = bin_lower + 1;
721 double prof_lower = p->current_profile[bin_lower];
722 double prof_upper = p->current_profile[bin_upper];
724 double weight = bin_upper - bin;
726 pint = weight*prof_lower + (1-weight)*prof_upper;
732 p->current_ypos, p->current_profile,
737 p->current_interpolated[pos->y - pos->ylow] = pint;
748 for (pos->y = pos->ylow; pos->y <= pos->yhigh; pos->y++)
750 p->current_interpolated[pos->y - pos->ylow] /= sum;
772 uves_extract_profile_evaluate(
const uves_extract_profile *profile,
773 const uves_iterate_position *pos)
777 if (profile->constant) {
778 result = 1.0 / profile->current_area;
780 else if (profile->f != NULL)
784 a[0] = profile->current_y0;
785 a[1] = profile->current_sigma;
786 a[2] = 1/profile->current_area;
801 double xp[3] = {-0.387298334621, 0, 0.387298334621};
802 double weight[3] = {0.2777777777778, 0.444444444444, 0.2777777777778};
806 for (i = 0; i < 3; i++)
811 a[0] = profile->current_y0 + xp[i];
812 profile->f(&y, a, &val);
813 result += weight[i] * val;
820 a[0] = profile->current_y0;
821 profile->f(&y, a, &result);
828 result = profile->current_interpolated[pos->y - pos->ylow];