52#include <gsl/gsl_multifit.h>
79 float sol_lambda_min=0, sol_lambda_max=0;
80 int sol_absorder_min=0, sol_absorder_max=0;
95 res->
polx = cpl_polynomial_new(3);
96 res->
poly = cpl_polynomial_new(3);
97 res->
dim = cpl_vector_new(3);
98 res->
header = cpl_propertylist_new();
112 for( i=1; i< spec_list->
size; i++){
114 float lambda_min, lambda_max;
118 if ( absorder > sol_absorder_max){
119 sol_absorder_max = absorder;
121 if ( absorder < sol_absorder_min){
122 sol_absorder_min = absorder;
124 if ( lambda_min < sol_lambda_min){
125 sol_lambda_min = lambda_min;
127 if ( lambda_max > sol_lambda_max){
128 sol_lambda_max = lambda_max;
171 res->
polx = cpl_polynomial_duplicate( org->
polx ) ;
172 res->
poly = cpl_polynomial_duplicate( org->
poly ) ;
173 res->
dim = cpl_vector_duplicate( org->
dim ) ;
174 res->
header = cpl_propertylist_duplicate( org->
header ) ;
196 double vto = 0.0, vfrom = 0.0;
202 check(vfrom = cpl_polynomial_get_coeff(from->
poly, pows));
203 check(vto = cpl_polynomial_get_coeff(to->
poly, pows));
205 check( cpl_polynomial_set_coeff( to->
poly, pows, vto));
242 cpl_polynomial* res = NULL;
299 cpl_polynomial* res = NULL;
317 cpl_propertylist * res = NULL;
339 double tcheb_slit = 0.0, tcheb_order, tcheb_lambda;
340 double pos = 0.0, res = 0.0;
343 cpl_vector *tcheb_coef_lambda = NULL;
344 cpl_vector *tcheb_coef_order = NULL;
345 cpl_vector *tcheb_coef_slit = NULL;
358 if ( tcheb_lambda < -1. ) tcheb_lambda = -1. ;
359 if ( tcheb_lambda > 1. ) tcheb_lambda = 1. ;
370 for(k = 0; k < sol->
deg_slit +1 ; k++){
376 check( vlambda = cpl_vector_get( tcheb_coef_lambda, i));
377 check( vorder = cpl_vector_get( tcheb_coef_order, j));
378 check( vslit = cpl_vector_get( tcheb_coef_slit, k));
382 check( coef = cpl_polynomial_get_coeff(sol->
polx, pows));
383 res += coef*vslit*vorder*vlambda;
415 double tcheb_slit = 0.0, tcheb_order, tcheb_lambda;
416 double pos = 0.0, res = 0.0;
419 cpl_vector *tcheb_coef_lambda = NULL;
420 cpl_vector *tcheb_coef_order = NULL;
421 cpl_vector *tcheb_coef_slit = NULL;
435 if ( tcheb_lambda < -1. ) tcheb_lambda = -1. ;
436 if ( tcheb_lambda > 1. ) tcheb_lambda = 1. ;
447 for(k = 0; k < sol->
deg_slit +1 ; k++){
453 check( vlambda = cpl_vector_get( tcheb_coef_lambda, i));
454 check( vorder = cpl_vector_get( tcheb_coef_order, j));
455 check( vslit = cpl_vector_get( tcheb_coef_slit, k));
459 check( coef = cpl_polynomial_get_coeff(sol->
poly, pows));
460 res += coef*vslit*vorder*vlambda;
496 double* pos,
double *posmin,
double *posmax,
double* lambda,
497 double*
order,
double* slit, cpl_polynomial* result)
501 gsl_matrix *X = NULL, *cov = NULL;
502 gsl_vector *
y = NULL, *c = NULL;
503 gsl_multifit_linear_workspace *work = NULL;
505 double *tcheb_pos = NULL, *tcheb_lambda = NULL;
506 double *tcheb_order = NULL, *tcheb_slit = NULL;
539 y = gsl_vector_alloc (
size);
540 c = gsl_vector_alloc (sol->
nbcoefs);
543 for (i = 0; i <
size; i++) {
546 for(l = 0; l < sol->
deg_slit +1 ; l++){
547 double vslit = cos(l*acos(tcheb_slit[i]));
548 double vorder = cos(k*acos(tcheb_order[i]));
549 double vlambda = cos(j*acos(tcheb_lambda[i]));
552 (sol->
deg_slit+1), vslit*vorder*vlambda);
556 gsl_vector_set (
y, i, tcheb_pos[i]);
559 work = gsl_multifit_linear_alloc(
size,sol->
nbcoefs);
560 gsl_multifit_linear(X,
y, c, cov, &chisq, work);
564 for(l = 0; l < sol->
deg_slit +1 ; l++){
568 cpl_polynomial_set_coeff(result, pows, gsl_vector_get(c,
573 gsl_multifit_linear_free (work);
577 gsl_matrix_free (cov);
602 double* new_pos,
double* lambda,
603 double*
order,
double* slit,
604 cpl_polynomial* result,
char axis)
608 gsl_matrix *X = NULL, *cov = NULL;
609 gsl_vector *
y = NULL, *c = NULL;
610 gsl_multifit_linear_workspace *work = NULL;
612 double *tcheb_pos = NULL, *tcheb_lambda = NULL;
613 double *tcheb_order = NULL, *tcheb_slit = NULL;
614 double * tcheb_new = NULL ;
615 double posmin, posmax ;
633 posmin = adj->
min_y ;
634 posmax = adj->
max_y ;
637 posmin = adj->
min_x ;
638 posmax = adj->
max_x ;
666 double temp0, temp1, a, b ;
668 a = 2/(posmax-posmin);
669 b = 1-2*posmax/(posmax-posmin);
671 for( indx = 0 ; indx <
size ; indx++ ) {
680 temp1 = (temp0*a) + b ;
681 tcheb_pos[indx] = tcheb_new[indx] - temp1 ;
686 y = gsl_vector_alloc (
size);
687 c = gsl_vector_alloc (sol->
nbcoefs);
690 for (i = 0; i <
size; i++) {
692 for(k = 0; k < sol->
deg_order +1 ; k++) {
693 for(l = 0; l < sol->
deg_slit +1 ; l++) {
694 double vslit = cos(l*acos(tcheb_slit[i]));
695 double vorder = cos(k*acos(tcheb_order[i]));
696 double vlambda = cos(j*acos(tcheb_lambda[i]));
699 (sol->
deg_slit+1), vslit*vorder*vlambda);
703 gsl_vector_set (
y, i, tcheb_pos[i]);
707 "Not enough Points vs Number of Coeffs" ) ;
708 work = gsl_multifit_linear_alloc(
size, sol->
nbcoefs);
709 gsl_multifit_linear(X,
y, c, cov, &chisq, work);
713 for(l = 0; l < sol->
deg_slit +1 ; l++){
717 cpl_polynomial_set_coeff(result, pows, gsl_vector_get(c,
722 gsl_multifit_linear_free (work);
726 gsl_matrix_free (cov);
751 cpl_table* table = NULL;
752 cpl_frame * result = NULL ;
797 double vx = 0.0, vy = 0.0;
801 sprintf(coefname,
"C%d%d%d",i,j,k);
802 check(cpl_table_new_column(table,coefname, CPL_TYPE_DOUBLE));
803 check(vx = cpl_polynomial_get_coeff(w->
polx, pows));
804 check(vy = cpl_polynomial_get_coeff(w->
poly, pows));
805 check(cpl_table_set_double( table, coefname, 0, vx));
806 check(cpl_table_set_double( table, coefname, 1, vy));
823 check(cpl_table_save(table, w->
header, NULL, filename, CPL_IO_DEFAULT));
824 check(cpl_table_save(trace, NULL, NULL, filename, CPL_IO_EXTEND));
829 CPL_FRAME_TYPE_TABLE,
830 CPL_FRAME_GROUP_PRODUCT,
831 CPL_FRAME_LEVEL_TEMPORARY));
852 cpl_table* table = NULL;
853 const char* tablename = NULL;
860 check(tablename = cpl_frame_get_filename(frame));
866 check(result->
header = cpl_propertylist_load(tablename,0));
868 check( rows = cpl_table_get_nrow( table ) ) ;
869 check( cols = cpl_table_get_ncol( table ) ) ;
903 CPL_TYPE_INT, 0, &result->
deg_slit ) ) ;
905 CPL_TYPE_INT, 0, &result->
deg_order ) ) ;
913 result->
polx = cpl_polynomial_new(3);
914 result->
poly = cpl_polynomial_new(3);
915 result->
dim = cpl_vector_new(3);
918 for( i = 0 ; i<=result->
deg_slit ; i++ ) {
919 for( j = 0 ; j<=result->
deg_order ; j++ ) {
928 sprintf( coefname,
"C%d%d%d", i, j, k ) ;
933 check( cpl_polynomial_set_coeff( result->
polx, pows, coef ) ) ;
937 check( cpl_polynomial_set_coeff( result->
poly, pows, coef ) ) ;
948 if (cpl_error_get_code () != CPL_ERROR_NONE) {
963 if ( fname != NULL ) fout = fopen( fname,
"w" ) ;
966 for( i = 0 ; i <= wsol->
deg_slit ; i++ )
968 for( k = 0 ; k <= wsol->
deg_order ; k++ ) {
973 check(coeff = cpl_polynomial_get_coeff( wsol->
poly, pows));
975 xsh_msg(
" %d%d%d; %lf", i, j, k, coeff ) ;
977 fprintf( fout,
"%d%d%d: %lf\n", i, j, k, coeff ) ;
979 if ( nb != 0 && l >= nb )
goto cleanup ;
982 if ( fout != NULL ) fclose( fout ) ;
989 cpl_table* table = NULL ;
1005 table=cpl_table_new(
size);
1006 cpl_table_new_column(table,
"WAVELENGTH",CPL_TYPE_DOUBLE);
1007 cpl_table_new_column(table,
"ORDER",CPL_TYPE_DOUBLE);
1008 cpl_table_new_column(table,
"X",CPL_TYPE_DOUBLE);
1009 cpl_table_new_column(table,
"Y",CPL_TYPE_DOUBLE);
1010 cpl_table_new_column(table,
"S",CPL_TYPE_DOUBLE);
1012 cpl_table_fill_column_window(table,
"WAVELENGTH",0,
size,0);
1013 cpl_table_fill_column_window(table,
"ORDER",0,
size,0);
1014 cpl_table_fill_column_window(table,
"X",0,
size,0);
1015 cpl_table_fill_column_window(table,
"Y",0,
size,0);
1016 cpl_table_fill_column_window(table,
"S",0,
size,0);
1018 po=cpl_table_get_data_double(table,
"ORDER");
1019 pw=cpl_table_get_data_double(table,
"WAVELENGTH");
1020 px=cpl_table_get_data_double(table,
"X");
1021 py=cpl_table_get_data_double(table,
"Y");
1022 ps=cpl_table_get_data_double(table,
"S");
1024 for(i = 0 ; i<
size; i++) {
static xsh_instrument * instrument
void xsh_wavesol_apply_shift(xsh_wavesol *wsol, float shift_x, float shift_y)
Apply a shift on X and Y to wave solution.
void xsh_wavesol_set_bin_y(xsh_wavesol *wsol, int bin)
Set the bin of wave table in y.
void xsh_wavesol_set_bin_x(xsh_wavesol *wsol, int bin)
Set the bin of wave table in x.
cpl_table * xsh_wavesol_trace(xsh_wavesol *wsol, double *lambda, double *order, double *slit, int size)
void xsh_wavesol_compute(xsh_wavesol *sol, int size, double *pos, double *posmin, double *posmax, double *lambda, double *order, double *slit, cpl_polynomial *result)
compute a wavelength solution
cpl_polynomial * xsh_wavesol_get_polx(xsh_wavesol *sol)
get the solution in X
void xsh_wavesol_dump(xsh_wavesol *wsol, const char *fname, int nb)
xsh_wavesol * xsh_wavesol_load(cpl_frame *frame, xsh_instrument *instrument)
load a wavelength solution
double xsh_wavesol_eval_poly(xsh_wavesol *sol, double lambda, double order, double slit)
eval the polynomial solution in Y
void xsh_wavesol_residual(xsh_wavesol *sol, xsh_wavesol *adj, int size, double *new_pos, double *lambda, double *order, double *slit, cpl_polynomial *result, char axis)
xsh_wavesol * xsh_wavesol_create(cpl_frame *spectral_format_frame, xsh_detect_arclines_param *params, xsh_instrument *instrument)
Create a new wavelength solution structure.
cpl_polynomial * xsh_wavesol_get_poly(xsh_wavesol *sol)
get the solution in Y
void xsh_wavesol_free(xsh_wavesol **w)
free wavelength solution structure
double xsh_wavesol_eval_polx(xsh_wavesol *sol, double lambda, double order, double slit)
eval the polynomial solution in X
enum wavesol_type xsh_wavesol_get_type(xsh_wavesol *wsol)
get the type of the wave table
void xsh_wavesol_set_type(xsh_wavesol *wsol, enum wavesol_type type)
set the type of the wave table
cpl_propertylist * xsh_wavesol_get_header(xsh_wavesol *sol)
get header of the table
xsh_wavesol * xsh_wavesol_duplicate(xsh_wavesol *org)
duplicate a wavelength solution structure
void xsh_wavesol_add_poly(xsh_wavesol *to, xsh_wavesol *from)
cpl_frame * xsh_wavesol_save(xsh_wavesol *w, cpl_table *trace, const char *filename, const char *tag)
save a wavelength solution
#define XSH_ASSURE_NOT_ILLEGAL(cond)
#define XSH_ASSURE_NOT_ILLEGAL_MSG(cond, msg)
#define xsh_error_msg(...)
#define XSH_ASSURE_NOT_NULL(pointer)
int xsh_instrument_get_binx(xsh_instrument *instrument)
int xsh_instrument_get_biny(xsh_instrument *instrument)
#define xsh_msg(...)
Print a message on info level.
#define xsh_msg_dbg_high(...)
double xsh_pfits_get_wavesol_lambda_min(cpl_propertylist *plist)
find out the min lambda
double xsh_pfits_get_wavesol_lambda_max(cpl_propertylist *plist)
find out the wavesol max lambda
void xsh_pfits_set_pcatg(cpl_propertylist *plist, const char *value)
Write the PCATG value.
void xsh_pfits_set_wavesol_x_min(cpl_propertylist *plist, double value)
WRITE the min x.
double xsh_pfits_get_wavesol_order_min(cpl_propertylist *plist)
find out the min order
double xsh_pfits_get_wavesol_y_max(cpl_propertylist *plist)
find out the wavesol max y position
double xsh_pfits_get_wavesol_slit_min(cpl_propertylist *plist)
find out the min slit
void xsh_pfits_set_wavesol_y_min(cpl_propertylist *plist, double value)
WRITE the min y.
double xsh_pfits_get_wavesol_x_max(cpl_propertylist *plist)
find out the wavesol max x position
void xsh_pfits_set_wavesol_y_max(cpl_propertylist *plist, double value)
WRITE the max y position.
double xsh_pfits_get_wavesol_y_min(cpl_propertylist *plist)
find out the min y position
void xsh_pfits_set_wavesol_slit_min(cpl_propertylist *plist, double value)
WRITE the min slit.
void xsh_pfits_set_wavesol_lambda_max(cpl_propertylist *plist, double value)
WRITE the max lambda.
void xsh_pfits_set_wavesol_slit_max(cpl_propertylist *plist, double value)
WRITE the max slit.
void xsh_pfits_set_wavesol_order_max(cpl_propertylist *plist, double value)
WRITE the max order.
double xsh_pfits_get_wavesol_x_min(cpl_propertylist *plist)
find out the min x position
double xsh_pfits_get_wavesol_slit_max(cpl_propertylist *plist)
find out the wavesol max slit
void xsh_pfits_set_wavesol_lambda_min(cpl_propertylist *plist, double value)
WRITE the min lambda.
void xsh_pfits_set_wavesol_x_max(cpl_propertylist *plist, double value)
WRITE the max x position.
double xsh_pfits_get_wavesol_order_max(cpl_propertylist *plist)
find out the wavesol max order
void xsh_pfits_set_wavesol_order_min(cpl_propertylist *plist, double value)
WRITE the min order.
void xsh_free_polynomial(cpl_polynomial **p)
Deallocate a polynomial and set the pointer to NULL.
void xsh_free_vector(cpl_vector **v)
Deallocate a vector and set the pointer to NULL.
void xsh_tools_min_max(int size, double *tab, double *min, double *max)
computes min & max in ab array
double convert_data_to_bin(double data, int binning)
double xsh_tools_tchebitchev_transform(double pos, double min, double max)
computes Tchebitchev transformation
cpl_vector * xsh_tools_tchebitchev_poly_eval(int n, double X)
Compute tchebitchev Tn(X) first coefficient for tchebitchev polynomial.
double xsh_tools_tchebitchev_reverse_transform(double pos, double min, double max)
computes reverse Tchebitchev transformation
void xsh_free_propertylist(cpl_propertylist **p)
Deallocate a property list and set the pointer to NULL.
cpl_error_code xsh_get_table_value(const cpl_table *table, const char *colname, cpl_type coltype, int i, void *result)
Read a table value from a fits table.
void xsh_tools_tchebitchev_transform_tab(int size, double *pos, double min, double max, double *tcheb_pos)
computes Tchebitchev transformation
cpl_propertylist * header
#define XSH_WAVESOL_TABLE_COLNAME_DEGSLIT
#define XSH_WAVESOL_TABLE_COLNAME_DEGLAMBDA
#define XSH_WAVESOL_TABLE_NB_COL
#define XSH_WAVESOL_TABLE_COLNAME_AXIS
#define XSH_WAVESOL_TABLE_NB_ROWS
#define XSH_WAVESOL_TABLE_COLNAME_DEGORDER
cpl_frame * xsh_frame_product(const char *fname, const char *tag, cpl_frame_type type, cpl_frame_group group, cpl_frame_level level)
Creates a frame with given characteristics.
#define XSH_FREE(POINTER)
#define XSH_MALLOC(POINTER, TYPE, SIZE)
#define XSH_CALLOC(POINTER, TYPE, SIZE)
#define XSH_TABLE_LOAD(TABLE, NAME)
#define XSH_TABLE_FREE(TABLE)