X-shooter Pipeline Reference Manual 3.8.15
xsh_order_table_from_fmtchk.c
Go to the documentation of this file.
1/* *
2 * This file is part of the ESO X-shooter Pipeline *
3 * Copyright (C) 2006 European Southern Observatory *
4 * *
5 * This library is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA *
18 * */
19
20/*
21 * $Author: amodigli $
22 * $Date: 2009-09-27 10:40:48 $
23 * $Revision: 1.19 $
24*/
25
26#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29
37/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------
41 Includes
42 ----------------------------------------------------------------------------*/
43
44#include <math.h>
45#include <xsh_drl.h>
46#include <xsh_data_order.h>
48#include <xsh_error.h>
49#include <xsh_utils.h>
50#include <xsh_msg.h>
51#include <xsh_data_pre.h>
52#include <xsh_pfits.h>
53#include <xsh_parameters.h>
54
55#include <cpl.h>
56
57typedef struct {
58 int order ;
59 int pos_x ;
60 int pos_y ;
61 double flux ;
63
64typedef struct {
66 int start_x ;
68
69/*
70 In the spectral format table:
71 DIST_ORDER (In header keyword OR recipe parameter)
72 ABS_ORDER In the table
73 XDISP_CEN .... The X position of the center of the order
74
75 Starting from each possible measured order, calculate
76 the delta between theoretical (from spectral format table) and measured
77 orders.
78 Evaluate the validity (mean value of deltas)
79 Keep the best as the starting abs order.
80
81 The theoretical distance i scalculated from the XDISP_CEN column of the
82 spectral format table and the DIST ORDER keyword from the header of the
83 spectral format frame.
84*/
85
86static void compute_dist_pixel( int * xdisp, int * pdist, int dist_order,
87 int first, int last )
88{
89 int i, nb ;
90
91 nb = last - first ;
92 memset( pdist, 0, nb*sizeof(int) ) ;
93
94 for( i = 0 ; (i+dist_order) < nb ; i++, pdist++ ) {
95 *pdist = xdisp[i] - xdisp[i+dist_order] ;
96 xsh_msg( " Order: %d, Distance: %d\n", first+i, *pdist ) ;
97 }
98
99}
100
101static int compute_abs_order( START_ORDER * start_x, int nb,
102 cpl_frame * spectral_frame,
103 xsh_detect_continuum_param * detect_param,
105{
106 int dist_order ;
107 xsh_spectralformat_list * spectral_list = NULL ;
108 int * abs_orders = NULL ;
109 int * dist_pixel = NULL ;
110 int * xdisp_cen = NULL ;
111 int spec_size=0 ;
112 int i=0 ;
113 int * distances = NULL, * delta = NULL, * the_absorder = NULL ;
114 int ndist=0;
115 int good_order=0;
116 int ngood=0 ;
117 int first_order=0;
118 int last_order=0 ;
119 int min_idx=0 ;
120 XSH_ARM the_arm ;
121
122 xsh_msg( ">>>> Entering compute_abs_order" ) ;
124
125 /* Load spectral format list */
126 check( spectral_list = xsh_spectralformat_list_load(spectral_frame,
127 instrument)) ;
128 spec_size = spectral_list->size ;
129 xsh_msg( " Nb of Orders in Spectral Format: %d", spec_size ) ;
130
131 /* and get all relevant data needed */
132 XSH_CALLOC(dist_pixel, int, spec_size ) ;
133 XSH_CALLOC(xdisp_cen, int, spec_size ) ;
134 XSH_CALLOC(abs_orders, int, spec_size ) ;
135 check(xsh_spectralformat_list_get_xdisp_cen( spectral_list,
136 abs_orders, xdisp_cen));
137 if ( detect_param->dist_order == 0 ) dist_order = spectral_list->dist_order ;
138 else dist_order = detect_param->dist_order ;
139 xsh_msg( " DIST_ORDER = %d", dist_order ) ;
140 first_order = abs_orders[0] ;
141 last_order = abs_orders[spec_size-1]+1 ;
142 compute_dist_pixel( xdisp_cen, dist_pixel, dist_order, first_order,
143 last_order ) ;
144
145 xsh_msg( "First Order: %d, Last Order: %d", first_order, last_order ) ;
146 /* Calculate distances berween orders */
147 XSH_CALLOC( distances, int, nb ) ;
148 xsh_msg( "Calcul Distances" ) ;
149 for( ndist = 0, i = 0 ; i<nb ; i++, ndist++ ) {
150 int j ;
151
152 j = i+dist_order ;
153 if ( j >= nb ) break ;
154 distances[i] = abs((start_x+i)->start_x - (start_x+j)->start_x ) ;
155 xsh_msg( "distances[%d] = %d", i, distances[i] ) ;
156 }
157
158 /*
159 Loop over orders from spectral format:
160 compute avg of deltas
161 and get the minimum
162 */
163 {
164 float min_avg = 9999999. ;
165
166 for( i = 0 ; i<ndist ; i++ ) {
167 int j, k ;
168 float sdelta = 0., avg = 0. ;
169
170 if ( distances[i] <= 0 ) break ;
171 xsh_msg( " Start order %d", i ) ;
172 for( k = i, j = 0 ; j<spec_size; j++, k++ ) {
173 if ( dist_pixel[j] <= 0 ) break ;
174 sdelta += abs(distances[k] - dist_pixel[j]) ;
175 xsh_msg( " found: %d, spec: %d, delta: %d (%d,%d)", k, j,
176 abs(distances[k] - dist_pixel[j]), distances[k],
177 dist_pixel[j] ) ;
178 }
179 if ( j == 0 ) continue ;
180 avg = sdelta/(float)j ;
181 xsh_msg( " ===> avg: %.3lf", avg ) ;
182
183 if ( avg < min_avg ) {
184 min_avg = avg ;
185 min_idx = i ;
186 }
187 }
188 xsh_msg( " Best first absolute order found: %d (%d)", min_idx,
189 abs_orders[0] ) ;
190 }
191
192 good_order = abs_orders[0] ;
193 xsh_msg( "First good order: index %d, absorder %d, Position %d",
194 min_idx, good_order, (start_x+min_idx)->start_x ) ;
195
196 /* Set absolute orders TEST !*/
197 for( ngood=0, i=min_idx ; i<nb && good_order<last_order ; i++, ngood++ ) {
198 (start_x+i)->absorder = good_order++ ;
199 xsh_msg( "Center[%d]: Absorder %d, Position %d", i, (start_x+i)->absorder,
200 (start_x+i)->start_x) ;
201 }
202
203 /* if min_idx is not 0, suppress spurious orders */
204 if ( min_idx != 0 ) {
205 xsh_msg( "Remove spurious orders" ) ;
206 memmove( start_x, start_x+min_idx, sizeof(START_ORDER)*ngood ) ;
207 }
208
209 {
210 int expected ;
211 expected = instrument->config->orders ;
212 xsh_msg( " ===== Orders Found: %d (should be %d)", ngood, expected ) ;
213 XSH_ASSURE_NOT_ILLEGAL_MSG( ngood == expected,
214 "\n***** NOT ENOUGH ORDERS FOUND. STOP *****\n" ) ;
215 }
216
217 cleanup:
218 XSH_FREE( distances ) ;
219 XSH_FREE( dist_pixel ) ;
220 XSH_FREE( abs_orders ) ;
221 XSH_FREE( delta ) ;
222 XSH_FREE( the_absorder ) ;
223 xsh_spectralformat_list_free( &spectral_list ) ;
224
225 return ngood ;
226}
227
228static void invert_startx( START_ORDER * pstart, int nb )
229{
230 int i, j ;
231 START_ORDER * nstart = NULL;
232
233 XSH_CALLOC( nstart, START_ORDER, nb ) ;
234
235 for( j = 0, i = (nb-1) ; i>=0 ; i--, j++ )
236 *(nstart+j) = *(pstart+i) ;
237
238 memcpy( pstart, nstart, nb*sizeof(START_ORDER) ) ;
239
240 cleanup:
241 return ;
242}
243
244static int comp_center( const void * one, const void * two )
245{
246 CENTER_ORDER * first = (CENTER_ORDER *)one ;
247 CENTER_ORDER * secnd = (CENTER_ORDER *)two ;
248
249 if ( first->order < secnd->order ) return -1 ;
250 else if ( first->order > secnd->order ) return 1 ;
251 else return 0 ;
252}
253
266static int find_maximum( int * found, double * pos_x, int ix0, int max,
267 double thresh )
268{
269 int ix ;
270 double * ppos ;
271
272 xsh_msg_dbg_high( "Find_maximum: Start at %d, thresh=%lf", ix0, thresh ) ;
273 if ( thresh < 0 ) thresh = 0. ;
274 for( ppos = pos_x+ix0, ix = ix0 ; ix < max ; ix++, ppos++ ) {
275 double flux0 ;
276
277 if ( *ppos < thresh ) continue ;
278 /* Got a pixel with flux > threshold
279 now search maximum
280 */
281 for( flux0 = 0., ppos++, ix++ ; ix < max ; ix++, ppos++ ) {
282 if ( *ppos > flux0 ) {
283 flux0 = *ppos ;
284 *found = ix ;
285 continue ;
286 }
287 else {
288 /*
289 continue till flux < threshold
290 */
291 xsh_msg_dbg_high( " Max X: %d, %lf", *found, flux0 ) ;
292 for( ; ix < max ; ix++, ppos++ ) {
293 if ( *ppos < thresh ) {
294 /* finished ! */
295 return ix ;
296 }
297 xsh_msg_dbg_high( " X: %d, %lf", ix, *ppos ) ;
298 }
299 }
300 }
301 }
302 xsh_msg( " NOT FOUND !" ) ;
303 return -1 ;
304}
305
317static int search_max( xsh_pre * pre, int iy, int ix0, int ix1 )
318{
319 int ix, ixmax ;
320 double max = -9999999. ;
321
322 for( ixmax = 0, ix = ix0 ; ix<ix1 ; ix++ ) {
323 int rej ;
324 double flux ;
325
326 flux = cpl_image_get( pre->data, ix, iy, &rej ) ;
327
328 if ( rej != 0 ) continue ;
329 if ( flux > max ) {
330 ixmax = ix ;
331 max = flux ;
332 }
333 }
334
335 return ixmax ;
336}
337
338static void save_centers(CENTER_ORDER * pcent, int fpos, int npos,
339 const char * arm )
340{
341 static FILE * fgnu = NULL, * freg = NULL ;
342 static const char * gnuname ;
343 int first_call ;
344 FILE *fout ;
345 char fname[32] ;
346 int i, order ;
347 CENTER_ORDER * ppcent ;
348
349 if ( fgnu == NULL ) {
350 gnuname = xsh_stringcat_any( "all_orders_", arm, ".gnu", (void*)NULL ) ;
351 fgnu = fopen( gnuname, "w" ) ;
352 fprintf( fgnu, "set term x11\nplot " ) ;
353 first_call = 1 ;
354 }
355 else first_call = 0 ;
356 ppcent = pcent + fpos ;
357 order = ppcent->order ;
358 sprintf( fname, "order_%s_%02d.dat", arm, order ) ;
359 fout = fopen( fname, "w" ) ;
360
361 if ( !first_call ) fprintf( fgnu, "," ) ;
362 fprintf( fgnu, "'%s' u 1:2 w points pt 5 t''", fname ) ;
363
364 for( i = fpos ; i<npos; i++, ppcent++ )
365 fprintf( fout, "%d %d %.3lf\n",
366 ppcent->pos_x, ppcent->pos_y, ppcent->flux ) ;
367
368 fclose( fout ) ;
369 if ( order == 0 ) {
370 fprintf( fgnu, "\n" ) ;
371 fclose( fgnu ) ;
372 }
373
374 /* Now create a .reg file */
375 if ( freg == NULL )
376 freg = fopen( "order_create.reg", "w" ) ;
377 fprintf( freg, "# Region file format: DS9 version 4.0\n" ) ;
378 fprintf( freg, "global color=red font=\"helvetica 4 normal\"select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source\n" ) ;
379 fprintf( freg, "image\n# RED center_x center_y (pixels)\n" ) ;
380 for( ppcent = pcent+fpos, i = fpos ; i <npos ; i++, ppcent++ ) {
381 fprintf( freg, "point(%d.,%d.) #point=cross color=red font=\"helvetica 4 normal\"\n", ppcent->pos_x, ppcent->pos_y ) ;
382 }
383 if ( order == 0 ) fclose( freg ) ;
384}
385
386static void save_pos_x( double * posx, int size, const char * arm )
387{
388 FILE * fout ;
389 char fname[32] ;
390 int i ;
391
392 sprintf( fname, "histo_%s.dat", arm ) ;
393 fout = fopen( fname, "w" ) ;
394
395 for( i = 0 ; i<size ; i++ )
396 fprintf( fout, "%d %lf\n", i, *(posx+i) ) ;
397
398 fclose( fout ) ;
399}
400
401static void fit_order_list( xsh_order_list * list,
402 int npos, CENTER_ORDER * pcent, int degree)
403{
404 double * vorder = NULL, * po ;
405 double * pos_x = NULL, * px ;
406 double * pos_y = NULL, * py ;
407 int i ;
408
409 XSH_CALLOC( vorder, double, npos ) ;
410 XSH_CALLOC( pos_x, double, npos ) ;
411 XSH_CALLOC( pos_y, double, npos ) ;
412
413 po = vorder ;
414 px = pos_x ;
415 py = pos_y ;
416 for( i = 0 ; i<npos ; i++, po++, px++, py++, pcent++ ) {
417 *po = pcent->order ;
418 *px = pcent->pos_x ;
419 *py = pcent->pos_y ;
420 }
421
422 xsh_order_list_fit(list, npos, vorder, pos_x, pos_y, degree) ;
423
424 cleanup:
425 XSH_FREE( vorder ) ;
426 XSH_FREE( pos_x ) ;
427 XSH_FREE( pos_y ) ;
428 return ;
429}
430
431/*
432 Starting at the center Y=NY/2
433 Detect local maxima with an S/N ratio 'fmtchk_search_sn'
434 ==> gives us a list of center of orders
435 For each order:
436 + start form position of the previous center --> high Y
437 shift in Y by step_y pixels
438 search the maximum in a window 'fmtchk_window' around new y center
439 ==> the new center added to list of centers for this order
440 + start form position of the previous center --> low Y
441 shift in Y by step_y pixels
442 search the maximum in a window 'fmtchk_window' around new y center
443 ==> the new center added to list of centers for this order
444
445 Fit the polynomials (xsh_order_list_fit)
446
447 TBD:
448 How do i know the absolute orders ? (necessary for the order_table)
449
450*/
451
452
453cpl_frame *
455 cpl_frame * spectral_frame,
456 xsh_detect_continuum_param * detect_param,
458{
459 xsh_order_list * res_list = NULL ;
460 cpl_frame * result = NULL ;
461 int nx, ny, iy0, iy=0, ix, ix0, ix1, step_y ;
462 int degree ;
463 int norders ;
464 int imax=0, found=0;
465 double * pos_x = NULL ;
466 double med, stdev ;
467 int nfound, iord, npos, fpos ;
468 CENTER_ORDER * centers = NULL ;
469 START_ORDER * order_startx = NULL ;
470 const char* tag=NULL;
471 const char* fname=NULL;
472
473 xsh_msg( " ======= xsh_order_table_from_fmtchk" ) ;
474 xsh_msg( " Window: %d, Step: %d, Search S/N; %.1lf, Follow S/N: %.1lf",
475 detect_param->fmtchk_window, detect_param->fmtchk_step,
476 detect_param->fmtchk_search_sn,
477 detect_param->fmtchk_follow_sn ) ;
478
479 XSH_ASSURE_NOT_NULL( pre ) ;
480 XSH_ASSURE_NOT_NULL( spectral_frame ) ;
481 XSH_ASSURE_NOT_NULL( detect_param ) ;
483
484 /*
485 set the expected nb of orders
486 should be available in instrument structure
487 */
488 if ( instrument->config == NULL )
490
491 norders = instrument->config->orders ;
492 xsh_msg( " Expected Orders: %d", norders ) ;
493 /* We reserve room for extra orders. Multipliying by 2 is certainly too much
494 but is conservative. */
495 XSH_CALLOC( order_startx, START_ORDER, norders*2 ) ;
496
497 nx = xsh_pre_get_nx( pre ) ;
498 ny = xsh_pre_get_ny( pre ) ;
499
500 if ( instrument->arm == XSH_ARM_VIS ) iy0 = 0.75*ny ;
501 else iy0 = ny/2 ;
502
503 degree = detect_param->poly_degree ;
504 step_y = detect_param->fmtchk_step ;
505
506 XSH_CALLOC( centers, CENTER_ORDER, ((norders*2)*(ny/step_y))+10 ) ;
507
508 /*
509 starting from the middle of the frame
510 make a projection along X axis.
511 calculate maxima
512 move to the end of the frame (x = nx) by step pixels
513 Same by moving to the beginning (x = 0)
514
515 Compute the polynomial coefficients
516
517 That's it
518 */
519
520 XSH_CALLOC( pos_x, double, nx ) ;
521
522 /* Create empty order list */
523 check( res_list=xsh_order_list_create( instrument ) ) ;
524
525 /* Search maxima at y = ny/2 */
526 // get median value in the window
527
528 med = cpl_image_get_median_window( pre->data, 1, iy0, nx, iy0 ) ;
529 stdev = cpl_image_get_stdev_window( pre->data, 1, iy0, nx, iy0 ) ;
530 xsh_msg( " ===> Y=%d, median = %lf, stdev = %lf", iy, med, stdev ) ;
531
532 for( ix = 1; ix <= nx ; ix++ ) {
533 double flux ;
534 int rej ;
535
536 flux = cpl_image_get( pre->data, ix, iy0, &rej ) ;
537 *(pos_x+ix-1) = flux ;
538 }
540 save_pos_x( pos_x, nx,
542
543 /* Search maxima in pos_x array */
544 for( ix = 0, imax = 0, nfound = 0 ; nfound < (norders*2) ; ) {
545 ix = find_maximum( &found, pos_x, ix, nx-1,
546 med*detect_param->fmtchk_search_sn ) ;
547 if ( ix == -1 ) break ;
548 xsh_msg( "Found Order %d at %d,%d, value: %lf", nfound, found, iy0,
549 *(pos_x+found) ) ;
550 (order_startx+nfound)->start_x = found+1 ;
552 nfound++ ;
553 }
554 if (nfound ==0) {
555 xsh_msg("Found only 0 orders!");
556 xsh_msg("Try to decrease drecoverformat-search-min-sn parameter value");
557 }
558
559 /* Invert the order of the orders (high X/high lambda first) */
560 check(invert_startx( order_startx, nfound ) );
561
562 /* Now we should
563 a) find the first "correct" order
564 b) assign at each order an absolute order number
565 c) keep only the "good" orders ie as many orders as possible up to
566 the nb of orders for this arm
567 */
568 check(norders = compute_abs_order( order_startx, nfound,
569 spectral_frame, detect_param,
570 instrument )) ;
571
572 /* For each order found, find maxima for y --> ny and
573 for y --> 1 */
574 for( fpos = 0, npos = 0, iord = 0 ; iord < norders ; iord++ ) {
575 double max ;
576 int dum ;
577 int low_y = 0, up_y = ny-1 ;
578 int the_ord ;
579
580 xsh_msg( " Seaching for Order %d (window: %d)", iord,
581 detect_param->fmtchk_window ) ;
582 xsh_msg( " Starting position: %d,%d",
583 (order_startx+iord)->start_x, iy0 );
584
585 ix = (order_startx+iord)->start_x ;
586 the_ord = (order_startx+iord)->absorder ;
587 centers[npos].order = the_ord ; /* TEST !!! */
588 centers[npos].pos_x = ix ;
589 centers[npos].pos_y = iy0 ;
590 centers[npos].flux = *(pos_x+ix) ;
591 npos++ ;
592 for( iy = (iy0+step_y) ; iy <= ny ; iy+= step_y, npos++ ) {
593 // ix, iy in [1,n] space
594 ix0 = ix - detect_param->fmtchk_window ;
595 ix1 = ix + detect_param->fmtchk_window ;
596 if ( ix0 < 1 ) ix0 = 1 ;
597 if ( ix1 >= nx ) ix1 = nx ;
598 /* get max in a window (in X) 2*search_window + 1 */
599 ix = search_max( pre, iy, ix0, ix1 ) ;
600 max = cpl_image_get( pre->data, ix, iy, &dum ) ;
601 if ( dum != 0 ) continue ;
602 if ( max <= 0 || max < med*detect_param->fmtchk_follow_sn ) break ;
603 up_y = iy ;
604 centers[npos].order = the_ord ; /* TEST !!! */
605 centers[npos].pos_x = ix ;
606 centers[npos].pos_y = iy ;
607 centers[npos].flux = max ;
608 xsh_msg_dbg_high( " Max at %d,%d: %lf", ix, iy, max ) ;
609 }
610 ix = (order_startx+iord)->start_x ;
611 for( iy = (iy0-step_y) ; iy > 0 ; iy -= step_y, npos++ ) {
612 ix0 = ix - detect_param->fmtchk_window ;
613 ix1 =ix + detect_param->fmtchk_window ;
614 if ( ix0 < 1 ) break ;
615 if ( ix1 > nx ) break ;
616 /* get max in a window (in X) 2*detect_param->fmtchk_window + 1 */
617 ix = search_max( pre, iy, ix0, ix1 ) ;
618 max = cpl_image_get( pre->data, ix, iy, &dum ) ;
619 if ( max <= 0 || max < med*detect_param->fmtchk_follow_sn ) {
620 xsh_msg( " Stop Following at %d,%d (value = %.2lf)", ix, iy, max ) ;
621 break ;
622 }
623 low_y = iy ;
624 centers[npos].order = the_ord ; /* TEST !!! */
625 centers[npos].pos_x = ix ;
626 centers[npos].pos_y = iy ;
627 centers[npos].flux = max ;
628 xsh_msg_dbg_high( " Max at %d,%d: %lf", ix, iy, max ) ;
629 }
631 save_centers( centers, fpos, npos,
633 fpos = npos ;
634 res_list->list[iord].starty = low_y ;
635 res_list->list[iord].endy = up_y ;
636 res_list->list[iord].absorder = the_ord ; /* TEST !!! */
637 }
638
639 /*Fit order list */
640 qsort( centers, npos, sizeof( CENTER_ORDER ), comp_center ) ;
641 fit_order_list(res_list, npos, centers, degree);
642 //xsh_order_list_dump( res_list, NULL ) ;
643
644 /*
645 Save order table frame
646 */
648 fname="ORDER_TAB_FROM_FMTCHK.fits";
649 check(result=xsh_order_list_save(res_list,instrument,fname,tag,pre->ny)) ;
650
651 cleanup:
652 XSH_FREE( pos_x ) ;
653 XSH_FREE( centers ) ;
654 XSH_FREE( order_startx ) ;
655
656 return result ;
657}
static int degree
static xsh_instrument * instrument
xsh_order_list * xsh_order_list_create(xsh_instrument *instr)
create an empty order list
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.
void xsh_order_list_fit(xsh_order_list *list, int size, double *order, double *posx, double *posy, int deg_poly)
fit the polynomial solution of given points
int xsh_pre_get_ny(const xsh_pre *pre)
Get ny of pre structure.
int xsh_pre_get_nx(const xsh_pre *pre)
Get nx of pre structure.
xsh_spectralformat_list * xsh_spectralformat_list_load(cpl_frame *frame, xsh_instrument *instr)
Load a spectralformat list from a frame.
void xsh_spectralformat_list_free(xsh_spectralformat_list **list)
Free memory associated to an spactralformat_list.
static int compute_abs_order(START_ORDER *start_x, int nb, cpl_frame *spectral_frame, xsh_detect_continuum_param *detect_param, xsh_instrument *instrument)
static int find_maximum(int *found, double *pos_x, int ix0, int max, double thresh)
static void save_centers(CENTER_ORDER *pcent, int fpos, int npos, const char *arm)
static void save_pos_x(double *posx, int size, const char *arm)
cpl_frame * xsh_order_table_from_fmtchk(xsh_pre *pre, cpl_frame *spectral_frame, xsh_detect_continuum_param *detect_param, xsh_instrument *instrument)
static void invert_startx(START_ORDER *pstart, int nb)
static int search_max(xsh_pre *pre, int iy, int ix0, int ix1)
static void fit_order_list(xsh_order_list *list, int npos, CENTER_ORDER *pcent, int degree)
static int comp_center(const void *one, const void *two)
static void compute_dist_pixel(int *xdisp, int *pdist, int dist_order, int first, int last)
#define check(COMMAND)
Definition: xsh_error.h:71
#define XSH_ASSURE_NOT_ILLEGAL_MSG(cond, msg)
Definition: xsh_error.h:111
#define XSH_ASSURE_NOT_NULL(pointer)
Definition: xsh_error.h:99
const char * xsh_instrument_arm_tostring(xsh_instrument *i)
Get the string associated with an arm.
XSH_INSTRCONFIG * xsh_instrument_get_config(xsh_instrument *i)
Get the instrument default set of keywords.
XSH_ARM xsh_instrument_get_arm(xsh_instrument *i)
Get an arm on instrument structure.
int size
#define xsh_msg(...)
Print a message on info level.
Definition: xsh_msg.h:121
#define xsh_msg_dbg_high(...)
Definition: xsh_msg.h:40
int xsh_debug_level_get(void)
get debug level
Definition: xsh_utils.c:3142
char * xsh_stringcat_any(const char *s,...)
Concatenate an arbitrary number of strings.
Definition: xsh_utils.c:1925
unsigned int first
Definition: irplib_error.c:88
unsigned int last
Definition: irplib_error.c:89
XSH_INSTRCONFIG * config
xsh_order * list
cpl_image * data
Definition: xsh_data_pre.h:65
@ XSH_ARM_VIS
#define pdist(x1, y1, x2, y2)
Definition: xsh_detmon.c:53
int nx
int ny
int order
Definition: xsh_detmon_lg.c:80
#define XSH_ORDER_TAB_GUESS
Definition: xsh_dfs.h:552
#define XSH_GET_TAG_FROM_ARM(TAG, instr)
Definition: xsh_dfs.h:1548
#define max(a, b)
#define XSH_FREE(POINTER)
Definition: xsh_utils.h:92
@ XSH_DEBUG_LEVEL_LOW
Definition: xsh_utils.h:137
#define XSH_CALLOC(POINTER, TYPE, SIZE)
Definition: xsh_utils.h:56