87 float *
data,
float *p_errs,
110#define BAD_POSITION_FLAG 999999
111#define THRESH_POSITION_FLAG 9999999
117 int x,
int y,
int nx,
118 float *
data,
float *p_errs,
123 cpl_vector *v_pos = NULL ;
124 cpl_vector *v_values = NULL ;
125 cpl_error_code err = CPL_ERROR_NONE ;
128 double flux=0.0, min_flux=0.0;
133 double *warray = NULL ;
134 int pix_shift=(
y-1)*
nx-1;
150 x0 =
x - search_window;
151 x2 =
x + search_window;
152 if ( x0 < 1 ) x0 = 1;
153 if ( x2 >
nx ) x2 =
nx;
160 if ( running_window != 0 ) {
162 for( l = 0 ; l<nelem ; l++, x0++ )
163 warray[l] =
data[x0+pix_shift];
173 nelem = (fit_window*2)+1 ;
179 check( v_pos = cpl_vector_new( nelem ) ) ;
180 check( v_values = cpl_vector_new( nelem ) ) ;
183 for( l = 0 ; l<nelem ; l++, x0++ ) {
184 cpl_vector_set( v_pos, l, (
double)x0 ) ;
185 cpl_vector_set( v_values, l, (
double)
data[x0+pix_shift] ) ;
188 err = cpl_vector_fit_gaussian( v_pos, NULL, v_values, NULL,
192 &result->
mse, NULL, NULL ) ;
193 if ( err == CPL_ERROR_NONE ) {
195 flux = (double)
data[x0+pix_shift] ;
197 min_flux = (double)p_errs[x0+pix_shift] *
threshold ;
198 if ( flux < min_flux ) {
199 err = CPL_ERROR_UNSPECIFIED ;
203 if ( err != CPL_ERROR_NONE ) {
206 if ( err == CPL_ERROR_UNSPECIFIED ) {
208 x,
y, flux, min_flux ) ;
216 for( i = 0 ; i<nelem ; i++ ) {
218 cpl_vector_get( v_pos, i ),
219 cpl_vector_get( v_values, i ) ) ;
226 char dirname1[128], dirname2[128], fname[256], cmd[256] ;
230 if ( access( dirname1, 0 ) != 0 ) {
231 sprintf( cmd,
"mkdir %s", dirname1 ) ;
234 sprintf( dirname2,
"%s/O_%02d", dirname1,
order ) ;
235 if ( access( dirname2, 0 ) != 0 ) {
236 sprintf( cmd,
"mkdir %s", dirname2 ) ;
240 sprintf( fname,
"%s/fit_%04d", dirname2,
y ) ;
241 fout = fopen( fname,
"w" ) ;
242 for( l = 0 ; l<nelem ; l++ ) {
243 fprintf( fout,
"%lf %lf %lf %lf\n", cpl_vector_get( v_pos, l ),
244 cpl_vector_get( v_values, l ),
270 cpl_frame * resid_frame = NULL ;
272 char frame_name[256] ;
281 if ( (flog = fopen( logname,
"w" ) ) == NULL )
282 xsh_msg(
"Cant open log file \"%s\"", logname ) ;
283 else xsh_msg(
" ASCII File '%s'", logname ) ;
288 fprintf( flog,
"%d %lf %lf %lf %lf\n",
302 sprintf(frame_name,
"%s.fits",tag);
310 if(cpl_error_get_code() != CPL_ERROR_NONE) {
330 xsh_msg_dbg_low(
" Cumulate: Order %d, Nb of Points: %d", absorder, npts ) ;
350 Delta0 =
Deltas + prevSize ;
353 for( j = 0 ; j<npts ; j++, pcent++ ) {
372 cpl_vector *v_avg = NULL ;
373 double residavg, residmax, residmin, residrms ;
374 v_avg = cpl_vector_wrap( npts, Delta0 ) ;
376 residavg = cpl_vector_get_mean( v_avg ) ;
377 residmax = cpl_vector_get_max( v_avg ) ;
378 residmin = cpl_vector_get_min( v_avg ) ;
379 residrms = cpl_vector_get_stdev( v_avg ) ;
382 residavg, residmax, residmin, residrms ) ;
385 cpl_vector_unwrap( v_avg ) ;
396 cpl_vector *v_avg = NULL ;
397 cpl_frame* resid_frame=NULL;
400 assure( v_avg != NULL, cpl_error_get_code(),
401 "Cant wrap the v_avg vector" ) ;
403 qcparam->
residavg = cpl_vector_get_mean( v_avg ) ;
404 qcparam->
residmax = cpl_vector_get_max( v_avg ) ;
405 qcparam->
residmin = cpl_vector_get_min( v_avg ) ;
406 qcparam->
residrms = cpl_vector_get_stdev( v_avg ) ;
410 cpl_vector_unwrap( v_avg ) ;
416 if(cpl_error_get_code() != CPL_ERROR_NONE) {
423static int comp_pos(
const void * un,
const void * deux )
436 cpl_propertylist * header=NULL ;
508 cpl_frame *spectral_frame,
512 cpl_frame** resid_frame)
515 cpl_frame *result = NULL;
521 cpl_vector *centers = NULL ;
522 cpl_vector *xpos = NULL ;
526 float *p_errs = NULL;
531 static FILE *flog = NULL ;
533 double fit_threshold ;
544 detect_param->
fit_window > 0, CPL_ERROR_NULL_INPUT,
545 "Windows must be > 0" ) ;
554 dcn_clipping->
niter, dcn_clipping->
frac);
562 CPL_ERROR_ILLEGAL_INPUT,
563 "Search windows half size %d must be > 0 and < %d change value of "
564 "parameter detectcontinuum-search-win-hsize",
579 check( p_errs = cpl_image_get_data_float( pre->
errs));
591 for(i=0; i< list->
size; i++){
594 int npts = 0, totpts = 0, npos, nn,
mm,
niter, totnbad = 0 ;
609 (
double)ycenter,NULL));
616 absorder,
x, ycenter ) ;
619 if (
x >= 1 && x <= pre->
nx) {
629 if ( err == CPL_ERROR_NONE ) {
631 (Centroids+npts)->position = (
double) ycenter ;
632 (Centroids+npts)->pos_x = (
double)
x;
633 (Centroids+npts)->centervalue = fit_result.
centroid ;
634 (Centroids+npts)->sigmavalue = fit_result.
sigma ;
635 (Centroids+npts)->absorder = absorder ;
651 if (
x >= 1 && x <= pre->
nx) {
659 fit_threshold ),
"Try to increase detectcontinuum-fit-win-hsize") ;
660 if ( err == CPL_ERROR_NONE ) {
662 (Centroids+npts)->position = (
double)
y ;
663 (Centroids+npts)->pos_x = (
double)
x;
664 (Centroids+npts)->centervalue = fit_result.
centroid ;
665 (Centroids+npts)->sigmavalue = fit_result.
sigma ;
666 (Centroids+npts)->absorder = absorder ;
686 if (
x >= 1 && x <= pre->
nx) {
695 if ( err == CPL_ERROR_NONE ) {
697 (Centroids+npts)->position = (
double)
y ;
698 (Centroids+npts)->pos_x = (
double)
x ;
699 (Centroids+npts)->centervalue = fit_result.
centroid ;
700 (Centroids+npts)->sigmavalue = fit_result.
sigma ;
701 (Centroids+npts)->absorder = absorder ;
713 FILE* debug_file = NULL;
714 char debug_name[256];
717 sprintf(debug_name,
"centroid_%d.reg", list->
list[i].
absorder);
719 debug_file = fopen( debug_name,
"w");
720 fprintf( debug_file,
"# Region file format: DS9 version 4.0\n"\
721 "global color=red font=\"helvetica 4 normal\""\
722 "select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 "\
724 for( idebug=0; idebug < npts; idebug++){
725 fprintf( debug_file,
"point(%f,%f) #point=cross color=blue\n",
726 Centroids[idebug].pos_x, Centroids[idebug].position);
727 fprintf( debug_file,
"point(%f,%f) #point=cross color=red\n",
728 Centroids[idebug].centervalue, Centroids[idebug].position);
741 assure(npts > 3,CPL_ERROR_ILLEGAL_OUTPUT,
742 "can't fit polynomial solution with nb of points %d", npts );
754 xsh_msg(
"Sigma Clipping on residuals over %d pts", npts ) ;
766 check( xpos = cpl_vector_new( npos ) ) ;
767 check( centers = cpl_vector_new( npos ) ) ;
770 for( j = 0 ; j<npos ; j++ ) {
771 cpl_vector_set( xpos, j, (Centroids+j)->position ) ;
772 cpl_vector_set( centers, j, (Centroids+j)->centervalue ) ;
790 poly_rms = sqrt( poly_rms ) ;
794 for( nn = 0 ; nn < npos ; nn++ ) {
798 double xpoly, delta ;
800 xpoly = cpl_polynomial_eval_1d( list->
list[i].
cenpoly,
801 (Centroids+nn)->position,
803 delta = fabs( xpoly - (Centroids+nn)->centervalue) ;
804 if ( delta > dcn_clipping->
res_max ) {
808 (Centroids+nn)->centervalue,
809 (Centroids+nn)->position,
825 if ( ((
float)(npts-totnbad)/(
float)npts) < dcn_clipping->
frac ) {
829 xsh_msg_warning(
"**** Too many rejected points: %d/%d (%.2f) Discard Order %d",
830 totnbad, npts, (
float)(npts-totnbad)/(
float)npts, absorder ) ;
831 xsh_msg_warning(
"Try to increase detectcontinuum-clip-res-max and/or decrease detectcontinuum-clip-frac and/or detectcontinuum-search-win-hsize");
836 for( nn = 0,
mm = 0 ; nn<npos ; nn++ ) {
838 if (
mm != nn ) *(Centroids+
mm) = *(Centroids+nn) ;
857 check( xpos = cpl_vector_new( npos ) ) ;
858 check( centers = cpl_vector_new( npos ) ) ;
861 for( j = 0 ; j<npos ; j++ ) {
862 cpl_vector_set( xpos, j, (Centroids+j)->position ) ;
863 cpl_vector_set( centers, j, (Centroids+j)->centervalue ) ;
876 double coeff0, coeff1, coeff2 ;
877 cpl_size icoeff = 0 ;
879 coeff0 = cpl_polynomial_get_coeff( list->
list[i].
cenpoly, &icoeff ) ;
881 coeff1 = cpl_polynomial_get_coeff( list->
list[i].
cenpoly, &icoeff ) ;
883 coeff2 = cpl_polynomial_get_coeff( list->
list[i].
cenpoly, &icoeff ) ;
884 xsh_msg_dbg_low(
" Calculated Poly: %lf %lf %lf", coeff0, coeff1, coeff2 ) ;
886 coeff0 = cpl_polynomial_get_coeff( guess_list->
list[i].
cenpoly, &icoeff ) ;
888 coeff1 = cpl_polynomial_get_coeff( guess_list->
list[i].
cenpoly, &icoeff ) ;
890 coeff2 = cpl_polynomial_get_coeff( guess_list->
list[i].
cenpoly, &icoeff ) ;
891 xsh_msg_dbg_low(
" Initial Poly: %lf %lf %lf", coeff0, coeff1, coeff2 ) ;
896 poly_rms = sqrt( poly_rms ) ;
899 for( nn = 0 ; nn < npos ; nn++ ) {
903 double xpoly, delta ;
905 xpoly = cpl_polynomial_eval_1d( list->
list[i].
cenpoly,
906 (Centroids+nn)->position,
908 delta = fabs( xpoly - (Centroids+nn)->centervalue) ;
909 if ( delta > poly_rms*dcn_clipping->
sigma ) {
913 (Centroids+nn)->centervalue,
914 (Centroids+nn)->position,
921 if ( nbad == 0 ) break ;
928 if ( ((
float)(npts-totnbad)/(
float)npts) < dcn_clipping->
frac ) {
932 xsh_msg(
"**** Too many rejected points: %d/%d (%.2f) Discard Order %d",
933 totnbad, npts, (
float)(npts-totnbad)/(
float)npts, absorder ) ;
938 for( nn = 0,
mm = 0 ; nn<npos ; nn++ ) {
940 if (
mm != nn ) *(Centroids+
mm) = *(Centroids+nn) ;
948 double coeff0, coeff1, coeff2 ;
949 cpl_size icoeff = 0 ;
952 coeff0 = cpl_polynomial_get_coeff( list->
list[i].
cenpoly, &icoeff ) ;
954 coeff1 = cpl_polynomial_get_coeff( list->
list[i].
cenpoly, &icoeff ) ;
956 coeff2 = cpl_polynomial_get_coeff( list->
list[i].
cenpoly, &icoeff ) ;
957 xsh_msg(
" Polynomial Coeffs: %lf %lf %lf",
958 coeff0, coeff1, coeff2 ) ;
966 xsh_msg(
" ++ Nb of Detected Orders: %d", ndetected ) ;
967 assure(ndetected > 0,CPL_ERROR_ILLEGAL_INPUT,
968 "parameter detectcontinuum-search-wind-hsize may have a too large value or detectcontinuum-ordertab-deg-y or detectcontinuum-clip-sigma or detectcontinuum-clip-res-max may have a too small value");
973 ord_qc_param.
ndet = ndetected ;
994 char frame_name[256];
997 sprintf(frame_name,
"%s%s",tag,
".fits");
1008 if ( flog ) fclose( flog ) ;
static xsh_instrument * instrument
cpl_frame * xsh_order_list_save(xsh_order_list *order_list, xsh_instrument *instrument, const char *filename, const char *tag, const int ny)
Save an order list to a frame.
xsh_order_list * xsh_order_list_load(cpl_frame *frame, xsh_instrument *instr)
load an order list from a frame
cpl_propertylist * xsh_order_list_get_header(xsh_order_list *list)
get header of the table
void xsh_order_list_free(xsh_order_list **list)
free memory associated to an order_list
void xsh_order_list_verify(xsh_order_list *list, int ny)
xsh_pre * xsh_pre_load(cpl_frame *frame, xsh_instrument *instr)
Load a xsh_pre structure from a frame.
int xsh_pre_get_ny(const xsh_pre *pre)
Get ny of pre structure.
void xsh_pre_free(xsh_pre **pre)
Free a xsh_pre structure.
xsh_resid_order_tab * xsh_resid_order_create(int size, int *orders, double *posx, double *posy, double *resx, double *polx)
Create a residual tab structure.
void xsh_resid_order_free(xsh_resid_order_tab **resid)
Free memory associated to a resid_tab.
cpl_frame * xsh_resid_order_save(xsh_resid_order_tab *resid, const char *filename, xsh_instrument *instrument, ORDERPOS_QC_PARAM *ord_qc_param, const char *tag)
Save a residual tab to a frame.
static cpl_frame * create_resid_tab(xsh_instrument *instrument, ORDERPOS_QC_PARAM *qcparam)
static cpl_frame * calculate_qc_parameters(ORDERPOS_QC_PARAM *qcparam, xsh_instrument *instrument)
static double * XorderPos
cpl_frame * xsh_detect_continuum(cpl_frame *frame, cpl_frame *order_table, cpl_frame *spectral_frame, xsh_detect_continuum_param *detect_param, xsh_clipping_param *dcn_clipping, xsh_instrument *instr, cpl_frame **resid_frame)
Detect order and compute polynomial description of ordermin and order max. Uses a guess order table i...
static cpl_error_code xsh_fit_gaussian(xsh_detect_continuum_param *detect_param, int x, int y, int nx, float *data, float *p_errs, struct gauss_res *result, xsh_instrument *instrument, int order, double threshold)
static int comp_pos(const void *un, const void *deux)
static void cumulate_qc_parameter(int order, xsh_order_list *list, CENTROIDS_STRUCT *pcent, int npts)
#define THRESH_POSITION_FLAG
static void set_qc_parameters(xsh_order_list *list, ORDERPOS_QC_PARAM *pqc, xsh_instrument *instrument)
#define BAD_POSITION_FLAG
#define assure(CONDITION, ERROR_CODE,...)
#define check_msg(COMMAND,...)
#define XSH_ASSURE_NOT_NULL(pointer)
const char * xsh_instrument_arm_tostring(xsh_instrument *i)
Get the string associated with an arm.
#define xsh_msg_warning(...)
Print an warning message.
#define xsh_msg_dbg_medium(...)
#define xsh_msg(...)
Print a message on info level.
#define xsh_msg_dbg_low(...)
#define xsh_msg_dbg_high(...)
void xsh_pfits_set_qc(cpl_propertylist *plist, void *value, const char *kw, xsh_instrument *instrument)
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.
int xsh_debug_level_get(void)
get debug level
void xsh_free_frame(cpl_frame **f)
Deallocate a frame and set the pointer to NULL.
int xsh_tools_running_median_1d_get_max(double *tab, int size, int wsize)
get max of a list of doubles after running median
void xsh_free_propertylist(cpl_propertylist **p)
Deallocate a property list and set the pointer to NULL.
cpl_propertylist * header
#define XSH_ORDERPOS_RESID_TAB
#define XSH_GET_TAG_FROM_ARM(TAG, instr)
#define XSH_ORDER_TAB_CENTR
#define QC_ORD_ORDERPOS_RESIDMAX
#define QC_ORD_ORDERPOS_RESIDAVG
#define QC_ORD_ORDERPOS_NPRED
#define QC_ORD_ORDERPOS_RESIDMIN
#define QC_ORD_ORDERPOS_RESIDRMS
#define QC_ORD_ORDERPOS_NDET
#define XSH_NEW_PROPERTYLIST(POINTER)
#define XSH_FREE(POINTER)
#define XSH_MALLOC(POINTER, TYPE, SIZE)
#define XSH_CALLOC(POINTER, TYPE, SIZE)
cpl_polynomial * xsh_polynomial_fit_1d_create(const cpl_vector *x_pos, const cpl_vector *values, int degree, double *mse)