12#include <gsl/gsl_version.h>
52 cpl_table_unselect_all(spec_total);
53 cpl_table_or_selected_double(spec_total,
"WAVEL", CPL_NOT_GREATER_THAN,
55 index = (int)cpl_table_count_selected(spec_total);
57 if (index <= cpl_table_get_nrow(spec_total))
65static cpl_size get_index_from_spec_alt(cpl_table* spec_total,
double lambda){
68 double cdelta1, crval1;
70 cdelta1=cpl_table_get(spec_total,
"WAVEL",1, error) -
71 cpl_table_get(spec_total,
"WAVEL",0, error);
73 crval1=cpl_table_get(spec_total,
"WAVEL",0, error);
74 index = (long) (1./cdelta1*lambda-crval1/cdelta1) + 1;
77 double dv = (cdelta1)/crval1;
79 index = (long) log(lambda*r/cdelta1)/log(r);
83 if (index <= cpl_table_get_nrow(spec_total))
106 double cdelta1= cpl_table_get(spec_total,
"WAVEL",1, error) -
107 cpl_table_get(spec_total,
"WAVEL",0, error);
129 cpl_table** spec_region)
131 cpl_errorstate prestate = cpl_errorstate_get();
140 cpl_size begin = index_line - count/2;
143 *spec_region = cpl_table_extract(spec_total,
148 if (!cpl_errorstate_is_equal(prestate)) {
149 return (
int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
150 "Unable to Get region of the spectrum");
154 return CPL_ERROR_NONE;
167 int i,
n = cpl_table_get_nrow(spec_region);
169 for(i=0; i <
n; i++){
170 x[i] = cpl_table_get_double(spec_region,
"WAVEL",i,NULL);
171 y[i] = cpl_table_get_double(spec_region,
"FLUX",i,NULL);
178 int xind1=0,xind2=
n-1,hjk;
180 for (hjk=0; hjk <
n; hjk++){
181 if ((
y[hjk] > cont_rejt) &&
182 (
x[hjk] - (line-klo) >
x[xind1] - (line-klo)) &&
183 (
x[hjk] - (line-klo) < 0))
185 if ((
y[hjk] > cont_rejt) &&
186 (
x[hjk] - (line+klo) <
x[xind2] - (line+klo)) &&
187 (
x[hjk] - (line+klo) > 0) )
198 int i,
n = cpl_table_get_nrow(spec_region);
199 double x[
n],
y[
n], dy[
n];
201 for(i=0; i <
n; i++){
202 x[i] = cpl_table_get_double(spec_region,
"WAVEL",i,NULL);
203 y[i] = cpl_table_get_double(spec_region,
"FLUX",i,NULL);
206 cpl_table* table_deriv = NULL;
207 table_deriv = cpl_table_duplicate(spec_region);
213 for(i=0; i <
n; i++){
214 cpl_table_set_double(table_deriv,
"FLUX",i,dy[i]);
224 int i,
n = cpl_table_get_nrow(spec_region);
226 for(i=0; i <
n; i++){
227 y[i] = cpl_table_get_double(spec_region,
"FLUX",i,NULL);
234 for(i=0; i <
n; i++){
235 cpl_table_set_double(spec_region,
"FLUX",i,sy[i]);
249 for (i=0; (i < (w-1)/2);i++)
251 for (i=(w-1)/2;i<
n-((w-1)/2);i++) {
253 for (j=i-((w-1)/2); j<=i+((w-1)/2);j++)
257 for (i=
n-((w-1)/2); i<
n;i++)
263static void zeroscenterfind(
double iy[],
double y[],
double dy[],
double ddy[],
long n,
long center[],
long *ncenter,
double det_line_thres) {
265 long ctot=0, i, centertot[
n];
266 int signalc=0, signalc_ant=0;
267 if (ddy[0] == abs(ddy[0]))
272 for (i=0; i<
n; i++) {
274 if ( (
float) ddy[i] == fabs( (
float) ddy[i]) )
283 if ((signalc != signalc_ant) &&
284 (dy[i] > 0.01*maxdy) &&
285 (iy[i] < 1. - det_line_thres) &&
296 for (i=0;i<ctot;i++) center[i]=centertot[i];
306 double maxi=
vec[1+nvec/20];
307 for (i=1+nvec/20; i<nvec-nvec/20; i++)
333 cpl_table* line_table,
334 double fit_ngauss_width)
337 cpl_errorstate prestate = cpl_errorstate_get();
341 int i,ns = cpl_table_get_nrow(spec_cont_region);
342 int nl = cpl_table_get_nrow(line_table);
344 double xfit[ns], yfit[ns],
sigma[ns];
346 for(i=0; i < ns; i++){
347 xfit[i] = cpl_table_get_double(spec_cont_region,
"WAVEL",i,NULL);
348 yfit[i] = cpl_table_get_double(spec_cont_region,
"FLUX",i,NULL) - 1.0;
351 sigma[i] = 1.- 0.997573;
356 double acoef[npara], acoef_er[npara];
358 acoef[3*igauss]=cpl_table_get_double(line_table,
"PEAK",i,NULL) - 1.0;
360 acoef[3*igauss+1]=fit_ngauss_width;
361 acoef[3*igauss+2]=cpl_table_get_double(line_table,
"WAVEL",i,NULL);
373 for(i=0; i < nl; i++){
374 cpl_table_set_double(line_table,
"PEAK",i,-acoef[3*i]);
375 cpl_table_set_double(line_table,
"PEAK_ERR",i,acoef_er[3*i]);
376 cpl_table_set_double(line_table,
"WAVEL",i,acoef[3*i+2]);
377 cpl_table_set_double(line_table,
"WAVEL_ERR",i,acoef_er[3*i+2]);
379 cpl_table_set_double(line_table,
"FWHM",i,2.*sqrt(log(2)/acoef[3*i+1]));
380 double ind_ew = acoef[3*i]*sqrt(CPL_MATH_PI/acoef[3*i+1])*-1.;
381 cpl_table_set_double(line_table,
"EW",i,ind_ew*10000.);
382 cpl_table_set_double(line_table,
"SIGMA",i,sqrt(0.5/(acoef[3*i+1])));
383 cpl_table_set_double(line_table,
"SIGMA_ERR",i,0.5*CPL_MATH_SQRT1_2*(acoef_er[3*i+1])*pow(acoef[3*i+1],-3.*0.5));
387 double ind_ew_err_square = ind_ew*ind_ew * ( acoef_er[3*i]*acoef_er[3*i]/acoef[3*i]/acoef[3*i] + (0.5*0.5*acoef_er[3*i+1]*acoef_er[3*i+1]/acoef[3*i+1]/acoef[3*i+1]));
388 cpl_table_set_double(line_table,
"EW_ERR",i,sqrt(ind_ew_err_square)*10000.);
392 if (!cpl_errorstate_is_equal(prestate)) {
393 return (
int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
394 "Unable to Get region of the spectrum");
398 return CPL_ERROR_NONE;
405 double det_line_resol,
410 int nl = cpl_table_get_nrow(line_table);
419 for (i=0; i < nl; i++) {
420 if ( fabs( line - cpl_table_get_double(line_table,
"WAVEL",i,NULL) ) < det_line_resol ) {
421 ew+=cpl_table_get_double(line_table,
"EW",i,NULL);
422 ew_er+=cpl_table_get_double(line_table,
"EW_ERR",i,NULL);
435poly_fitn(
double xvec[],
double yvec[],
double err[],
long n,
long ord,
double coefs[]) {
437 double xi, yi, ei, chisq,xi2;
439 gsl_vector *
y, *w, *c;
441 X = gsl_matrix_alloc (
n, ord);
442 y = gsl_vector_alloc (
n);
443 w = gsl_vector_alloc (
n);
444 c = gsl_vector_alloc (ord);
445 cov = gsl_matrix_alloc (ord, ord);
446 for (i = 0; i <
n; i++) {
450 for (j = 0; j < ord; j++) {
452 for (k=0; k<j; k++) xi2*=xi;
453 gsl_matrix_set (X, i, j, xi2);
455 gsl_vector_set (
y, i, yi);
456 gsl_vector_set (w, i, 1.0/(ei*ei));
459 gsl_multifit_linear_workspace * work = gsl_multifit_linear_alloc (
n, ord);
460 gsl_multifit_wlinear (X, w,
y, c, cov, &chisq, work);
461 gsl_multifit_linear_free (work);
463 #define C(i) (gsl_vector_get(c,(i)))
464 #define COV(i,j) (gsl_matrix_get(cov,(i),(j)))
466 for (j = 0; j < ord; j++)
472 gsl_matrix_free (cov);
476void deriv(
double x[],
double y[],
double dy[],
long n) {
478 gsl_interp_accel *acc = gsl_interp_accel_alloc ();
479 gsl_interp *interp = gsl_interp_alloc (gsl_interp_cspline,
n);
482 gsl_interp_init (interp,
x,
y,
n);
484 dy[i]=gsl_interp_eval_deriv (interp,
x,
y,
x[i],acc);
485 gsl_interp_free (interp);
486 gsl_interp_accel_free (acc);
491 double acoef[],
double acoef_er[],
int para,
int *status2)
493 const gsl_multifit_fdfsolver_type *T;
494 gsl_multifit_fdfsolver *
s;
500 const size_t p = para;
502 gsl_matrix *covar = gsl_matrix_alloc (p, p);
503#if defined GSL_MAJOR_VERSION && GSL_MAJOR_VERSION >= 2
508 gsl_multifit_function_fdf f;
511 for (i=0; i< (size_t)
para; i++)
521 gsl_vector_view
x = gsl_vector_view_array (x_init, p);
523 T = gsl_multifit_fdfsolver_lmder;
525 s = gsl_multifit_fdfsolver_alloc (T,
n, p);
527 gsl_multifit_fdfsolver_set (
s, &f, &
x.vector);
531 status = gsl_multifit_fdfsolver_iterate (
s);
537 status = gsl_multifit_test_delta (
s->dx,
s->
x,
540 while (status == GSL_CONTINUE && iter < 5000);
541#if defined GSL_MAJOR_VERSION && GSL_MAJOR_VERSION >= 2
542 J = gsl_matrix_alloc(
n, p);
543 gsl_multifit_fdfsolver_jac(
s, J);
544 gsl_multifit_covar (J, 0.0, covar);
547 gsl_multifit_covar (
s->J, 0.0, covar);
550#define FIT(i) gsl_vector_get(s->x, i)
551#define ERR(i) sqrt(gsl_matrix_get(covar,i,i))
555 double chi = gsl_blas_dnrm2(
s->f);
557 double c = GSL_MAX_DBL(1, chi / sqrt(dof));
559 for (i=0; i < (size_t)
para; i++)
562 acoef_er[i]=c*
ERR(i);
568 gsl_multifit_fdfsolver_free (
s);
569 gsl_matrix_free (covar);
592 cpl_errorstate prestate = cpl_errorstate_get();
600 *tab = cpl_table_new(
size);
601 cpl_table_new_column(*tab,
"WAVEL", CPL_TYPE_DOUBLE);
602 cpl_table_new_column(*tab,
"WAVEL_ERR", CPL_TYPE_DOUBLE);
603 cpl_table_new_column(*tab,
"PEAK", CPL_TYPE_DOUBLE);
604 cpl_table_new_column(*tab,
"PEAK_ERR", CPL_TYPE_DOUBLE);
605 cpl_table_new_column(*tab,
"MU", CPL_TYPE_DOUBLE);
606 cpl_table_new_column(*tab,
"MU_ERR", CPL_TYPE_DOUBLE);
607 cpl_table_new_column(*tab,
"SIGMA", CPL_TYPE_DOUBLE);
608 cpl_table_new_column(*tab,
"SIGMA_ERR", CPL_TYPE_DOUBLE);
609 cpl_table_new_column(*tab,
"EW", CPL_TYPE_DOUBLE);
610 cpl_table_new_column(*tab,
"EW_ERR", CPL_TYPE_DOUBLE);
611 cpl_table_new_column(*tab,
"FWHM", CPL_TYPE_DOUBLE);
612 cpl_table_new_column(*tab,
"FWHM_ERR", CPL_TYPE_DOUBLE);
614 if (!cpl_errorstate_is_equal(prestate)) {
615 return (
int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
616 "Unable to create table.");
629 cpl_table_fill_column_window_double(*tab,
"WAVEL", 0, ceil, -9999.0);
630 cpl_table_fill_column_window_double(*tab,
"WAVEL_ERR", 0, ceil, -9999.0);
631 cpl_table_fill_column_window_double(*tab,
"PEAK", 0, ceil, -9999.0);
632 cpl_table_fill_column_window_double(*tab,
"PEAK_ERR", 0, ceil, -9999.0);
633 cpl_table_fill_column_window_double(*tab,
"MU", 0, ceil, -9999.0);
634 cpl_table_fill_column_window_double(*tab,
"MU_ERR", 0, ceil, -9999.0);
635 cpl_table_fill_column_window_double(*tab,
"SIGMA", 0, ceil, -9999.0);
636 cpl_table_fill_column_window_double(*tab,
"SIGMA_ERR", 0, ceil, -9999.0);
637 cpl_table_fill_column_window_double(*tab,
"EW", 0, ceil, -9999.0);
638 cpl_table_fill_column_window_double(*tab,
"EW_ERR", 0, ceil, -9999.0);
639 cpl_table_fill_column_window_double(*tab,
"FWHM", 0, ceil, -9999.0);
640 cpl_table_fill_column_window_double(*tab,
"FWHM_ERR", 0, ceil, -9999.0);
642 if (!cpl_errorstate_is_equal(prestate)) {
643 return (
int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
644 "Unable to initialize table.");
651 return CPL_ERROR_NONE;
675 cpl_errorstate prestate = cpl_errorstate_get();
677 int n = cpl_table_get_nrow(spec_region);
682 double coefs[
order+1];
683 double x[
n],
y[
n], err[
n], ynorm[
n];
688 for(i=0; i <
n; i++){
689 x[i] = cpl_table_get_double(spec_region,
"WAVEL",i,NULL);
690 y[i] = cpl_table_get_double(spec_region,
"FLUX",i,NULL);
702 for(i=0; i <
n; i++) {
705 for (j=0; j <
order + 1; j++) {
706 ynorm[i]+=coefs[j]*xi;
711 double vecx[
n],vecy[
n];
713 for (jk=0; jk < cont_iter; jk++) {
716 for (i=0; i<
n-1; i++) {
720 if (
y[i] > ynorm[i]*cont_rejt && fabs(
y[i]-
y[i+1]) < 0.1*
y[i]){
728 for(i=0; i <
n; i++) {
731 for (j=0;j<
order+1;j++) {
732 ynorm[i]+=coefs[j]*xi;
739 for (i=0; i <
n; i++)
740 ynorm[i]=
y[i]/(coefs[0]+coefs[1]*
x[i]+coefs[2]*
x[i]*
x[i]);
744 for(i=0; i <
n; i++){
745 cpl_table_set_double(spec_region,
"FLUX",i,ynorm[i]);
748 if (!cpl_errorstate_is_equal(prestate)) {
749 return (
int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
750 "Unable to Get region of the spectrum");
754 return CPL_ERROR_NONE;
776 double det_line_thres,
777 double det_line_resol,
778 int det_line_smwidth,
779 cpl_table** line_table
782 cpl_errorstate prestate = cpl_errorstate_get();
785 cpl_table* spec_cont_region_der1 = NULL;
786 cpl_table* spec_cont_region_der2 = NULL;
787 cpl_table* spec_cont_region_der3 = NULL;
801 int i,
n = cpl_table_get_nrow(spec_cont_region);
802 double x[
n], iy[
n],
y[
n], dy[
n], ddy[
n];
803 for(i=0; i <
n; i++){
804 x[i] = cpl_table_get_double(spec_cont_region,
"WAVEL",i,NULL);
805 iy[i] = cpl_table_get_double(spec_cont_region,
"FLUX",i,NULL);
806 y[i] = cpl_table_get_double(spec_cont_region_der1,
"FLUX",i,NULL);
807 dy[i] = cpl_table_get_double(spec_cont_region_der2,
"FLUX",i,NULL);
808 ddy[i] = cpl_table_get_double(spec_cont_region_der3,
"FLUX",i,NULL);
811 cpl_table_delete(spec_cont_region_der1);
812 cpl_table_delete(spec_cont_region_der2);
813 cpl_table_delete(spec_cont_region_der3);
815 long ncenter=
n, center[
n];
824 if (center[0] != -1 && ncenter != 0) {
825 double xlinhas[ncenter], ylinhas[ncenter];
829 for (i=0; i<ncenter; i++) {
832 den=1./(
x[i1]-
x[i1-1]);
833 diff_y=(ddy[i1] - ddy[i1m]);
834 xlinhas[i]= ( -ddy[i1m] + diff_y*den *
x[i1] ) / ( diff_y*den );
835 ylinhas[i]= diff_y*den * xlinhas[i] + iy[i1m] - ( iy[i1]- iy[i1m] )*den *
x[i1] ;
840 double xvec2[ncenter], yvec2[ncenter];
845 for(i=1;i<ncenter;i++) {
846 if (fabs(xvec2[j]-xlinhas[i]) < det_line_resol ) {
847 xvec2[j]=(xvec2[j]+xlinhas[i])*0.5;
848 yvec2[j]=(yvec2[j]+ylinhas[i])*0.5;
863 == CPL_ERROR_NONE, cpl_error_get_code());
865 for (i=0; i<nvec2; i++) {
866 cpl_table_set_double(*line_table,
"WAVEL",i,xvec2[i]);
867 cpl_table_set_double(*line_table,
"PEAK",i,yvec2[i]);
874 == CPL_ERROR_NONE, cpl_error_get_code());
879 if (!cpl_errorstate_is_equal(prestate)) {
880 return (
int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
881 "Unable to Get region of the spectrum");
885 return CPL_ERROR_NONE;
cpl_error_code esp_det_line(cpl_table *spec_cont_region, double det_line_thres, double det_line_resol, int det_line_smwidth, cpl_table **line_table)
Performs a local normalization of the spectrum region.
double maxele_vec(double vec[], long nvec)
cpl_error_code esp_fit_ngauss(cpl_table *spec_cont_region, cpl_table *line_table, double fit_ngauss_width)
Fit a list of absorption lines with n Gaussian profiles and compute the equivalent width of each line...
void smooth(double vec[], long n, int w, double svec[])
void find_left_right_continuum_pos(int *x1, int *x2, cpl_table *spec_region, double cont_rejt, double line)
static void esp_spec_smooth(cpl_table *spec_region, int smwidth)
void fitngauss(double t[], double y[], double sigma[], long nvec, double acoef[], double acoef_er[], int para, int *status2)
double check_ew(cpl_table *line_table, double line, double det_line_resol, int *index_line, int *n_lines, double *ew_error)
static void zeroscenterfind(double iy[], double y[], double dy[], double ddy[], long n, long center[], long *ncenter, double det_line_thres)
cpl_error_code espda_create_line_table(cpl_table **tab, cpl_size size)
Create a LINE table with a given row size.
static cpl_size get_pixel_to_nm_scale(cpl_table *spec_total, double nm)
get scale from nm to pixels
static void poly_fitn(double xvec[], double yvec[], double err[], long n, long ord, double coefs[])
static cpl_size get_index_from_spec(cpl_table *spec_total, double lambda)
cpl_error_code esp_fit_lcont(cpl_table *spec_region, double cont_rejt, int cont_iter)
Performs a local normalization of the spectrum region.
void deriv(double x[], double y[], double dy[], long n)
static cpl_table * esp_spec_deriv(cpl_table *spec_region)
cpl_error_code select_local_spec(cpl_table *spec_total, double ew_space, double lambda, cpl_table **spec_region)
Select_local_spec.
int expb_fdf(const gsl_vector *x, void *data, gsl_vector *f, gsl_matrix *J)
int expb_f(const gsl_vector *x, void *data, gsl_vector *f)
int expb_df(const gsl_vector *x, void *data, gsl_matrix *J)