X-shooter Pipeline Reference Manual 3.8.15
xsh_cfg_recover.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: 2012-12-18 14:12:51 $
23 * $Revision: 1.25 $
24 * $Name: not supported by cvs2svn $
25 */
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30
31/*--------------------------------------------------------------------------*/
45/*--------------------------------------------------------------------------*/
48/*---------------------------------------------------------------------------
49 Includes
50 ---------------------------------------------------------------------------*/
51
52
53/* DRL steps */
54
55/* Error handling */
56#include <xsh_error.h>
57/* Utility fonctions */
58#include <xsh_utils.h>
59#include <xsh_msg.h>
60
61//#include <xsh_data_instrument.h> //Needed?
62/* DFS functions */
63#include <xsh_dfs.h>
64/* DRL functions */
65//#include <xsh_data_order.h> //Needed?
66#include <xsh_drl.h>
67#include <xsh_pfits.h>
68
69//#include <xsh_data_the_map.h> //Needed?
70
71/* Library */
72#include <cpl.h>
73#include <math.h>
74//#include <xsh_data_the_map.h>
75#include <xsh_data_resid_tab.h>
76#include <xsh_utils_table.h>
77
78#include <xsh_model_kernel.h>
79#include <xsh_model_utils.h>
80#include <xsh_model_io.h>
81#include <xsh_spectrum.h>
82#include<xsh_model_utils.h>
83#include <xsh_fit.h>
84//#include <xsh_pfits.h>
85#include <stdlib.h>
86
87/*---------------------------------------------------------------------------
88 Defines
89 ---------------------------------------------------------------------------*/
90
91#define RECIPE_ID "xsh_cfg_recover"
92#define RECIPE_AUTHOR "A. Modigliani, P. Bristow"
93#define RECIPE_CONTACT "amodigli@eso.org"
94
95#define XSH_THE_TAB_SUB_VIS "XSH_THE_TAB_VIS"
96#define XSH_THE_TAB_SUB_UVB "XSH_THE_TAB_UVB"
97#define XSH_THE_TAB_SUB_NIR "XSH_THE_TAB_NIR"
98
99#define XSH_STARTUP_TABLE_COLNAME_X "X"
100
101
102#define XSH_ORDPOS_POL_DIM_MAX 4
103/*---------------------------------------------------------------------------
104 Functions prototypes
105 ---------------------------------------------------------------------------*/
106
107/*
108 * Plugin initalization, execute and cleanup handlers
109 */
110
111static cpl_error_code
112xsh_cfg_recover_prepare_pm_set(cpl_table* tab_pat,
113 cpl_table* tab_dat,
114 cpl_parameterlist* parameters,
115 cpl_matrix** mat_pat,
116 cpl_matrix** mat_dat,
117 int* use_pat,
118 int* use_dat);
119
120
121
122static cpl_error_code
123xsh_cfg_recover_model_THE_create(cpl_frame* config_frame,
125 cpl_frame* wave_list,
126 cpl_frame** THE1, cpl_frame** THE9);
127
128
129static cpl_error_code
130xsh_cfg_recover_pattern_match(cpl_parameterlist* parameters,
131 cpl_matrix* mat_gue,
132 cpl_matrix* mat_dat,
133 int use_pattern,
134 int use_data,
135 int debug_level);
136
137
138
139static cpl_error_code
140xsh_cfg_recover_guess_tab_corr_by_user(cpl_parameterlist* parameters,
141 cpl_frame** model_xy_gue);
142
143
144static cpl_error_code
145xsh_cfg_recover_measure_line_xy_fit(cpl_frame* raw_frm,
146 cpl_parameterlist* parameters,
147 cpl_frame** model_xy_gue,
148 int debug_level);
149
150
151static cpl_error_code
152xsh_cfg_recover_add_peaks_xpos(cpl_frame* order_tab_centr,
153 xsh_instrument* instr,
154 cpl_table** tab_xy_peaks);
155
156
157
158static cpl_table*
159xsh_cfg_recover_remove_blends(cpl_table* tab_xy_guess,
160 cpl_table* tab_xy_peaks_sel,
161 const int thresh_x,
162 const int thresh_y);
163
164
165static cpl_table*
166xsh_cfg_recover_measure_tab_xy_peaks(cpl_image* ima_ext,
167 cpl_parameterlist* parameters);
168
169static cpl_table*
170xsh_cfg_recover_select_peaks(cpl_table* tab_xy_guess,
171 cpl_table* tab_xy_peaks,
172 const double factor);
173
174static cpl_error_code
176
177static cpl_error_code
178xsh_cfg_recover_measure_line_xy(cpl_frame* frame,
179 xsh_instrument* inst,
180 cpl_frame* order_tab_centr,
181 cpl_parameterlist* parameters,
182 const char* method,
183 cpl_frame* model_config,
184 cpl_frame** guess,
185 int debug_level);
186
187static cpl_error_code
189 cpl_table * lines_tab,
190 struct xs_3* p_xs_3_config,
191 xsh_instrument* inst,int pre_scan,
192 cpl_table ** lines_gue);
193
194
195static cpl_frame*
197 cpl_frame * wave_list,
198 cpl_frame * config_frame,
199 xsh_instrument* instr,int prescan);
200
201
202static cpl_image*
203xsh_cfg_recover_linear_ext(cpl_frame* raw_frm,
204 cpl_frame* order_tab_centr,
205 xsh_instrument* instr,
206 const int slit,
207 const double thresh_min);
208
209static cpl_error_code
211 cpl_frame* order_tab_centr,
212 cpl_frame** model_xy_gue);
213
214
215
216
217static int xsh_cfg_recover_create(cpl_plugin *);
218static int xsh_cfg_recover_exec(cpl_plugin *);
219static int xsh_cfg_recover_destroy(cpl_plugin *);
220
221/* The actual executor function */
222static int
223xsh_cfg_recover_last_step(cpl_parameterlist* parameters,
224 cpl_frameset* frameset,
226 cpl_frameset* raws,
227 cpl_frameset* calib);
228
229static cpl_error_code
230xsh_cfg_recover_driver(cpl_parameterlist* parameters,
231 cpl_frameset* frameset);
232
233/*---------------------------------------------------------------------------
234 Static variables
235 ---------------------------------------------------------------------------*/
237 "Optimizes a model configuration to match data taken after a major format change";
238
239/*
240 - [UVB,OPTIONAL-required if trace-orders=TRUE] \n\
241 Two RAW frames (Format = RAW, Tag = ORDERDEF_QTH_arm,ORDERDEF_D2_arm)\n\
242 - [VIS,OPTIONAL-required if trace-orders=TRUE] \n\
243 A RAW frame (Format = RAW, Tag = ORDERDEF_arm)\n\
244 - [NIR,OPTIONAL-required if trace-orders=TRUE] \n\
245 Two RAW frames (Format = RAW, Tag = ORDERDEF_arm_ON, ORDERDEF_arm_OFF)\n\
246 - [OPTIONAL-Required if trace-orders=TRUE] \n\
247 A spectral format table (Format = TABLE, Tag = SPECTRAL_FORMAT_TAB_arm)\n\
248*/
250 "This recipe creates a wavelength solution and an order table.\n\
251 Input Frames :\n\
252 - [UVB, VIS] A RAW frame (Format = RAW, Tag = FMTCHK_arm)\n\
253 - [NIR] Two RAW frames (Format = RAW, Tag = FMTCHK_arm_ON,FMTCHK_arm_OFF)\n\
254 - The old model cfg table (Format = TABLE, Tag = XSH_MOD_CFG_TAB_arm)\n\
255 - A ref. line list. The model computes corresponding positions \n\
256 (Format = TABLE, Tag = ARC_LINE_LIST_arm)\n\
257 - [UVB,VIS,OPTIONAL] A master bias (Format = PRE, Tag = MASTER_BIAS_arm)\n\
258 - [UVB,VIS,OPTIONAL] A master dark (Format = PRE, Tag = MASTER_DARK_arm)\n\
259 - [OPTIONAL-Required if method=pm,peaks] \n\
260 An order table (Format = TABLE, Tag = ORDER_TAB_CENTR_arm)\n\
261 - [OPTIONAL-Required if first-anneal=TRUE] \n\
262 A table with measured line positions (Format = TABLE, Tag = XSH_MEASCOORD_arm)\n\
263 Products : \n\
264 - if first-anneal=FALSE & last-step=FALSE\n\
265 nothing\n\
266 - if first-anneal=TRUE & last-step=FALSE\n\
267 an optimized model configuration, PRO.CATG=XSH_MOD_CFG_arm\n\
268 - if last-step=TRUE\n\
269 an optimized model configuration, PRO.CATG=XSH_MOD_FAN_arm\n\
270 an optimized model configuration, PRO.CATG=XSH_MOD_CFG_OPT_arm\n\
271 an quality control table, PRO.CATG=MODEL_GUESS_XY_arm\n\
272 the model theoretical map corresponding to the optimized model config,\n\
273 PRO.CATG=THEO_TAB_MULT_arm, THEO_TAB_IFU_arm, and THEO_TAB_SING_arm\n\
274 \n";
275
276
277
278/*---------------------------------------------------------------------------
279 Functions code
280 ---------------------------------------------------------------------------*/
281
282
283/*--------------------------------------------------------------------------*/
292/*--------------------------------------------------------------------------*/
293
294int cpl_plugin_get_info(cpl_pluginlist *list) {
295 cpl_recipe *recipe = NULL;
296 cpl_plugin *plugin = NULL;
297
298 recipe = cpl_calloc(1, sizeof(*recipe));
299 if ( recipe == NULL ){
300 return -1;
301 }
302
303 plugin = &recipe->interface ;
304
305 cpl_plugin_init(plugin,
306 CPL_PLUGIN_API, /* Plugin API */
307 XSH_BINARY_VERSION, /* Plugin version */
308 CPL_PLUGIN_TYPE_RECIPE, /* Plugin type */
309 RECIPE_ID, /* Plugin name */
310 xsh_cfg_recover_description_short, /* Short help */
311 xsh_cfg_recover_description, /* Detailed help */
312 RECIPE_AUTHOR, /* Author name */
313 RECIPE_CONTACT, /* Contact address */
314 xsh_get_license(), /* Copyright */
318
319 cpl_pluginlist_append(list, plugin);
320
321 return (cpl_error_get_code() != CPL_ERROR_NONE);
322}
323
324
325
326/*---------------------------------------------------------------------------*/
346/*--------------------------------------------------------------------------*/
347static int xsh_cfg_recover_create(cpl_plugin * plugin)
348{
349 cpl_recipe * recipe ;
350 cpl_parameter * p ;
351/*
352 xsh_detect_continuum_param param = { 10, 2, 5,
353 DETECT_CONTINUUM_POLYNOMIAL_DEGREE,
354 1, 0.,
355 20, 50, 140., 2., 0 } ;
356*/
357 /* Reset library state */
358 xsh_init();
359
360
361 /* Check that the plugin is part of a valid recipe */
362 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
363 recipe = (cpl_recipe *)plugin ;
364 else return -1 ;
365
366 /* Create the parameters list in the cpl_recipe object */
367 recipe->parameters = cpl_parameterlist_new() ;
368
369 assure( recipe->parameters != NULL,
370 CPL_ERROR_ILLEGAL_OUTPUT,
371 "Memory allocation failed!");
372
373 /* Set generic parameters (common to all recipes) xsh_parameters_decode_bp(RECIPE_ID,recipe->parameters,-1);*/
374 check( xsh_parameters_generic( RECIPE_ID, recipe->parameters ) ) ;
375 xsh_parameters_decode_bp(RECIPE_ID,recipe->parameters,-1);
376
377 // Set startup parameters
378 /* Fill the parameters list */
379 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.first-anneal",
380 CPL_TYPE_BOOL,
381 "Run first annealing (TRUE) or not (FALSE)"
382 "See recipe man-page % Input frames",
383 "xsh.xsh_cfg_recover",CPL_FALSE);
384
385 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"first-anneal");
386 cpl_parameterlist_append(recipe->parameters,p);
387
388
389 //Set first_anneal params
390
391 p = cpl_parameter_new_enum("xsh.xsh_model_compute.arm",
392 CPL_TYPE_STRING,
393 "Arm setting: ",
394 "xsh.xsh_model_compute",
395 "vis",
396 3,"uvb","vis","nir");
397
398 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"arm");
399 cpl_parameterlist_append(recipe->parameters, p);
400
401
402 p = cpl_parameter_new_value("xsh.xsh_model_compute.name_i",
403 CPL_TYPE_STRING,
404 "Filename with wavelength,x,y,order: ",
405 "xsh.xsh_model_compute",
406 "line_xy_ord.txt");
407
408 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"name_i");
409 cpl_parameterlist_append(recipe->parameters, p);
410
411
412 p = cpl_parameter_new_value("xsh.xsh_model_compute.niter",
413 CPL_TYPE_INT,"No of iterations for first anneal",
414 "xsh.xsh_model_compute", 100000);
415
416 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"niter");
417 cpl_parameterlist_append(recipe->parameters,p);
418
419 p = cpl_parameter_new_value("xsh.xsh_model_compute.coord_frame",
420 CPL_TYPE_INT,"Co-ordinate frame for centroids (0=raw,1=pre)",
421 "xsh.xsh_model_compute", 1);
422
423 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"coord_frame");
424 cpl_parameterlist_append(recipe->parameters,p);
425
426/*
427 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.trace-orders",
428 CPL_TYPE_BOOL,
429 "Run order trace (TRUE) or not (FALSE)"
430 "If FALSE you must provide ORDER_TAB_CENTRE_arm"
431 "See recipe man-page % Input frames",
432 "xsh.xsh_cfg_recover",CPL_FALSE);
433
434 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"trace-orders");
435 cpl_parameterlist_append(recipe->parameters,p);
436
437
438 // Set orderpos parameters
439 check(xsh_parameters_detect_continuum_create(RECIPE_ID,
440 recipe->parameters,
441 param));
442 check( xsh_parameters_clipping_dcn_create( RECIPE_ID,
443 recipe->parameters ) ) ;
444
445*/
446
447 /* Fill the parameters list */
448 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.last-step",
449 CPL_TYPE_BOOL,
450 "Run last step (TRUE) or not (FALSE)"
451 "See recipe man-page % Input frames",
452 "xsh.xsh_cfg_recover",CPL_FALSE);
453
454 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"last-step");
455 cpl_parameterlist_append(recipe->parameters,p);
456
457 /* Fill the parameters list */
458 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.plot",
459 CPL_TYPE_BOOL,
460 "Display plot (TRUE) or not (FALSE)",
461 "xsh.xsh_cfg_recover",CPL_FALSE);
462
463 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"plot");
464 cpl_parameterlist_append(recipe->parameters,p);
465
466 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.ima_thresh_min",
467 CPL_TYPE_DOUBLE,
468 "Min thresh raw image.",
469 "xsh.xsh_cfg_recover", 40.);
470
471 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ima_tresh_min");
472 cpl_parameterlist_append(recipe->parameters,p);
473
474
475 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.cor_prescan",
476 CPL_TYPE_BOOL,"Correct for prescan",
477 "xsh.xsh_cfg_recover", FALSE);
478
479 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"cor_prescan");
480 cpl_parameterlist_append(recipe->parameters,p);
481
482
483 p = cpl_parameter_new_enum("xsh.xsh_cfg_recover.method",
484 CPL_TYPE_STRING,
485 "Model predictions correction method. "
486 "safefit: safe fit"
487 "gfit: 2D Gaussian line fit"
488 "peaks: line peaks detection"
489 "pm: line peaks detection & pattern match",
490 "xsh.xsh_cfg_recover",
491 "safefit", 4,
492 "safefit","gfit","peaks", "pm");
493// "peaks", "gfit", "pbrfit", "safefit", "pm");
494 //Temporarily suppressed methods
495
496
497 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"method");
498 cpl_parameterlist_append(recipe->parameters,p);
499
500
501 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.offx",
502 CPL_TYPE_DOUBLE,"X offset to model predictions",
503 "xsh.xsh_cfg_recover", 0.);
504
505 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"offx");
506 cpl_parameterlist_append(recipe->parameters,p);
507
508
509 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.offy",
510 CPL_TYPE_DOUBLE,"Y offset to model predictions",
511 "xsh.xsh_cfg_recover", 0.);
512
513 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"offy");
514 cpl_parameterlist_append(recipe->parameters,p);
515
516
517
518 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.slit",
519 CPL_TYPE_INT,"Extraction slit",
520 "xsh.xsh_cfg_recover", 5);
521
522 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"slit");
523 cpl_parameterlist_append(recipe->parameters,p);
524
525
526 /*
527 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.gfit_box_sx",
528 CPL_TYPE_INT,"2D Gauss fit X search box size"
529 "for lines on actual frame",
530 "xsh.xsh_cfg_recover", 5);
531
532 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"gfit_box_sx");
533 cpl_parameterlist_append(recipe->parameters,p);
534 */
535
536
537 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.gfit_box_sy",
538 CPL_TYPE_INT,"Gauss fit Y search box size "
539 "for lines on actual frame",
540 "xsh.xsh_cfg_recover", 20);
541
542 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"gfit_box_sy");
543 cpl_parameterlist_append(recipe->parameters,p);
544
545
546 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.peak_line_fwhm",
547 CPL_TYPE_INT,
548 "The FWHM used in line convolution, "
549 "in pixel units",
550 "xsh.xsh_cfg_recover", 4);
551
552 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"peak_line_fwhm");
553 cpl_parameterlist_append(recipe->parameters,p);
554
555
556 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.peak_kappa",
557 CPL_TYPE_DOUBLE,
558 "The kappa value, used to identify line peaks "
559 "if max>kappa*stdev+median, max is a valid peak "
560 "where max, stdev,median are computed on the "
561 "extracted spectrum",
562 "xsh.xsh_cfg_recover", 5.);
563
564 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"peak_kappa");
565 cpl_parameterlist_append(recipe->parameters,p);
566
567
568
569
570 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.peak_factor",
571 CPL_TYPE_DOUBLE,
572 "Relative Intensity threshold factor "
573 "for line peaks detection",
574 "xsh.xsh_cfg_recover", 10.);
575
576 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"peak_factor");
577 cpl_parameterlist_append(recipe->parameters,p);
578
579
580 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.peak_match_x",
581 CPL_TYPE_INT,"Radii for line peaks matches",
582 "xsh.xsh_cfg_recover", 10);
583
584 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"peak_match_x");
585 cpl_parameterlist_append(recipe->parameters,p);
586
587
588 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.peak_match_y",
589 CPL_TYPE_INT,"Radii for line peaks matches",
590 "xsh.xsh_cfg_recover", 20);
591
592 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"peak_match_y");
593 cpl_parameterlist_append(recipe->parameters,p);
594
595
596 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.pm_ord_sel",
597 CPL_TYPE_INT,
598 "From guess line and peaks positions "
599 "are extracted the ones in the range "
600 "[ord_min,ord_min+pm_ord_sel] ",
601 "xsh.xsh_cfg_recover", 1);
602
603 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"pm_ord_sel");
604 cpl_parameterlist_append(recipe->parameters,p);
605
606
607 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.pm_radius",
608 CPL_TYPE_DOUBLE,
609 "Search radius applied in final pattern "
610 "matching (data units).",
611 "xsh.xsh_cfg_recover", 20.);
612
613 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"pm_radius");
614 cpl_parameterlist_append(recipe->parameters,p);
615
616 p = cpl_parameter_new_range("xsh.xsh_cfg_recover.pm_tolerance",
617 CPL_TYPE_DOUBLE,
618 "Max relative difference of angles and scales "
619 "from their median value for match acceptance.",
620 "xsh.xsh_cfg_recover", 0.1,0.001,0.5);
621
622 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"pm_tolerance");
623 cpl_parameterlist_append(recipe->parameters,p);
624
625
626
627 p = cpl_parameter_new_value("xsh.xsh_cfg_recover.anneal_niter",
628 CPL_TYPE_INT,"Simulated annealing iterations",
629 "xsh.xsh_cfg_recover", 1000);
630
631 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"anneal_niter");
632 cpl_parameterlist_append(recipe->parameters,p);
633
634
635
636 /* Return */
637 cleanup:
638 return 0;
639}
640
641
642
643/*--------------------------------------------------------------------------*/
649/*--------------------------------------------------------------------------*/
650
651static int xsh_cfg_recover_exec(cpl_plugin *plugin) {
652 cpl_recipe *recipe = NULL;
653 int recipe_status=0;
654 cpl_errorstate initial_errorstate = cpl_errorstate_get();
655
656 /* Check parameter */
657 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
658
659 /* Get the recipe out of the plugin */
660 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
661 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
662
663 recipe = (cpl_recipe *)plugin;
664
665 /* Check recipe */
666 check(xsh_cfg_recover_driver(recipe->parameters, recipe->frames));
667
668 if (!cpl_errorstate_is_equal(initial_errorstate)) {
669 /* Dump the error history since recipe execution start.
670 At this point the recipe cannot recover from the error */
671 xsh_free_parameterlist(&recipe->parameters);
672 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
673 }
674
675 cleanup:
676 return recipe_status;
677
678}
679
680/*--------------------------------------------------------------------------*/
686/*--------------------------------------------------------------------------*/
687static int xsh_cfg_recover_destroy(cpl_plugin *plugin)
688{
689 cpl_recipe *recipe = NULL;
690
691 /* Check parameter */
692 assure( plugin != NULL, CPL_ERROR_NULL_INPUT, "Null plugin" );
693
694 /* Get the recipe out of the plugin */
695 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
696 CPL_ERROR_TYPE_MISMATCH, "Plugin is not a recipe");
697
698 recipe = (cpl_recipe *)plugin;
699
700 xsh_free_parameterlist(&recipe->parameters);
701
702 cleanup:
703 if (cpl_error_get_code() != CPL_ERROR_NONE)
704 {
705 return 1;
706 }
707 else
708 {
709 return 0;
710 }
711}
712
713static cpl_error_code
714xsh_cfg_recover_driver(cpl_parameterlist* parameters,
715 cpl_frameset* frameset)
716{
717
718 const char* recipe_tags[1] = {XSH_FMTCHK};
719 int recipe_tags_size = 1;
720
721 cpl_parameter* p=NULL;
722 int first_anneal=0;
723 //int trace_order=0;
724 int last_step=0;
725 cpl_frameset* raws=NULL;
726 cpl_frameset* calib=NULL;
728
729/*
730 check(p = cpl_parameterlist_find(parameters,
731 "xsh.xsh_cfg_recover.trace-orders"));
732 check(trace_order = cpl_parameter_get_bool(p));
733*/
734
735 check(p = cpl_parameterlist_find(parameters,
736 "xsh.xsh_cfg_recover.first-anneal"));
737 check(first_anneal = cpl_parameter_get_bool(p));
738
739
740 check(p = cpl_parameterlist_find(parameters,
741 "xsh.xsh_cfg_recover.last-step"));
742 check(last_step = cpl_parameter_get_bool(p));
743
744/*
745 check( xsh_begin(frameset,parameters,&instrument, &raws, &calib,
746 "XSH_FAN",RECIPE_ID, XSH_BINARY_VERSION,
747 xsh_first_anneal_description_short ) ) ;
748*/
749
750 check( xsh_begin( frameset, parameters, &instrument, &raws, &calib,
751 recipe_tags, recipe_tags_size, RECIPE_ID,
752 XSH_BINARY_VERSION,
754
755 if(first_anneal) {
756 check_msg(xsh_model_first_anneal(parameters,frameset),
757 "error_performing first anneal");
758 }
759
760/*
761 if(trace_order) {
762 check_msg(xsh_orderpos(recipe->parameters, recipe->frames),
763 "Error performing order tracing");
764 }
765*/
766
767 if(last_step) {
768 check_msg(xsh_cfg_recover_last_step(parameters,frameset,
769 instrument,raws,calib),
770 "error performing startup");
771 }
772
773 xsh_free_frameset(&raws);
774 xsh_free_frameset(&calib);
775
776 cleanup:
777 xsh_free_frameset(&raws);
778 xsh_free_frameset(&calib);
780
781 return cpl_error_get_code();
782
783}
784
785
786/*--------------------------------------------------------------------------*/
794/*--------------------------------------------------------------------------*/
795static int
796xsh_cfg_recover_last_step(cpl_parameterlist* parameters,
797 cpl_frameset* frameset,
799 cpl_frameset* raws,
800 cpl_frameset* calib)
801{
802
803 //const char * fctid = "xsh_cfg_recover" ;
804 //xsh_instrument* instrument=NULL;
805
806 /* allocated locally */
807
808 //cpl_frameset* raws = NULL;
809 //cpl_frameset* calib = NULL;
810
811 cpl_frameset* on = NULL;
812 cpl_frameset* off = NULL;
813 cpl_frameset* on_off = NULL;
814
815
816 cpl_frame* master_bias = NULL;
817 cpl_frame* master_dark = NULL;
818 cpl_frame* bpmap = NULL;
819 cpl_frame* predict_rmbias = NULL;
820 cpl_frame* predict_rmdark = NULL;
821
822 cpl_frame* wave_list=NULL ;
823 cpl_frame* xsh_config_first_anneal=NULL ;
824 cpl_frame* xsh_config_input=NULL ;
825 cpl_frame* xsh_config_last_anneal=NULL ;
826 cpl_frame * order_tab_centr = NULL ;
827 cpl_frame * model_xy_gue=NULL;
828 cpl_frame * measure_xy_pos_frm=NULL;
829 cpl_frame * model_THE1_frm=NULL;
830 cpl_frame * model_THE9_frm=NULL;
831
832 int anneal_niter=10000;
833 cpl_parameter* p=NULL;
834 const char* method=NULL;
835 int prescan=false;
836 int debug_level=0;
837 cpl_frame* fmtchk = NULL;
838 const char* name=NULL;
839 const char* tag=NULL;
840 //cpl_frame* usr_lines_gue=NULL;
841 //cpl_table* usr_lines_tab=NULL;
842 const char* filename=NULL;
843 cpl_propertylist* plist=NULL ;
844 cpl_table* tab_xsh_config_first_anneal=NULL;
845 cpl_table* tab_xsh_config_input=NULL;
846 cpl_frame* first_anneal_frm=NULL;
847 int found_temp=true;
848 int first_anneal=true;
849
850 int pre_overscan_corr=0;
851
852 //double zeroK=-273.15;
853 int nrows;
854 /*Get the recipe options*/
855 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.cor_prescan"));
856 check(prescan = cpl_parameter_get_bool(p));
857
858 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.anneal_niter"));
859 check(anneal_niter = cpl_parameter_get_int(p));
860
861 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.method"));
862 check(method = cpl_parameter_get_string(p));
863
864 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.first-anneal"));
865 check(first_anneal = cpl_parameter_get_bool(p));
866
867 check(debug_level=xsh_parameters_debug_level_get("xsh_cfg_recover",parameters));
868
869
870/*
871 check( xsh_begin( frameset, parameters, &instrument, &raws, &calib,
872 XSH_FMTCHK,RECIPE_ID, XSH_BINARY_VERSION,
873 xsh_cfg_recover_description_short ) ) ;
874*/
876
877 /* RETRIEVE INPUT DATA */
878 if(first_anneal) {
879 check(first_anneal_frm=xsh_find_frame_with_tag(frameset,
881 instrument));
882 check(xsh_config_first_anneal=cpl_frame_duplicate(first_anneal_frm));
883 } else {
884 check(first_anneal_frm=xsh_find_frame_with_tag(frameset,
886 instrument));
887 check(xsh_config_first_anneal=cpl_frame_duplicate(first_anneal_frm));
888 check(name=cpl_frame_get_filename(xsh_config_first_anneal));
889 check(tab_xsh_config_first_anneal=cpl_table_load(name,1,0));
890 check(plist=cpl_propertylist_load(name,0));
892 check(filename=cpl_sprintf("%s%s",tag,".fits"));
893 check(cpl_table_save(tab_xsh_config_first_anneal,plist, NULL,filename,
894 CPL_IO_DEFAULT));
895 check(cpl_frame_set_filename(xsh_config_first_anneal,filename));
896 check(cpl_frame_set_tag(xsh_config_first_anneal,tag));
897 check(cpl_frame_set_group(xsh_config_first_anneal,CPL_FRAME_GROUP_PRODUCT));
898 check(cpl_frame_set_level(xsh_config_first_anneal,CPL_FRAME_LEVEL_FINAL));
899
900 }
901 /* Read in the list of wavelengths*/
903 instrument));
904
905
906 check(bpmap = xsh_find_master_bpmap( calib));
907 /* Look for a order_tab file (this has the polynomial coefficients for already
908 fitted orders*/
909 if(strcmp(method,"safefit")!=0) {
910 if((order_tab_centr = xsh_find_frame_with_tag(calib,XSH_ORDER_TAB_CENTR,
911 instrument)) == NULL ) {
912 xsh_msg_warning("Frame %s not provided",
914 cpl_error_set(cpl_func,CPL_ERROR_DATA_NOT_FOUND);
915 order_tab_centr=NULL;
917 if ((strcmp(method,"pm") == 0) || (strcmp(method,"peaks") == 0) ) {
918 xsh_msg_error("If method is 'pm' or 'peaks' you must provide");
919 xsh_msg_error("A valid frame taged as %s ",
921 goto cleanup;
922 }
923 }
924 }
925 /* In UVB and VIS mode */
927 /* RAWS frameset must have only one file */
928 XSH_ASSURE_NOT_ILLEGAL(cpl_frameset_get_size(raws) == 1);
929 if((master_bias = xsh_find_frame_with_tag(calib,XSH_MASTER_BIAS,
930 instrument)) == NULL) {
931 xsh_msg_warning("Frame %s not provided",XSH_MASTER_BIAS);
933 }
934 if((master_dark = xsh_find_frame_with_tag(calib,XSH_MASTER_DARK,
935 instrument)) == NULL) {
936 xsh_msg_warning("Frame %s not provided",XSH_MASTER_DARK);
938 }
939 }
940
941 /* Reduce data */
942 /* Prepare frames */
943 /* In UVB and VIS mode */
944
946 /* prepare RAW frames in XSH format */
947 check(xsh_prepare( raws, bpmap, master_bias, XSH_FMTCHK, instrument,
948 pre_overscan_corr,CPL_TRUE));
949 check(fmtchk = cpl_frameset_get_frame(raws,0));
950 /* subtract bias */
951 if(master_bias != NULL) {
952 check(predict_rmbias = xsh_subtract_bias(fmtchk,master_bias,
953 instrument,"FMTCHK_",0,0));
954 } else {
955 predict_rmbias = cpl_frame_duplicate(fmtchk);
956 }
957 if(master_dark != NULL) {
958 /* subtract dark */
959 filename = xsh_stringcat_any( "FMTCHK_DARK_",
961 ".fits", (void*)NULL ) ;
962 check(predict_rmdark = xsh_subtract_dark(predict_rmbias, master_dark,
963 filename, instrument));
964 } else {
965 predict_rmdark = cpl_frame_duplicate(predict_rmbias);
966 }
967 }
968 /* in NIR mode */
969 else{
971 check( off = xsh_frameset_extract ( raws,XSH_FMTCHK_OFF ) ) ;
972
973 check(xsh_prepare(on,NULL, NULL, "ON", instrument,pre_overscan_corr,CPL_TRUE));
974 /* prepare OFF frames in XSH format */
975 check(xsh_prepare(off,bpmap, NULL, "OFF", instrument,pre_overscan_corr,CPL_TRUE));
976 /* subtract dark */
977 check(on_off = xsh_subtract_nir_on_off(on, off, instrument));
978 check(predict_rmdark = cpl_frame_duplicate(cpl_frameset_get_frame(on_off,0)));
979 }
980
981
982 /* Compute guess table frame */
983 check(model_xy_gue=xsh_cfg_recover_gen_xyg_frame(wave_list,
984 xsh_config_first_anneal,
985 instrument,prescan));
986
987
988 //Apply user defined offsets if any has been set
989 check(xsh_cfg_recover_guess_tab_corr_by_user(parameters,&model_xy_gue));
990
991 /* This creates extra columns that are needed later, even in the case that we
992 use the barycentre measured in the data instead of the orderpos x-disp value*/
993
995 &model_xy_gue));
996
997 /*If first anneal is skipped then we want to update the temperature of the old
998 config that we are using to do the search. However, we should not update the
999 temperature if first_anneal was run because the config produced by first_anneal
1000 will have been fit with the old temperature and won't find the lines if we put
1001 the new one in*/
1002 /*load the image, we just want the header here*/
1003
1004 if (!first_anneal) {
1005 if(found_temp) {
1006 xsh_msg("update the prism temperatures before line matching");
1007 check(xsh_model_temperature_update_frame(&xsh_config_first_anneal,predict_rmdark,
1008 instrument,&found_temp));
1009 }
1010 }
1011
1013 instrument,
1014 order_tab_centr,
1015 parameters,
1016 method,
1017 xsh_config_first_anneal,
1018 &model_xy_gue,
1019 debug_level));
1020
1021 xsh_msg(" REGDEBUG A generate %s", cpl_frame_get_filename(model_xy_gue));
1022
1023 /*The first anneal config was only needed for locating the features, now we go back
1024 to the input config, the least known good soln*/
1025 if((xsh_config_input = xsh_find_frame_with_tag(frameset,XSH_MOD_CFG,
1026 instrument)) == NULL) {
1027 xsh_msg_error("Frame %s not found",
1030 (void*)NULL ) ) ;
1031 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1032 goto cleanup;
1033 }
1034
1035
1036 /*Now that the matching has been done, we should update the temperature
1037 before the annealing, because we want the eventual solution to be valid
1038 for the correct temperature*/
1039 if(found_temp) {
1040 xsh_msg("update the prism temperatures before annealing");
1041 //get the model so that we can update the prism
1042 //temperatures before annealing
1043 check(xsh_model_temperature_update_frame(&xsh_config_input,predict_rmdark,
1044 instrument,&found_temp));
1045 }
1046
1047
1048 //We need to set proper format in our best guess table in order to interface
1049 //with the anneal part of the physical model
1050 check(measure_xy_pos_frm=cpl_frame_duplicate(model_xy_gue));
1051
1052 /*add extra columns needed for pipe_anneal function*/
1054
1055 check(name=cpl_frame_get_filename(measure_xy_pos_frm));
1056
1057 nrows=cpl_table_get_nrow(cpl_table_load(name,1,0));
1058 //printf("rows in tab %d \n",nrows);
1059 if ((xsh_instrument_get_arm(instrument)==XSH_ARM_UVB && nrows<70) ||
1060 (xsh_instrument_get_arm(instrument) == XSH_ARM_VIS && nrows<120) ||
1061 (xsh_instrument_get_arm(instrument) == XSH_ARM_NIR && nrows<80)) {
1062 xsh_msg_error("Not enough matches (%" CPL_SIZE_FORMAT "). Try running with more iterations for first_anneal (higher niter)",cpl_table_get_nrow(cpl_table_load(name,1,0)));
1063 return -1;
1064 }
1065
1066 /*Call the annealing*/
1067 //The following generates leaks
1068 xsh_msg(" REGDEBUG B before annealing %s", cpl_frame_get_filename( measure_xy_pos_frm));
1069 check(xsh_config_last_anneal=xsh_model_pipe_anneal(xsh_config_input,
1070 measure_xy_pos_frm,
1071 anneal_niter,
1072 1.0,
1073 1,
1074 0));
1075 /*Make a THE table with the new config*/
1076 check(xsh_cfg_recover_model_THE_create(xsh_config_last_anneal,
1077 instrument,
1078 wave_list,
1079 &model_THE1_frm,
1080 &model_THE9_frm));
1081
1082 // xsh_cfg_recover_model_anneal();
1083
1084 check(xsh_add_product_table(xsh_config_last_anneal,frameset,parameters,
1085 RECIPE_ID,instrument,NULL));
1086 check(xsh_add_product_table(model_xy_gue,frameset,parameters, RECIPE_ID,
1087 instrument,NULL));
1088 check(xsh_add_product_table(model_THE1_frm,frameset,parameters, RECIPE_ID,
1089 instrument,NULL));
1090 check(xsh_add_product_table(model_THE9_frm,frameset,parameters, RECIPE_ID,
1091 instrument,NULL));
1092
1093 cleanup:
1094 xsh_free_table(&tab_xsh_config_first_anneal);
1095 xsh_free_table(&tab_xsh_config_input);
1096 xsh_end( RECIPE_ID, frameset, parameters );
1097 //xsh_free_frameset(&raws);
1098 //xsh_free_frameset(&calib);
1099 xsh_free_frame(&predict_rmbias );
1100 xsh_free_frame(&predict_rmdark );
1101 //xsh_instrument_free(&instrument );
1102 xsh_free_frame(&model_xy_gue);
1103 xsh_free_frame(&measure_xy_pos_frm);
1104 xsh_free_frame(&xsh_config_last_anneal);
1105 xsh_free_frame(&model_THE1_frm);
1106 xsh_free_frame(&model_THE9_frm);
1107 xsh_free_frameset(&on);
1108 xsh_free_frameset(&off);
1109 xsh_free_frameset(&on_off);
1110
1111
1112 /* Return */
1113 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1115 return -1 ;
1116 } else {
1117 return 0 ;
1118 }
1119
1120}
1121
1122/*--------------------------------------------------------------------------*/
1137/*--------------------------------------------------------------------------*/
1138
1139static cpl_error_code
1140xsh_cfg_recover_model_THE_create(cpl_frame* config_frame,
1142 cpl_frame* wave_list,
1143 cpl_frame** THE1_frm,
1144 cpl_frame** THE9_frm)
1145{
1146 struct xs_3* p_xs_3_config=NULL;
1147 struct xs_3 xs_3_config;
1148 const char* line_list=NULL;
1149 const char* THE1_filename="model_THE1.fits";
1150 const char* THE9_filename="model_THE9.fits";
1151 const char* pro_catg=NULL;
1152
1153 //Load xsh model configuration
1154 p_xs_3_config=&xs_3_config;
1155 if (xsh_model_config_load_best(config_frame, p_xs_3_config) !=
1156 CPL_ERROR_NONE) {
1157 xsh_msg_error("Cannot load %s as a config",
1158 cpl_frame_get_filename(config_frame)) ;
1159 return CPL_ERROR_DATA_NOT_FOUND ;
1160 }
1161
1162 check(line_list=cpl_frame_get_filename(wave_list));
1163 check(*THE1_frm=xsh_model_THE_create(p_xs_3_config,instrument,line_list,
1164 1,-1,THE1_filename));
1166 check(xsh_frame_config(THE1_filename,pro_catg,CPL_FRAME_TYPE_TABLE,
1167 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL,
1168 THE1_frm));
1169
1170 check(*THE9_frm=xsh_model_THE_create(p_xs_3_config,instrument,line_list,
1171 9,-1,THE9_filename));
1172
1174 check(xsh_frame_config(THE9_filename,pro_catg,CPL_FRAME_TYPE_TABLE,
1175 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL,
1176 THE9_frm));
1177
1178
1179 cleanup:
1180 if(cpl_error_get_code() == CPL_ERROR_NONE) {
1181 return cpl_error_get_code();
1182 } else {
1184 return cpl_error_get_code();
1185 }
1186}
1187
1188/*--------------------------------------------------------------------------*/
1198/*--------------------------------------------------------------------------*/
1199
1200static cpl_error_code
1201xsh_cfg_recover_guess_tab_corr_by_user(cpl_parameterlist* parameters,
1202 cpl_frame** model_xy_gue)
1203{
1204 const char* name=NULL;
1205 cpl_table* tab=NULL;
1206 double offx=0;
1207 double offy=0;
1208 cpl_parameter* p=NULL;
1209
1210 check(name=cpl_frame_get_filename(*model_xy_gue));
1211 check(tab=cpl_table_load(name,1,0));
1212
1213 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.offx"));
1214 check(offx = cpl_parameter_get_double(p));
1215
1216 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.offy"));
1217 check(offy = cpl_parameter_get_double(p));
1218
1219 check(cpl_table_add_scalar(tab,"XG",offx));
1220 check(cpl_table_add_scalar(tab,"YG",offy));
1221
1222 check(cpl_table_save(tab, NULL, NULL,name, CPL_IO_DEFAULT));
1223
1224 cleanup:
1225 xsh_free_table(&tab);
1226
1227 /* Return */
1228 return cpl_error_get_code();
1229}
1230
1231
1232/*--------------------------------------------------------------------------*/
1239/*--------------------------------------------------------------------------*/
1240
1241static cpl_error_code
1243{
1244 const char * name=NULL;
1245 cpl_table* tbl=NULL;
1246 int nrows=0;
1247 cpl_propertylist* header = NULL;
1248 char name_o[256];
1249 const char* tag=XSH_GET_TAG_FROM_ARM(XSH_MEASURE_LINE_POS_XY,inst);
1250
1251 sprintf(name_o,"%s%s",tag,".fits");
1252
1253 check(name=cpl_frame_get_filename(*frm));
1254
1255/* Commented because we have changed definition of the resid tab */
1256
1257 check(tbl=cpl_table_load(name,1,0));
1258 check ( header = cpl_propertylist_load( name, 0));
1259
1260 check(nrows=cpl_table_get_nrow(tbl));
1261 if(nrows==0) {
1262 xsh_msg_error("Table %s has 0 rows. Something wrong! Exit",name);
1263 goto cleanup;
1264 }
1265
1266 /* Renaming to be similar with resid_tab */
1267 check(cpl_table_name_column(tbl,"WAVELENGTH",
1269 check(cpl_table_name_column(tbl,"ABS_ORD",
1271 check(cpl_table_new_column(tbl,XSH_RESID_TAB_TABLE_COLNAME_SLITPOSITION,
1272 CPL_TYPE_DOUBLE));
1273 check(cpl_table_fill_column_window(tbl,
1275 0,nrows,0.));
1276 cpl_table_new_column(tbl,XSH_RESID_TAB_TABLE_COLNAME_SLITINDEX,CPL_TYPE_INT);
1277 cpl_table_fill_column_window(tbl,XSH_RESID_TAB_TABLE_COLNAME_SLITINDEX,0,
1278 nrows,4);
1279
1280 /* Input theoretical positions Not used by model */
1281 check(cpl_table_duplicate_column(tbl,
1283 tbl,"XC"));
1284 check( cpl_table_duplicate_column(tbl,
1286 tbl, "YC"));
1287
1288 /* Corrected input positions Not used by model */
1289 check(cpl_table_duplicate_column(tbl,
1291 tbl,"XC"));
1292 check( cpl_table_duplicate_column(tbl,
1294 tbl, "YC"));
1295
1296 /* Only Important columns for model */
1297 check(cpl_table_duplicate_column(tbl,
1299 tbl,"XC"));
1300 check( cpl_table_duplicate_column(tbl,
1302 tbl, "YC"));
1303
1304 cpl_table_new_column(tbl, XSH_RESID_TAB_TABLE_COLNAME_SIGMAXGAUSS,
1305 CPL_TYPE_DOUBLE);
1307
1308 cpl_table_fill_column_window(tbl, XSH_RESID_TAB_TABLE_COLNAME_SIGMAXGAUSS,
1309 0, nrows, 0.);
1310 cpl_table_new_column(tbl, XSH_RESID_TAB_TABLE_COLNAME_SIGMAYGAUSS,
1311 CPL_TYPE_DOUBLE);
1312 cpl_table_fill_column_window(tbl, XSH_RESID_TAB_TABLE_COLNAME_SIGMAYGAUSS,
1313 0, nrows, 0.);
1314 cpl_table_new_column(tbl, XSH_RESID_TAB_TABLE_COLNAME_XTHANNEAL,
1315 CPL_TYPE_DOUBLE);
1316 cpl_table_fill_column_window(tbl, XSH_RESID_TAB_TABLE_COLNAME_XTHANNEAL,
1317 0, nrows, 0.);
1318 cpl_table_new_column(tbl, XSH_RESID_TAB_TABLE_COLNAME_YTHANNEAL,
1319 CPL_TYPE_DOUBLE);
1320 cpl_table_fill_column_window(tbl, XSH_RESID_TAB_TABLE_COLNAME_YTHANNEAL,
1321 0, nrows, 0.);
1322
1323 cpl_table_new_column(tbl, XSH_RESID_TAB_TABLE_COLNAME_RESIDXMODEL,
1324 CPL_TYPE_DOUBLE);
1325 cpl_table_fill_column_window(tbl, XSH_RESID_TAB_TABLE_COLNAME_RESIDXMODEL,
1326 0, nrows, 0.);
1327 cpl_table_new_column(tbl, XSH_RESID_TAB_TABLE_COLNAME_RESIDYMODEL,
1328 CPL_TYPE_DOUBLE);
1329 cpl_table_fill_column_window(tbl, XSH_RESID_TAB_TABLE_COLNAME_RESIDYMODEL,
1330 0, nrows, 0.);
1331
1333
1334 cpl_table_erase_invalid_rows(tbl);
1335 check( xsh_pfits_set_pcatg(header,tag));
1336 check(cpl_table_save(tbl, header, NULL,name_o, CPL_IO_DEFAULT));
1337
1338 cpl_frame_set_filename(*frm,name_o);
1339 cpl_frame_set_tag(*frm,tag);
1340
1341 cleanup:
1342 xsh_free_table(&tbl);
1343 if(cpl_error_get_code() != CPL_ERROR_NONE) {
1345 }
1346 return cpl_error_get_code() ;
1347}
1348/*--------------------------------------------------------------------------*/
1361/*--------------------------------------------------------------------------*/
1362
1363static cpl_error_code
1365 cpl_parameterlist* parameters,
1366 cpl_frame** guess,
1367 int debug_level)
1368{
1369 //int box_sx=0;
1370 int box_sy=0;
1371 cpl_parameter* p=NULL;
1372 int ngue=0;
1373 int i=0;
1374
1375 double* pxg=NULL;
1376 double* pyg=NULL;
1377 double* pxf=NULL;
1378 double* pyf=NULL;
1379
1380 int* ps=NULL;
1381 cpl_image* ima=NULL;
1382 const char* name=NULL;
1383 //int size=50;
1384 double norm=0;
1385 double xcen=0;
1386 double ycen=0;
1387 double sig_x=0;
1388 double sig_y=0;
1389 double fwhm_x=0;
1390 double fwhm_y=0;
1391 const char* name_g="tab_xy_corr_gauss.fits";
1392 cpl_table* tab=NULL;
1393 cpl_table* tmp=NULL;
1394 int nfit=0;
1395 /*
1396 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.gfit_box_sx"));
1397 check(box_sx = cpl_parameter_get_int(p));
1398 */
1399
1400 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.gfit_box_sy"));
1401 check(box_sy = cpl_parameter_get_int(p));
1402
1403 check(name=cpl_frame_get_filename(raw_frm));
1404 check(ima=cpl_image_load(name,CPL_TYPE_DOUBLE,0,0));
1405
1406 check(name=cpl_frame_get_filename(*guess));
1407 check(tab=cpl_table_load(name,1,0));
1408
1409 check(ngue=cpl_table_get_nrow(tab));
1410 check(cpl_table_new_column(tab,"SELECT",CPL_TYPE_INT));
1411 check(cpl_table_new_column(tab,"XF",CPL_TYPE_DOUBLE));
1412 check(cpl_table_new_column(tab,"YF",CPL_TYPE_DOUBLE));
1413
1414 check(cpl_table_fill_column_window(tab,"SELECT",0,ngue,-1));
1415 check(cpl_table_fill_column_window(tab,"XF",0,ngue,0));
1416 check(cpl_table_fill_column_window(tab,"YF",0,ngue,0));
1417
1418 check(pxg=cpl_table_get_data_double(tab,"XC"));
1419 check(pyg=cpl_table_get_data_double(tab,"YC"));
1420 check(pxf=cpl_table_get_data_double(tab,"XF"));
1421 check(pyf=cpl_table_get_data_double(tab,"YF"));
1422 check(ps=cpl_table_get_data_int(tab,"SELECT"));
1423
1424 xsh_msg("ngue=%d",ngue);
1425 for(i=0;i<ngue;i++) {
1426 //xsh_msg("fit line %d",i);
1427 //one could also use xsh_image_find_barycenter but that is less accurate
1428 if(cpl_image_fit_gaussian(ima,(int)pxg[i],(int)pyg[i],box_sy,
1429 &norm,
1430 &xcen,&ycen,
1431 &sig_x,&sig_y,
1432 &fwhm_x,&fwhm_y) == CPL_ERROR_NONE) {
1433 pxf[i]=xcen;
1434 pyf[i]=ycen;
1435 ps[i]=1;
1436
1437 } else {
1438 //xsh_print_rec_status(0);
1439 cpl_error_reset();
1440 }
1441 }
1442 check(nfit=cpl_table_and_selected_int(tab,"SELECT",CPL_GREATER_THAN,-1));
1443
1444 xsh_msg("nfit=%d",nfit);
1445 check(tmp=cpl_table_extract_selected(tab));
1446
1447 check(cpl_table_erase_column(tmp,"XC"));
1448 check(cpl_table_erase_column(tmp,"YC"));
1449
1450 check(cpl_table_duplicate_column(tmp,"XC",tmp,"XF"));
1451 check(cpl_table_duplicate_column(tmp,"YC",tmp,"YF"));
1452
1453 if(debug_level > XSH_DEBUG_LEVEL_NONE) {
1454 check(cpl_table_save(tmp, NULL, NULL, name_g, CPL_IO_DEFAULT));
1455 check(cpl_table_save(tmp, NULL, NULL, name, CPL_IO_DEFAULT));
1456 }
1457
1458 cleanup:
1459 xsh_free_table(&tab);
1460 xsh_free_table(&tmp);
1461 xsh_free_image(&ima);
1462
1463 if(nfit ==0 ) {
1464 xsh_msg_error("nfit = 0, something wrong in %s",cpl_func);
1465 return CPL_ERROR_UNSPECIFIED;
1466 } else {
1467 if( cpl_error_get_code() != CPL_ERROR_NONE) {
1469 }
1470 return cpl_error_get_code() ;
1471 }
1472}
1473/*--------------------------------------------------------------------------*/
1485/*--------------------------------------------------------------------------*/
1486
1487
1488static cpl_error_code xsh_cfg_recover_measure_line_xy(cpl_frame* raw_frm,
1489 xsh_instrument* instr, cpl_frame* order_tab_centr,
1490 cpl_parameterlist* parameters, const char* method, cpl_frame* model_config,
1491 cpl_frame** guess, int debug_level) {
1492 cpl_image* ima = NULL;
1493
1494
1495
1496 cpl_table* tab_tmp1 = NULL;
1497 cpl_table* tab_tmp2 = NULL;
1498 cpl_table* tab_xy_corr = NULL;
1499 cpl_image* ima_ext = NULL;
1500 cpl_image* ima_raw = NULL;
1501 double fct = 2.;
1502 int slit = 10;
1503 cpl_parameter* p = NULL;
1504 const char* name = NULL;
1505 const char* name_g = NULL;
1506 const char* name_t = "tab_xy_peaks.fits";
1507 int thresh_x = 0;
1508 int thresh_y = 0;
1509 cpl_table* tab_xy_guess=NULL;
1510 cpl_matrix* mat_gue = NULL;
1511 cpl_matrix* mat_msr = NULL;
1512 double thresh_min = 25;
1513 int use_data = 0;
1514 int use_pattern = 0;
1515
1516 double* pxg = NULL;
1517 double* pyg = NULL;
1518 double yg_temp[20000];
1519 double xg_temp[20000];
1520 double* wave = NULL;
1521 int* ordg = NULL;
1522 int* psl = NULL;
1523
1524
1525 //int ord_num;
1526 int wmin = 0;
1527
1528 int w = 0;
1529
1530
1531 cpl_vector* spectrum = NULL;
1532 cpl_vector* filtered = NULL;
1533 cpl_vector* spec_clean = NULL;
1534 cpl_vector* bright_lines = NULL;
1535
1536 //FILE* ex1d_out=NULL;
1537 int kk = 0;
1538 double* pxc = NULL;
1539 double* pyc = NULL;
1540 //double* pwl = NULL;
1541 int nrow = 0;
1542
1543 cpl_vector** trace = NULL;
1544 cpl_vector** extracted = NULL;
1545 int MAX_NO_ORD = 16;
1546 struct xs_3 xs_3_config;
1547 struct xs_3* p_xs_3 = NULL;
1548 int h = 4;
1549 cpl_table* spec_form_tab = NULL;
1550 int starti = 0;
1551 int absord = 0;
1552 double tot = 0.0;
1553 double total = 0.0;
1554 double dx = 0;
1555 double* detec = NULL;
1556 int size_x = 0;
1557 int size_y = 0;
1558 int size_y_use = 0;
1559 int status = 0;
1560 double x = 0, y = 0, offx = 0, offy = 0;
1561 cpl_frame* spec_form_frame = NULL;
1562 int pix = 0;
1563 int nb_match = 0;
1564 cpl_table* tab_tmp = NULL;
1565 cpl_table* tab_xy_peaks = NULL;
1566 cpl_table* tab_xy_peaks_sel = NULL;
1567 double wave_use = 0, zero_off = 0, match_lim = 0, startlam = 0, endlam = 0;
1568 //double order_median = 0;
1569 p_xs_3 = &xs_3_config;
1570
1571 /*Get a new spectral format table using the config in spectralformat_create function*/
1572 check(xsh_model_config_load_best(model_config, p_xs_3));
1573 xsh_msg("Calling spectral format create");
1574 /*When "spec_form.fits" is passed as the name then the extra orders are generated
1575 so that other parts of the pipeline do not complain about the number of orders*/
1576 check(
1577 spec_form_frame = xsh_model_spectralformat_create(p_xs_3,
1578 "not_spec_form.fits"));
1579 check(
1580 cpl_frame_set_tag(spec_form_frame,
1582
1583 check(p = cpl_parameterlist_find(parameters, "xsh.xsh_cfg_recover.method"));
1584 check(method = cpl_parameter_get_string(p));
1585
1586 int starty = 0;
1587 int endy = 0;
1588 int ii=0, jj=0;
1589 if (strcmp(method, "gfit") == 0) {
1590 check(
1591 xsh_cfg_recover_measure_line_xy_fit(raw_frm, parameters, guess,
1592 debug_level));
1593
1594 } else if (strcmp(method, "pbrfit") == 0 || strcmp(method, "safefit") == 0) {
1595
1596 if (strcmp(method, "safefit") == 0) {
1597 /* Get the command line offsets so that they can be applied in the xtraction
1598 and the matching */
1599 check(p = cpl_parameterlist_find(parameters, "xsh.xsh_cfg_recover.offx"));
1600 check(offx = cpl_parameter_get_double(p));
1601 check(p = cpl_parameterlist_find(parameters, "xsh.xsh_cfg_recover.offy"));
1602 check(offy = cpl_parameter_get_double(p));
1603
1604 /*Get the loci of the orders defined by the current model (as opposed to using
1605 the orderpos polynomials*/
1606 trace = xsh_model_locus(p_xs_3, instr, 0.0);
1607 /*Get the order parameter table defined by the current model (for max min
1608 co-ords and wavelengths for each order) */
1609 spec_form_tab = cpl_table_load(cpl_frame_get_filename(spec_form_frame), 1,
1610 0);
1611
1612 /*Put the raw data pixel array into a 1d array - detec*/
1613 check(name = cpl_frame_get_filename(raw_frm));
1614 check(ima_raw = cpl_image_load(name, CPL_TYPE_DOUBLE, 0, 0));
1615 check(size_y = cpl_image_get_size_y(ima_raw));
1616 check(size_x = cpl_image_get_size_x(ima_raw));
1617 xsh_msg("size_x=%d size_y=%d", size_x, size_y);
1618 check(detec = cpl_image_get_data_double(ima_raw));
1619
1620 /*Allocate array of MAX_NO_ORD vectors for 1d extracted spectra and fill with zeros*/
1621 check(extracted = cpl_malloc(MAX_NO_ORD * sizeof(cpl_vector *)));
1622 for (ii = 0; ii < MAX_NO_ORD; ii++) {
1623 extracted[ii] = cpl_vector_new(size_y);
1624 cpl_vector_fill(extracted[ii], 0.0);
1625 }
1626 /*The order parameter table may contain extra orders (dev purposes), so find the
1627 index of the one corresponding to the standard minimum order for this arm and
1628 start the loop from there*/
1629 starti = 0;
1630 while (cpl_table_get_int(spec_form_tab, "ORDER", starti, &status)
1631 < p_xs_3->morder_min) {
1632 starti++;
1633 }
1634 ii = starti;
1635 /*loop over orders*/
1636 for (ii = starti; ii <= starti + p_xs_3->morder_max - p_xs_3->morder_min;
1637 ii++) {
1638 absord = cpl_table_get_int(spec_form_tab, "ORDER", ii, &status);
1639 if (p_xs_3->arm != 2) {
1640 starty = (int) (cpl_table_get_float(spec_form_tab, "DISP_MIN", ii,
1641 &status));
1642 endy = (int) (cpl_table_get_float(spec_form_tab, "DISP_MAX", ii,
1643 &status));
1644 } else {
1645 starty = (int) (cpl_table_get_float(spec_form_tab, "DISP_MAX", ii,
1646 &status));
1647 endy = (int) (cpl_table_get_float(spec_form_tab, "DISP_MIN", ii,
1648 &status));
1649 }
1650 /*now loop over dispersion coordinate:
1651 - Compute x-disp coord from model
1652 - extract flux from +/-h pix around x-disp posn
1653 NOTE: ds9(1,1) -> jj=0 int(dx+0.5)+kk=0
1654 */
1655 //xsh_msg("endy=%d",endy);
1656 /*correct the limits with the command line offsets*/
1657 if (offy < 0.0) {
1658 starty -= (int) (offy);
1659 size_y_use = size_y;
1660 } else {
1661 endy -= (int) (offy);
1662 size_y_use = size_y - offy;
1663 }
1664 int jj=0;
1665 for (jj = starty; ((jj < endy) && (jj < size_y_use)); jj++) {
1666 tot = 0.0;
1667 /*get dx as a function of jj, with the command line offsets applied*/
1668 dx = cpl_vector_get(trace[absord - p_xs_3->morder_min], jj + offy)
1669 - offx;
1670 for (kk = -h; kk <= h; kk++) {
1671 if (p_xs_3->arm == 2) {
1672 pix = size_x * jj + ((int) (dx + 0.5) + kk);
1673 } else {
1674 pix = size_x * jj + (int) (dx + 0.5) + kk;
1675 }
1676 if (pix < size_x * size_y) {
1677 tot += detec[pix];
1678 }
1679 }
1680 check(
1681 cpl_vector_set(extracted[absord - p_xs_3->morder_min], jj, tot));
1682 }
1683 }
1684 }
1685
1686 else {
1687 //Get parameters for linear extraction
1688 check(p = cpl_parameterlist_find(parameters, "xsh.xsh_cfg_recover.slit"));
1689 check(slit = cpl_parameter_get_int(p));
1690
1691 check(
1692 p = cpl_parameterlist_find(parameters,
1693 "xsh.xsh_cfg_recover.peak_factor"));
1694 check(fct = cpl_parameter_get_double(p));
1695
1696 check(
1697 p = cpl_parameterlist_find(parameters,
1698 "xsh.xsh_cfg_recover.peak_match_x"));
1699 check(thresh_x = cpl_parameter_get_int(p));
1700
1701 check(
1702 p = cpl_parameterlist_find(parameters,
1703 "xsh.xsh_cfg_recover.peak_match_y"));
1704 check(thresh_y = cpl_parameter_get_int(p));
1705
1706 check(
1707 p = cpl_parameterlist_find(parameters,
1708 "xsh.xsh_cfg_recover.ima_thresh_min"));
1709 check(thresh_min = cpl_parameter_get_double(p));
1710
1711 //Image (linear) extraction: sum pixels
1712 //to check the actual image we are going to fit vs the model guess
1713
1714 cknull(
1715 ima_ext = xsh_cfg_recover_linear_ext(raw_frm, order_tab_centr, instr,
1716 slit, thresh_min));
1717
1718 }
1719 cpl_table* tab_xy_guess = NULL;
1720 /*Get the table that will contain the measured centroids*/
1721 check(name_g = cpl_frame_get_filename(*guess));
1722 check(tab_xy_guess = cpl_table_load(name_g, 1, 0));
1723 xsh_msg("guess tablename=%s", name_g);
1724 int morder_min = 0;
1725 morder_min = p_xs_3->morder_min;
1726 nrow = cpl_table_get_nrow(tab_xy_guess);
1727 /*add some new columns that will be needed*/
1728 cpl_table_new_column(tab_xy_guess, "XF", CPL_TYPE_DOUBLE);
1729 cpl_table_new_column(tab_xy_guess, "YF", CPL_TYPE_DOUBLE);
1730 cpl_table_new_column(tab_xy_guess, "SELECT", CPL_TYPE_INT);
1731 cpl_table_fill_column_window(tab_xy_guess, "XF", 0, nrow, -1);
1732 cpl_table_fill_column_window(tab_xy_guess, "YF", 0, nrow, -1);
1733 cpl_table_fill_column_window(tab_xy_guess, "SELECT", 0, nrow, -1);
1734 /*set pointers to some table columns that we will want to update*/
1735 pxc = cpl_table_get_data_double(tab_xy_guess, "XF");
1736 pyc = cpl_table_get_data_double(tab_xy_guess, "YF");
1737 //pwl = cpl_table_get_data_double(tab_xy_guess, "WAVELENGTH");
1738 /*temporary variable for the newly calcuated yg so that we can continue to use the
1739 current value while we are stil in the loop below.
1740 Set to -1 so we know that =>1 means that a match was found*/
1741 for (kk = 0; kk < nrow; kk++) {
1742 yg_temp[kk] = -1.0;
1743 }
1744 for (kk = 0; kk < nrow; kk++) {
1745 xg_temp[kk] = -1.0;
1746 }
1747
1748 kk = 0;
1749 /* loop over orders*/
1750
1751 int ord=0;
1752 for (ord = 0; ord < p_xs_3->morder_max - morder_min + 1; ord++) {
1753 check(
1754 absord = cpl_table_get_int(spec_form_tab, "ORDER", ord + starti,
1755 &status));
1756 if (p_xs_3->arm != 2) {
1757 check(
1758 starty = (int) (cpl_table_get_float(spec_form_tab, "DISP_MIN",
1759 ord + starti, &status)));
1760 check(
1761 endy = (int) (cpl_table_get_float(spec_form_tab, "DISP_MAX",
1762 ord + starti, &status)));
1763 } else {
1764 check(
1765 starty = (int) (cpl_table_get_float(spec_form_tab, "DISP_MAX",
1766 ord + starti, &status)));
1767 check(
1768 endy = (int) (cpl_table_get_float(spec_form_tab, "DISP_MIN",
1769 ord + starti, &status)));
1770 }
1771 check(
1772 startlam = cpl_table_get_float(spec_form_tab, "LFSR", ord + starti,
1773 &status));
1774 check(
1775 endlam = cpl_table_get_float(spec_form_tab, "UFSR", ord + starti,
1776 &status));
1777 /*For safefit use the 1d sepc in extracted[ord]*/
1778 if (strcmp(method, "safefit") == 0) {
1779 spectrum = extracted[ord];
1780 /* Subrtract the low frequency part */
1781 //cpl_msg_info(__func__, "Low Frequency signal removal") ;
1782 if ((filtered = cpl_vector_filter_median_create(spectrum, 200))
1783 == NULL) {
1784 cpl_msg_error(__func__, "Cannot filter the spectrum");
1785 return CPL_ERROR_ILLEGAL_INPUT;
1786 }
1787 spec_clean = cpl_vector_duplicate(spectrum);
1788 cpl_vector_subtract(spec_clean, filtered);
1789 cpl_vector_delete(filtered);
1790
1791 //order_median = cpl_vector_get_median_const(spec_clean);
1792 } else {
1793 /*otherwise from the ima_ext image array created by the
1794 xsh_cfg_recover_linear_ext function*/
1795 check(spectrum = cpl_vector_new_from_image_row(ima_ext, ord + 1));
1796 spec_clean = cpl_vector_duplicate(spectrum);
1797 }
1798 check(bright_lines = xsh_model_refining_detect(spec_clean, 3, 5.0, 0));
1799
1800 /*set some more pointers to table colummns that we will want to update*/
1801 check(pxg = cpl_table_get_data_double(tab_xy_guess, "XC"));
1802 check(pyg = cpl_table_get_data_double(tab_xy_guess, "YC"));
1803 check(wave = cpl_table_get_data_double(tab_xy_guess, "WAVELENGTH"));
1804 check(ordg = cpl_table_get_data_int(tab_xy_guess, "ABS_ORD"));
1805 check(psl = cpl_table_get_data_int(tab_xy_guess, "SELECT"));
1806
1807 /*loop over these peaks:
1808 - loop over w
1809 - get CofG for region containing core on left and window on right
1810 - get CofG for region containing window on left and core on right
1811 - check that both are within prec of listed peak centre
1812 - record the value of w to which the CofG is OK
1813 */
1814 double flux = 0;
1815 //double cent2_cor = 0;
1816 //double flux_cor = 0;
1817 double ex_cor = 0;
1818 double prec = 0, precfac = 0, precmin = 0;
1819 int min_iso=0;
1820 int lmax = 0, rmax = 0;
1821 int nbright_lines = 0;
1822 int cnt = 0;
1823 int lines_dev = 0;
1824 cpl_table* tab_xy_guess = NULL;
1825
1826
1827 if (bright_lines != NULL) {
1828 check(nbright_lines = cpl_vector_get_size(bright_lines));
1829 double cent = 0, cent2 = 0;
1830 for (ii = 0; ii < nbright_lines; ii++) {
1831 cent = cpl_vector_get(bright_lines, ii) + 0.5 - 1.0;
1832 //printf("%d %d %lf \n",ord,ii,cent);
1833 /*The -1.0 above is because Yves' function labels the first bin in the
1834 vector as 1, I label it 0*/
1835
1836 /*lines_dev: 0=normal; 1=vis sim; 2=vis real; 3=uvb sim; 4=uvb real; 5 nir sim; 6 nir real*/
1837 /*Try with match lim small for sim data and large for real data*/
1838 lines_dev = 0;
1839
1840 if (lines_dev == 1) {
1841 precmin = 0.25;
1842 precfac = 25.0;
1843 wmin = 3;
1844 min_iso = 5;
1845 zero_off = -0.5;
1846 match_lim = 0.2;
1847 } else if (lines_dev == 2) {
1848 precmin = 0.5;
1849 precfac = 25.0;
1850 wmin = 3;
1851 min_iso = 5;
1852 zero_off = -0.5;
1853 match_lim = 1.0;
1854 } else if (lines_dev == 3) {
1855 precmin = 0.25;
1856 precfac = 25.0;
1857 wmin = 3;
1858 min_iso = 5;
1859 zero_off = -0.5;
1860 match_lim = 0.25;
1861 } else if (lines_dev == 4) {
1862 precmin = 0.5;
1863 precfac = 25.0;
1864 wmin = 3;
1865 min_iso = 5;
1866 zero_off = -0.5;
1867 match_lim = 1.0;
1868 } else if (lines_dev == 5) {
1869 precmin = 0.4;
1870 precfac = 25.0;
1871 wmin = 3;
1872 min_iso = 5;
1873 zero_off = -0.5;
1874 match_lim = 0.5;
1875 } else if (lines_dev == 6) {
1876 precmin = 0.5;
1877 precfac = 15.0;
1878 wmin = 3;
1879 min_iso = 80;
1880 zero_off = -0.5;
1881 match_lim = 1.0; //check
1882 } else {
1883 precmin = 0.5;
1884 precfac = 20.0;
1885 wmin = 4;
1886 min_iso = 4;
1887 match_lim = 2.5;
1888 zero_off = 0.0;
1889 }
1890 rmax = 0;
1891 w = wmin;
1892 while (w < 200) {
1893 //prec=2.0;
1894 prec = (float) (w) / precfac;
1895 if (prec < precmin) {
1896 prec = precmin;
1897 }
1898 flux = 0.0;
1899 cent2 = 0.0;
1900 //flux_cor = 0.0;
1901 //cent2_cor = 0.0;
1902 for (jj = (int) (cent) - wmin; jj <= (int) (cent) + w; jj++) {
1903 //printf("%d %d %d %d \n",ord, ii, jj,endy);
1904 if (jj > 0 && jj < endy) {
1905 ex_cor = cpl_vector_get(spec_clean, jj);
1906 if (ex_cor > 0.0) {
1907 flux += ex_cor;
1908 cent2 += ex_cor * ((float) (jj) + 0.5 - cent);
1909 }
1910 //printf("%d %d %d %lf %lf %lf %lf \n",ord, ii, jj, flux, cent2, flux_cor, cent2_cor);
1911 }
1912 }
1913 cent2 /= flux;
1914 //printf("1 %d %d %lf %lf %lf %d %d %lf \n",ord, ii, cent2, flux, cent, w, (int)(cent)+w, prec);
1915 cent2 += cent;
1916 if (fabs(cent2 - cent) < prec) {
1917 rmax = w;
1918 //printf("%d %d %lf \n",ii, -w, cent2-cent);
1919 } else {
1920 w = 1000;
1921 }
1922 w += 1;
1923 }
1924 lmax = 0;
1925 w = wmin;
1926 while (w < 200) {
1927 //prec=2.0;
1928 prec = (float) (w) / precfac;
1929 if (prec < precmin) {
1930 prec = precmin;
1931 }
1932 flux = 0.0;
1933 cent2 = 0.0;
1934 //flux_cor = 0.0;
1935 //cent2_cor = 0.0;
1936 for (jj = (int) (cent) - w; jj <= (int) (cent) + wmin; jj++) {
1937 if (jj > 0 && jj < endy) {
1938 ex_cor = cpl_vector_get(spec_clean, jj);
1939 if (ex_cor > 0.0) {
1940 flux += ex_cor;
1941 cent2 += ex_cor * ((float) (jj) + 0.5 - cent);
1942 }
1943 }
1944 }
1945 cent2 /= flux;
1946 //printf("2 %d %d %lf %lf %lf %d %d %lf \n",ord, ii, cent2, flux, cent, w, (int)(cent)-w, prec);
1947 cent2 += cent;
1948 if (fabs(cent2 - cent) < prec) {
1949 lmax = w;
1950 //printf("%d %d %lf \n",ii, w, cent2-cent);
1951 } else {
1952 w = 1000;
1953 }
1954 w += 1;
1955 }
1956 //printf("%d %lf %d %d %d\n",ii, cent, ord, lmax, rmax);
1957 /*Check that isolation on both sides is above the minimum*/
1958 int ll=0;
1959 if (lmax >= min_iso && rmax >= min_iso) {
1960 /*For method safefit use model predictions to check against measured position,
1961 then determine x-disp co-ord*/
1962 if (strcmp(method, "safefit") == 0) {
1963 nb_match = 0;
1964 for (jj = 0; jj < cpl_table_get_nrow(tab_xy_guess); jj++) {
1965 if (ord == ordg[jj] - morder_min) {
1966 /*Get x,y with model*/
1967 check(
1968 xsh_model_get_xy(p_xs_3, instr, wave[jj], absord, 0.0, &x,
1969 &y));
1970 x -= offx;
1971 y -= offy;
1972 if (lines_dev > 0 && fabs(y - cent + zero_off) < match_lim) {
1973 nb_match++;
1974 //printf("%lf %lf %lf %lf %lf %lf %d %d %d %d %lf %lf\n", wave[jj], x, pyg[jj], y, cent, y-cent, ord, lmax, rmax,nb_match,match_lim, fabs(y-cent+zero_off));
1975 wave_use = wave[jj];
1976 }
1977 if (abs(y - cent) < (float) (min_iso) / 2.0) {
1978 /*keep this measured disp centroid in a temporary vector while we still
1979 need pyg (actually not necessary for the safefit method*/
1980 yg_temp[jj] = cent;
1981 psl[jj] = 1;
1982 total = 0.0;
1983 cent2 = 0.0;
1984 /*Now get the barycenter in a rectagle 3 wide (centred on measured
1985 disp co-ord) and +/-h around the model x-disp co-ord*/
1986 for (ll = -h; ll <= h; ll++) {
1987 tot = 0.0;
1988 for (kk = -1; kk <= 1; kk++) {
1989 /* check(tot=cpl_image_get_median_window(ima_raw,(int)(x+0.5)+ll,(int)(cent+0.5)-1, */
1990 /* (int)(x+0.5)+ll,(int)(cent+0.5)+1)); */
1991 /* check(tot-=cpl_image_get_median_window(ima_raw,(int)(x+0.5)+14,(int)(cent+0.5)-1, */
1992 /* (int)(x+0.5)+16,(int)(cent+0.5)+1)); */
1993 pix = size_x * ((int) (cent + 0.5) + kk)
1994 + (int) (x + 0.5) + ll;
1995 tot += detec[pix];
1996 pix = size_x * ((int) (cent + 0.5) + kk)
1997 + (int) (x + 0.5) + ll + 15;
1998 tot -= detec[pix];
1999 //printf("%d %d %d %d %lf \n",ll, kk,(int)(x+0.5)+ll,((int)(cent+0.5)+kk),tot);
2000 }
2001 total += tot;
2002 cent2 += tot * ((float) (ll) + 0.5);
2003 }
2004 if (fabs(cent2 / total) < 3.0) {
2005 cent2 = x + (cent2 / total);
2006 } else {
2007 cent2 = x;
2008 }
2009 /*keep this measured x-disp centroid in a temporary vector while we still
2010 need pxg (actually not necessary for the safefit method)*/
2011 xg_temp[jj] = cent2;
2012 }
2013 }
2014 }
2015 if (nb_match == 1 && lines_dev > 0) {
2016 if (wave_use > startlam && wave_use < endlam) {
2017 cnt++;
2018 //printf("%lf 100.0 \n",wave_use);
2019 printf("%lf 100.0 %d tot%d\n", wave_use, min_iso, cnt);
2020 }
2021 }
2022 } else {
2023 for (jj = 0; jj < cpl_table_get_nrow(tab_xy_guess); jj++) {
2024 if (ord == ordg[jj] - morder_min) {
2025 //printf("-- %d %d %d %lf %lf %lf %lf %d %d \n", jj, lmax, rmax, pyg[jj],cent,pxg[jj],wave[jj],ord,ordg[jj]-morder_min);
2026 if (abs(pyg[jj] - cent) < (float) (min_iso / 2)) {
2027 //printf("%lf %lf %lf %lf %d \n", wave[jj], pxg[jj], pyg[jj], cent, ord);
2028 /*keep this measured disp centroid in a temporary vector while we still
2029 need pyg*/
2030 yg_temp[jj] = cent;
2031 psl[jj] = 1;
2032 }
2033 }
2034 }
2035 }
2036 } //end of isolation margins check
2037 } //end for loop on ii (line peaks in data)
2038 } //end check on bright line vector
2039 else {
2040 xsh_msg_warning("bright_lines is NULL, order %d\n", ord);
2041 }
2042 } //end loop on orders
2043 /*copy the temporary vectors to the table (via the pointers set up earlier*/
2044 for (jj = 0; jj < cpl_table_get_nrow(tab_xy_guess); jj++) {
2045 if (yg_temp[jj] > 0.0) {
2046 pyg[jj] = yg_temp[jj];
2047 pxg[jj] = xg_temp[jj];
2048 }
2049 pyc[jj] = pyg[jj];
2050 pxc[jj] = pxg[jj];
2051 }
2052 //int nfit = 0;
2053 /*clear out table entries that were not matched to the real data*/
2054 check(cpl_table_and_selected_int(tab_xy_guess, "SELECT",
2055 CPL_GREATER_THAN, -1));
2056 check(tab_tmp = cpl_table_extract_selected(tab_xy_guess));
2057 xsh_free_table(&tab_xy_guess);
2058 check(cpl_table_erase_column(tab_tmp, "XC"));
2059 check(cpl_table_erase_column(tab_tmp, "YC"));
2060
2061 check(cpl_table_duplicate_column(tab_tmp, "XC", tab_tmp, "XF"));
2062 check(cpl_table_duplicate_column(tab_tmp, "YC", tab_tmp, "YF"));
2063
2064 check(cpl_table_save( tab_tmp, NULL, NULL, name_g, CPL_IO_DEFAULT));
2065 xsh_free_table(&tab_tmp);
2066
2067 } else { //peaks or pm methods
2068
2069 //Get parameters for linear extraction
2070 check(p = cpl_parameterlist_find(parameters, "xsh.xsh_cfg_recover.slit"));
2071 check(slit = cpl_parameter_get_int(p));
2072
2073 check(
2074 p = cpl_parameterlist_find(parameters,
2075 "xsh.xsh_cfg_recover.peak_factor"));
2076 check(fct = cpl_parameter_get_double(p));
2077
2078 check(
2079 p = cpl_parameterlist_find(parameters,
2080 "xsh.xsh_cfg_recover.peak_match_x"));
2081 check(thresh_x = cpl_parameter_get_int(p));
2082
2083 check(
2084 p = cpl_parameterlist_find(parameters,
2085 "xsh.xsh_cfg_recover.peak_match_y"));
2086 check(thresh_y = cpl_parameter_get_int(p));
2087
2088 check(
2089 p = cpl_parameterlist_find(parameters,
2090 "xsh.xsh_cfg_recover.ima_thresh_min"));
2091 check(thresh_min = cpl_parameter_get_double(p));
2092
2093 //Image (linear) extraction: sum pixels
2094 //to check the actual image we are going to fit vs the model guess
2095
2096 cknull(
2097 ima_ext = xsh_cfg_recover_linear_ext(raw_frm, order_tab_centr, instr,
2098 slit, thresh_min));
2099
2100
2101 cpl_table* tab_xy_trace=NULL;
2102 //Peaks image & table determination
2103 cknull(
2104 tab_xy_peaks = xsh_cfg_recover_measure_tab_xy_peaks(ima_ext,
2105 parameters));
2106 check(
2107 cpl_table_duplicate_column(tab_xy_peaks, "ABS_ORD", tab_xy_peaks,
2108 "REL_ORD"));
2109
2110 check(name_g = cpl_frame_get_filename(*guess));
2111 check(tab_xy_guess = cpl_table_load(name_g, 1, 0));
2112 xsh_msg("guess table name=%s", name_g);
2113
2114 check(name = cpl_frame_get_filename(order_tab_centr));
2115 check(tab_xy_trace = cpl_table_load(name, 1, 0));
2116 xsh_msg("Trace table name=%s", name);
2117 int ord_min = 0;
2118 check(ord_min = cpl_table_get_column_min(tab_xy_trace, "ABSORDER"));
2119 check(cpl_table_add_scalar(tab_xy_peaks, "ABS_ORD", ord_min));
2120
2121 if (debug_level > XSH_DEBUG_LEVEL_NONE) {
2122 check(cpl_table_save( tab_xy_peaks, NULL, NULL, name_t, CPL_IO_DEFAULT));
2123 }
2124
2125 check(
2126 xsh_cfg_recover_add_peaks_xpos(order_tab_centr, instr, &tab_xy_peaks));
2127
2128 if (debug_level > XSH_DEBUG_LEVEL_NONE) {
2129 check(cpl_table_save( tab_xy_peaks, NULL, NULL, name_t, CPL_IO_DEFAULT));
2130 }
2131
2132
2133 if (fct > 0) {
2134 //Table peaks selection
2135 xsh_msg("Peaks selection fct=%g", fct);
2136 cknull(
2137 tab_xy_peaks_sel = xsh_cfg_recover_select_peaks(tab_xy_guess,
2138 tab_xy_peaks, fct));
2139 } else {
2140 xsh_msg("No peaks selection");
2141 tab_xy_peaks_sel = cpl_table_duplicate(tab_xy_peaks);
2142 }
2143
2144 if (debug_level > XSH_DEBUG_LEVEL_NONE) {
2145 check(
2146 cpl_table_save(tab_xy_peaks_sel, NULL, NULL, "tab_xy_peaks_sel.fits",
2147 CPL_IO_DEFAULT));
2148 }
2149 //Line selection: pattern matching or simple box selection
2150 int ngue = 0;
2151 int npck = 0;
2152 if ((strcmp(method, "pm") == 0) || (strcmp(method, "manual") == 0)) {
2153 check(
2154 xsh_cfg_recover_prepare_pm_set(tab_xy_guess, tab_xy_peaks_sel,
2155 parameters, &mat_gue, &mat_msr, &use_pattern, &use_data));
2156
2157 check(
2158 xsh_cfg_recover_pattern_match(parameters, mat_gue, mat_msr,
2159 use_pattern, use_data, debug_level));
2160
2161 } else {
2162
2163 //peaks table cleaning
2164 xsh_msg("Remove blended lines");
2165 //Identify and remove lines peaks which are either
2166 //out of any box centered on
2167 //the line guess x-y position or that contain a neighboor
2168 //within the same box
2169 ngue = cpl_table_get_nrow(tab_xy_guess);
2170 npck = cpl_table_get_nrow(tab_xy_peaks_sel);
2171 if (ngue <= npck) {
2172 cknull(
2173 tab_xy_corr = xsh_cfg_recover_remove_blends(tab_xy_guess,
2174 tab_xy_peaks_sel, thresh_x, thresh_y));
2175
2176 if (debug_level > XSH_DEBUG_LEVEL_NONE) {
2177 check(
2178 cpl_table_save(tab_xy_corr, NULL, NULL, "tab_xy_corr.fits",
2179 CPL_IO_DEFAULT));
2180
2181 }
2182 } else {
2183 xsh_msg_error("Number og guess lines more than found peaks!");
2184 xsh_msg_error("Either increase factor ");
2185 xsh_msg_error("or choose a reference line table with less entries");
2186 return CPL_ERROR_ILLEGAL_INPUT;
2187 }
2188 }
2189 }
2190
2191 cleanup: if (trace != NULL) {
2192 for (ii = 0; ii < MAX_NO_ORD; ii++) {
2193 xsh_free_vector(&(trace[ii]));
2194 }
2195 cpl_free(trace);
2196 trace = NULL;
2197 }
2198
2199 if (extracted != NULL) {
2200 for (ii = 0; ii < MAX_NO_ORD; ii++) {
2201 xsh_free_vector(&(extracted[ii]));
2202 }
2203 cpl_free(extracted);
2204 extracted = NULL;
2205 }
2206
2207 xsh_free_frame(&spec_form_frame);
2208 xsh_free_table(&spec_form_tab);
2209 xsh_free_image(&ima);
2210 xsh_free_image(&ima_ext);
2211 xsh_free_table(&tab_xy_guess);
2212 xsh_free_table(&tab_xy_peaks);
2213 xsh_free_table(&tab_xy_peaks_sel);
2214 xsh_free_table(&tab_tmp);
2215 xsh_free_table(&tab_tmp1);
2216 xsh_free_table(&tab_tmp2);
2217 xsh_free_table(&tab_xy_corr);
2218 cpl_vector_delete(spec_clean);
2219 if (cpl_error_get_code() != CPL_ERROR_NONE) {
2221 }
2222 return cpl_error_get_code();
2223
2224}
2225
2226
2227/*--------------------------------------------------------------------------*/
2239/*--------------------------------------------------------------------------*/
2240
2241static cpl_error_code
2243 cpl_table* tab_dat,
2244 cpl_parameterlist* parameters,
2245 cpl_matrix** mat_pat,
2246 cpl_matrix** mat_dat,
2247 int* use_pat,
2248 int* use_dat)
2249
2250{
2251
2252 int npat=0;
2253 int ndat=0;
2254 int i=0;
2255
2256 double* pxd=NULL;
2257 double* pyd=NULL;
2258 double* pxg=NULL;
2259 double* pyg=NULL;
2260
2261 int* pog=NULL;
2262 int* pod=NULL;
2263 int* ps=NULL;
2264
2265 int ord_min=0;
2266 int ord_max=0;
2267 int ord_min_dat=0;
2268 int ord_max_dat=0;
2269
2270 int ord=0;
2271
2272 int ord_sel=5;
2273 cpl_parameter* p=NULL;
2274 cpl_table* pat=NULL;
2275 cpl_table* dat=NULL;
2276 cpl_table* tmp=NULL;
2277
2278 int j=0;
2279 double rad=0;
2280 double xmin=0;
2281 double xmax=0;
2282 double ymin=0;
2283 double ymax=0;
2284
2285 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.pm_ord_sel"));
2286 check(ord_sel = cpl_parameter_get_int(p));
2287
2288 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.pm_radius"));
2289 check(rad = cpl_parameter_get_double(p));
2290
2291
2292 check(npat=cpl_table_get_nrow(tab_pat));
2293 check(ndat=cpl_table_get_nrow(tab_dat));
2294
2295
2296 check(xsh_sort_table_1(tab_pat,"ABS_ORD",CPL_TRUE));
2297 check(xsh_sort_table_1(tab_dat,"ABS_ORD",CPL_TRUE));
2298
2299 check(pat=cpl_table_duplicate(tab_pat));
2300 check(cpl_table_new_column(pat,"SEL",CPL_TYPE_INT));
2301 check(cpl_table_fill_column_window(pat,"SEL",0,npat,-1));
2302
2303
2304 check(ps=cpl_table_get_data_int(pat,"SEL"));
2305 check(pog=cpl_table_get_data_int(pat,"ABS_ORD"));
2306
2307 check(ord_min=cpl_table_get_column_min(pat,"ABS_ORD"));
2308 check(ord_max=cpl_table_get_column_max(pat,"ABS_ORD"));
2309
2310
2311 check(ord_min_dat=cpl_table_get_column_min(tab_dat,"ABS_ORD"));
2312 check(ord_max_dat=cpl_table_get_column_max(tab_dat,"ABS_ORD"));
2313
2314 xsh_msg("pat min=%d max=%d",ord_min,ord_max);
2315 xsh_msg("dat min=%d max=%d",ord_min_dat,ord_max_dat);
2316
2317
2318 *use_pat=0;
2319
2320 //select starting pattern points
2321 for(ord=ord_min;ord<=ord_max;ord++) {
2322 for(i=0;i<npat;i++) {
2323 if((pog[i]==ord) && (j< ord_sel)) {
2324 ps[i]=1;
2325 j++;
2326 }
2327 }
2328 j=0;
2329 }
2330 check(*use_pat=cpl_table_and_selected_int(pat,"SEL",CPL_GREATER_THAN,0));
2331 check(tmp=cpl_table_extract_selected(pat));
2332 //PIPPO
2333 check(cpl_table_save(pat,NULL,NULL,"pat.fits",CPL_IO_DEFAULT));
2334
2335
2336 check(dat=cpl_table_duplicate(tab_dat));
2337 check(cpl_table_new_column(dat,"SEL",CPL_TYPE_INT));
2338 check(cpl_table_fill_column_window(dat,"SEL",0,ndat,-1));
2339 check(ps=cpl_table_get_data_int(dat,"SEL"));
2340
2341 check(pod=cpl_table_get_data_int(dat,"ABS_ORD"));
2342 check(pxd=cpl_table_get_data_double(dat,"XP"));
2343 check(pyd=cpl_table_get_data_double(dat,"YP"));
2344
2345 check(pog=cpl_table_get_data_int(tmp,"ABS_ORD"));
2346 check(pxg=cpl_table_get_data_double(tmp,"XC"));
2347 check(pyg=cpl_table_get_data_double(tmp,"YC"));
2348
2349 //select starting data points
2350 for(i=0;i<*use_pat;i++) {
2351 xmin=pxg[i]-rad;
2352 xmax=pxg[i]+rad;
2353 ymin=pyg[i]-rad;
2354 ymax=pyg[i]+rad;
2355 for(j=0;j<ndat;j++) {
2356 if( pog[i] == pod[j] ) {
2357 if(pxd[j] >= xmin && pxd[j] <= xmax) {
2358 if(pyd[j] >= ymin && pyd[j] <= ymax ) {
2359 ps[j]=1;
2360 }
2361 }
2362 }
2363 }
2364 }
2365 check(cpl_table_save(dat,NULL,NULL,"dat.fits",CPL_IO_DEFAULT));
2366 check(*use_dat=cpl_table_and_selected_int(dat,"SEL",CPL_GREATER_THAN,0));
2367
2368 xsh_msg("use_pattern=%d use_data=%d",*use_pat,*use_dat);
2369 if(*use_pat > *use_dat) {
2370 xsh_msg_error("You try to find a matching pattern searching ");
2371 xsh_msg_error("more points than available data. Try to increase ");
2372 xsh_msg_error("pm_radius and or peaks_factor ");
2373 xsh_msg_error("and/or decrease pm_ord_sel parameter values");
2374 goto cleanup;
2375 }
2376
2377 check(xsh_sort_table_1(dat,"SEL",CPL_TRUE));
2378 check(xsh_sort_table_1(pat,"SEL",CPL_TRUE));
2379 check(*mat_pat=cpl_matrix_new(2,npat));
2380 check(*mat_dat=cpl_matrix_new(2,ndat));
2381
2382 check(pxg=cpl_table_get_data_double(pat,"XC"));
2383 check(pyg=cpl_table_get_data_double(pat,"YC"));
2384 for(i=0;i<npat;i++) {
2385
2386 check(cpl_matrix_set(*mat_pat,0,i,pxg[i]));
2387 check(cpl_matrix_set(*mat_pat,1,i,pyg[i]));
2388
2389 }
2390
2391 check(pxd=cpl_table_get_data_double(dat,"XP"));
2392 check(pyd=cpl_table_get_data_double(dat,"YP"));
2393 for(i=0;i<ndat;i++) {
2394
2395 check(cpl_matrix_set(*mat_dat,0,i,pxd[i]));
2396 check(cpl_matrix_set(*mat_dat,1,i,pyd[i]));
2397
2398 }
2399
2400
2401 cleanup:
2402 xsh_free_table(&pat);
2403 xsh_free_table(&dat);
2404 xsh_free_table(&tmp);
2405
2406
2407 return cpl_error_get_code() ;
2408
2409}
2410
2411
2412/*--------------------------------------------------------------------------*/
2425/*--------------------------------------------------------------------------*/
2426
2427
2428static cpl_error_code
2429xsh_cfg_recover_pattern_match(cpl_parameterlist* parameters,
2430 cpl_matrix* mat_gue,
2431 cpl_matrix* mat_dat,
2432 int use_pattern,
2433 int use_data,
2434 int debug_level)
2435{
2436 cpl_array *matches = NULL;
2437
2438 double err_data=1;
2439 double err_pattern=0;
2440 double tolerance=0.1;
2441 double radius=1;
2442 cpl_matrix* mdata=NULL;
2443 cpl_matrix* mpattern=NULL;
2444 cpl_parameter* p=NULL;
2445 cpl_table* pm_tbl=NULL;
2446 cpl_table* dat_tbl=NULL;
2447 cpl_table*gue_tbl=NULL;
2448
2449 int nmatch=0;
2450 double* pcatx=NULL;
2451 double* pcaty=NULL;
2452 double* ppatx=NULL;
2453 double* ppaty=NULL;
2454 int i=0;
2455 int ndat=0;
2456 int ngue=0;
2457 double lin_scale=1.0;
2458 double lin_angle=0.0;
2459
2460
2461 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.pm_tolerance"));
2462 check(tolerance = cpl_parameter_get_double(p));
2463
2464 check(p = cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.pm_radius"));
2465 check(radius = cpl_parameter_get_double(p));
2466
2467
2468 //Monitor input data
2469 ndat=cpl_matrix_get_ncol(mat_dat);
2470 ngue=cpl_matrix_get_ncol(mat_gue);
2471
2472 check(dat_tbl=cpl_table_new(ndat));
2473 check(gue_tbl=cpl_table_new(ngue));
2474
2475 check(cpl_table_new_column(dat_tbl,"XD",CPL_TYPE_DOUBLE));
2476 check(cpl_table_new_column(dat_tbl,"YD",CPL_TYPE_DOUBLE));
2477 check(cpl_table_fill_column_window(dat_tbl,"XD",0,ndat,0));
2478 check(cpl_table_fill_column_window(dat_tbl,"YD",0,ndat,0));
2479 check(pcatx=cpl_table_get_data_double(dat_tbl,"XD"));
2480 check(pcaty=cpl_table_get_data_double(dat_tbl,"YD"));
2481
2482
2483
2484 for(i=0;i<ndat;i++) {
2485
2486 check(pcatx[i]=cpl_matrix_get(mat_dat,0,i));
2487 check(pcaty[i]=cpl_matrix_get(mat_dat,1,i));
2488
2489
2490 }
2491
2492 if(debug_level > XSH_DEBUG_LEVEL_NONE) {
2493 check(cpl_table_save(dat_tbl,NULL,NULL,"pm_dat.fits",CPL_IO_DEFAULT));
2494 }
2495
2496 check(cpl_table_new_column(gue_tbl,"XG",CPL_TYPE_DOUBLE));
2497 check(cpl_table_new_column(gue_tbl,"YG",CPL_TYPE_DOUBLE));
2498 check(cpl_table_fill_column_window(gue_tbl,"XG",0,ngue,0));
2499 check(cpl_table_fill_column_window(gue_tbl,"YG",0,ngue,0));
2500 check(ppatx=cpl_table_get_data_double(gue_tbl,"XG"));
2501 check(ppaty=cpl_table_get_data_double(gue_tbl,"YG"));
2502
2503
2504 for(i=0;i<ngue;i++) {
2505
2506 check(ppatx[i]=cpl_matrix_get(mat_gue,0,i));
2507 check(ppaty[i]=cpl_matrix_get(mat_gue,1,i));
2508
2509
2510 }
2511
2512 if(debug_level > XSH_DEBUG_LEVEL_NONE) {
2513 check(cpl_table_save(gue_tbl,NULL,NULL,"pm_gue.fits",CPL_IO_DEFAULT));
2514 }
2515 check(matches = cpl_ppm_match_points(mat_dat,use_data,err_data,
2516 mat_gue,use_pattern,err_pattern,
2517 tolerance,radius,&mdata, &mpattern,
2518 &lin_scale,&lin_angle));
2519
2520 check(nmatch=cpl_matrix_get_ncol(mpattern));
2521 xsh_msg("%d points matched linear scale factor=%f linear angle factor %f",
2522 nmatch,lin_scale,lin_angle);
2523
2524 check(pm_tbl=cpl_table_new(nmatch));
2525 check(cpl_table_new_column(pm_tbl,"PM_CAT_X",CPL_TYPE_DOUBLE));
2526 check(cpl_table_new_column(pm_tbl,"PM_CAT_Y",CPL_TYPE_DOUBLE));
2527 check(cpl_table_new_column(pm_tbl,"PM_PAT_X",CPL_TYPE_DOUBLE));
2528 check(cpl_table_new_column(pm_tbl,"PM_PAT_Y",CPL_TYPE_DOUBLE));
2529
2530 check(cpl_table_fill_column_window(pm_tbl,"PM_CAT_X",0,nmatch,0));
2531 check(cpl_table_fill_column_window(pm_tbl,"PM_CAT_Y",0,nmatch,0));
2532 check(cpl_table_fill_column_window(pm_tbl,"PM_PAT_X",0,nmatch,0));
2533 check(cpl_table_fill_column_window(pm_tbl,"PM_PAT_Y",0,nmatch,0));
2534
2535
2536 check(ppatx=cpl_table_get_data_double(pm_tbl,"PM_CAT_X"));
2537 check(ppaty=cpl_table_get_data_double(pm_tbl,"PM_CAT_Y"));
2538
2539 check(pcatx=cpl_table_get_data_double(pm_tbl,"PM_PAT_X"));
2540 check(pcaty=cpl_table_get_data_double(pm_tbl,"PM_PAT_Y"));
2541
2542 for(i=0;i<nmatch;i++) {
2543
2544 check(pcatx[i]=cpl_matrix_get(mdata,0,i));
2545 check(pcaty[i]=cpl_matrix_get(mdata,1,i));
2546
2547 check(ppatx[i]=cpl_matrix_get(mpattern,0,i));
2548 check(ppaty[i]=cpl_matrix_get(mpattern,1,i));
2549
2550
2551 }
2552
2553 if(debug_level > XSH_DEBUG_LEVEL_NONE) {
2554 check(cpl_table_save(pm_tbl,NULL,NULL,
2555 "pattern_match.fits",CPL_IO_DEFAULT));
2556 }
2557 xsh_free_table(&gue_tbl);
2558 xsh_free_table(&dat_tbl);
2559 xsh_free_table(&pm_tbl);
2560 xsh_free_array(&matches);
2561 xsh_free_matrix(&mpattern);
2562 xsh_free_matrix(&mdata);
2563
2564 cleanup:
2565 if(cpl_error_get_code() != CPL_ERROR_NONE) {
2566 xsh_msg("Try to increase pm_radius and/or peak_factor");
2567 }
2568 return cpl_error_get_code() ;
2569
2570}
2571
2572
2573
2574/*--------------------------------------------------------------------------*/
2583/*--------------------------------------------------------------------------*/
2584static cpl_error_code
2585xsh_cfg_recover_add_peaks_xpos(cpl_frame* order_tab_centr,
2586 xsh_instrument* instr,
2587 cpl_table** tab_xy_peaks)
2588{
2589
2590 xsh_order_list* order_list = NULL;
2591 int size=0;
2592 double* px=NULL;
2593 double* py=NULL;
2594 int* po=NULL;
2595 int ord_min=0;
2596 int ord_rel=0;
2597 //double pre_scan=50;
2598 //double over_scan=50;
2599 int i=0;
2600
2601 check(size=cpl_table_get_nrow(*tab_xy_peaks));
2602 check(cpl_table_new_column(*tab_xy_peaks,"XP",CPL_TYPE_DOUBLE));
2603 check(cpl_table_fill_column_window(*tab_xy_peaks,"XP",0,size,-1));
2604
2605 check(px=cpl_table_get_data_double(*tab_xy_peaks,"XP"));
2606 check(py=cpl_table_get_data_double(*tab_xy_peaks,"YP"));
2607 check(po=cpl_table_get_data_int(*tab_xy_peaks,"ABS_ORD"));
2608 ord_min=cpl_table_get_column_min(*tab_xy_peaks,"ABS_ORD");
2609
2610 check(order_list = xsh_order_list_load(order_tab_centr,instr));
2611
2612 //xsh_msg("size=%d",size);
2613 for(i=0;i<size;i++) {
2614 //xsh_msg("abs order=%d",po[i]);
2615 check( ord_rel = xsh_order_list_get_order( order_list, po[i] ) ) ;
2616 //xsh_msg("rel order=%d",ord_rel);
2617 ord_rel=po[i]-ord_min;
2618 //xsh_msg("rel order=%d",ord_rel);
2619
2620 //xsh_msg("size-1=%d",order_list->size-1);
2621 if(cpl_polynomial_get_dimension(order_list->list[ord_rel].cenpoly) <
2623
2624 check( px[i] = cpl_polynomial_eval_1d(
2625 order_list->list[ord_rel].cenpoly,py[i],NULL));
2626 }
2627 // order_list->list[order_list->size-1].cenpoly,py[i],NULL));
2628 //xsh_msg("y=%f xfit+prescan=%f",py[i], pxc[i]);
2629 //xsh_msg("y=%f x=%f",py[i], px[i]);
2630 }
2631
2632 cleanup:
2633 xsh_order_list_free(&order_list);
2634
2635 return cpl_error_get_code();
2636
2637
2638}
2639
2640/*--------------------------------------------------------------------------*/
2651/*--------------------------------------------------------------------------*/
2652
2653static cpl_table*
2654xsh_cfg_recover_remove_blends(cpl_table* tab_xy_guess,
2655 cpl_table* tab_xy_peaks_sel,
2656 const int thresh_x,
2657 const int thresh_y)
2658{
2659
2660 //double* pxg=NULL;
2661 //double* pyg=NULL;
2662 double* pyt=NULL;
2663 double* pyp=NULL;
2664
2665 double* pxt=NULL;
2666 double* pxp=NULL;
2667 int* pwp=NULL;
2668 int* pap=NULL;
2669 int* prp=NULL;
2670
2671
2672
2673 double* pxr=NULL;
2674 double* pyr=NULL;
2675 int* pwr=NULL;
2676 int* par=NULL;
2677 int* prr=NULL;
2678
2679 double x=0;
2680 double y=0;
2681 int r=0;
2682 int a=0;
2683 int w=0;
2684
2685
2686 int ord=0;
2687 int ord_min=0;
2688 int ord_max=0;
2689 int nord=0;
2690 int npks=0;
2691 cpl_table* tab_tmp=NULL;
2692 cpl_table* tab_tmp1=NULL;
2693 cpl_table* tab_tmp2=NULL;
2694
2695 cpl_table* result=NULL;
2696 int found=0;
2697 int i=0;
2698 int j=0;
2699
2700 int k=0;
2701 int nrows=0;
2702
2703 //pxg=cpl_table_get_data_double(tab_xy_guess,"XC");
2704 //pyg=cpl_table_get_data_double(tab_xy_guess,"YC");
2705 ord_min=cpl_table_get_column_min(tab_xy_guess,"ABS_ORD");
2706 ord_max=cpl_table_get_column_max(tab_xy_guess,"ABS_ORD");
2707
2708 check(tab_tmp2=cpl_table_duplicate(tab_xy_peaks_sel));
2709 check(nrows=cpl_table_get_nrow(tab_tmp2));
2710 check(cpl_table_fill_column_window(tab_tmp2,"YP",0,nrows,-1));
2711 check(cpl_table_fill_column_window(tab_tmp2,"XP",0,nrows,-1));
2712 check(cpl_table_fill_column_window(tab_tmp2,"REL_ORD",0,nrows,-1));
2713 check(cpl_table_fill_column_window(tab_tmp2,"ABS_ORD",0,nrows,-1));
2714 check(cpl_table_fill_column_window(tab_tmp2,"WEIGHT",0,nrows,-1));
2715
2716 check(pxr=cpl_table_get_data_double(tab_tmp2,"XP"));
2717 check(pyr=cpl_table_get_data_double(tab_tmp2,"YP"));
2718 check(prr=cpl_table_get_data_int(tab_tmp2,"REL_ORD"));
2719 check(pwr=cpl_table_get_data_int(tab_tmp2,"WEIGHT"));
2720 check(par=cpl_table_get_data_int(tab_tmp2,"ABS_ORD"));
2721 //xsh_msg("nrows=%d",nrows);
2722 for(ord=ord_min;ord<=ord_max;ord++) {
2723 check(nord=cpl_table_and_selected_int(tab_xy_guess,"ABS_ORD",
2724 CPL_EQUAL_TO,ord));
2725 check(npks=cpl_table_and_selected_int(tab_xy_peaks_sel,"ABS_ORD",
2726 CPL_EQUAL_TO,ord));
2727 xsh_free_table(&tab_tmp);
2728 check(tab_tmp=cpl_table_extract_selected(tab_xy_guess));
2729 xsh_free_table(&tab_tmp1);
2730 check(tab_tmp1=cpl_table_extract_selected(tab_xy_peaks_sel));
2731
2732 pxt=cpl_table_get_data_double(tab_tmp,"XC");
2733 pyt=cpl_table_get_data_double(tab_tmp,"YC");
2734
2735 pxp=cpl_table_get_data_double(tab_tmp1,"XP");
2736 pyp=cpl_table_get_data_double(tab_tmp1,"YP");
2737 prp=cpl_table_get_data_int(tab_tmp1,"REL_ORD");
2738 pwp=cpl_table_get_data_int(tab_tmp1,"WEIGHT");
2739 pap=cpl_table_get_data_int(tab_tmp1,"ABS_ORD");
2740 //xsh_msg("ord=%d nord=%d npks=%d",ord,nord,npks);
2741
2742 for(i=0;i<nord;i++) {
2743 found=0;
2744 for(j=0;j<npks;j++) {
2745 //xsh_msg("dist=%f thresh=%d",fabs(pyp[j]-pyt[i]),thresh_y);
2746 if((fabs(pxp[j]-pxt[i]) < thresh_x) &&
2747 (fabs(pyp[j]-pyt[i]) < thresh_y)) {
2748 found++;
2749 r=prp[j];
2750 w=pwp[j];
2751 a=pap[j];
2752 x=pxp[j];
2753 y=pyp[j];
2754
2755 }
2756 }
2757 if(found==1) {
2758 pxr[k]=x;
2759 pyr[k]=y;
2760 prr[k]=r;
2761 pwr[k]=w;
2762 par[k]=a;
2763 k++;
2764 //xsh_msg("ord=%d found=%d k=%d",ord,found,k);
2765 }
2766 }
2767 check(cpl_table_select_all(tab_xy_peaks_sel));
2768 check(cpl_table_select_all(tab_xy_guess));
2769 }
2770
2771 check(cpl_table_and_selected_int(tab_tmp2,"REL_ORD",CPL_GREATER_THAN,-1));
2772 check(result=cpl_table_extract_selected(tab_tmp2));
2773 check(cpl_table_name_column(result,"XP","XC"));
2774 check(cpl_table_name_column(result,"YP","YC"));
2775
2776 cleanup:
2777 xsh_free_table(&tab_tmp);
2778 xsh_free_table(&tab_tmp1);
2779 xsh_free_table(&tab_tmp2);
2780
2781
2782 if (cpl_error_get_code() != CPL_ERROR_NONE) {
2783 return NULL;
2784 } else {
2785 return result;
2786 }
2787
2788}
2789
2790/*--------------------------------------------------------------------------*/
2800/*--------------------------------------------------------------------------*/
2801
2802static cpl_table*
2803xsh_cfg_recover_select_peaks(cpl_table* tab_xy_guess,
2804 cpl_table* tab_xy_peaks,
2805 const double factor)
2806{
2807
2808
2809 int ord=0;
2810 int nord=0;
2811 int ord_min=0;
2812 int ord_max=0;
2813 int ord_min_peaks=0;
2814 int ord_max_peaks=0;
2815 int ord_min_guess=0;
2816 int ord_max_guess=0;
2817
2818 int npks=0;
2819 cpl_table* tab_tmp=NULL;
2820 cpl_table* tab_tmp1=NULL;
2821 cpl_table* result=NULL;
2822 int weight_min=0;
2823 int nrows=0;
2824
2825 check(ord_min_guess=cpl_table_get_column_min(tab_xy_guess,"ABS_ORD"));
2826 check(ord_max_guess=cpl_table_get_column_max(tab_xy_guess,"ABS_ORD"));
2827
2828 check(ord_min_peaks=cpl_table_get_column_min(tab_xy_peaks,"ABS_ORD"));
2829 check(ord_max_peaks=cpl_table_get_column_max(tab_xy_peaks,"ABS_ORD"));
2830 ord_min=(ord_min_guess<=ord_min_peaks) ? ord_min_guess : ord_min_peaks;
2831 ord_max=(ord_max_guess>=ord_max_peaks) ? ord_max_guess : ord_max_peaks;
2832
2833 cpl_table_select_all(tab_xy_peaks);
2834
2835 xsh_msg("select lines in order range=[%d,%d]",ord_min,ord_max);
2836 //select the line peak sub table having for each order as many entries
2837 //as in the input table line list. Those are the brighest lines
2838 for(ord=ord_min;ord<=ord_max;ord++) {
2839
2840 nord=cpl_table_and_selected_int(tab_xy_guess,"ABS_ORD",CPL_EQUAL_TO,ord);
2841 npks=cpl_table_and_selected_int(tab_xy_peaks,"ABS_ORD",CPL_EQUAL_TO,ord);
2842 check(tab_tmp=cpl_table_extract_selected(tab_xy_peaks));
2843 //xsh_msg("ord=%d nord=%d npks=%d",ord,nord,npks);
2844 if(npks>nord) {
2845 weight_min=cpl_table_get_column_min(tab_tmp,"WEIGHT");
2846 check(npks=cpl_table_and_selected_int(tab_tmp,"WEIGHT",
2847 CPL_NOT_GREATER_THAN,
2848 (int)(weight_min+factor*nord)));
2849 tab_tmp1=cpl_table_extract_selected(tab_tmp);
2850 //xsh_msg("ord=%d nord=%d weight_min=%d thresh=%d npks=%d",
2851 // ord,nord,weight_min,(int)(weight_min+factor*nord),npks);
2852
2853 } else {
2854 tab_tmp1=cpl_table_duplicate(tab_tmp);
2855 }
2856 if(ord == ord_min) {
2857 result=cpl_table_duplicate(tab_tmp1);
2858 } else {
2859 nrows=cpl_table_get_nrow(tab_xy_peaks);
2860 cpl_table_insert(result,tab_tmp1,nrows);
2861 }
2862
2863 xsh_free_table(&tab_tmp1);
2864 xsh_free_table(&tab_tmp);
2865 cpl_table_select_all(tab_xy_peaks);
2866 cpl_table_select_all(tab_xy_guess);
2867 }
2868
2869 cleanup:
2870 xsh_free_table(&tab_tmp1);
2871 xsh_free_table(&tab_tmp);
2872
2873 if (cpl_error_get_code() != CPL_ERROR_NONE) {
2874 return NULL;
2875 } else {
2876 return result;
2877 }
2878
2879
2880}
2881
2882
2883/*--------------------------------------------------------------------------*/
2892/*--------------------------------------------------------------------------*/
2893static cpl_table*
2895 cpl_parameterlist* parameters)
2896{
2897
2898 const char* name_p="ima_peaks.fits";
2899 const int size=5000;
2900 cpl_table* result=NULL;
2901 cpl_propertylist* plist=NULL;
2902 double* pp=NULL;
2903 int* po=NULL;
2904 int row=0;
2905 int ord=0;
2906 int ord_num=0;
2907
2908 double* pv=NULL;
2909 int sv=0;
2910 int* pw=NULL;
2911 int nrows=0;
2912 cpl_vector* spectrum=NULL;
2913 cpl_vector* peaks=NULL;
2914 int display=0;
2915 int line_fwhm=4;
2916 double kappa=5;
2917 cpl_parameter* p=NULL;
2918 int i=0;
2919 cpl_table* tab_tmp=NULL;
2920 int debug_level=0;
2921 char ext_val[10];
2922
2923 check(p=cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.plot"));
2924 check(display = cpl_parameter_get_bool(p));
2925
2926 check(p=cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.peak_line_fwhm"));
2927 check(line_fwhm = cpl_parameter_get_int(p));
2928
2929 check(p=cpl_parameterlist_find(parameters,"xsh.xsh_cfg_recover.peak_kappa"));
2930 check(kappa = cpl_parameter_get_double(p));
2931 check(debug_level=xsh_parameters_debug_level_get("xsh_cfg_recover",parameters));
2932 ord_num=cpl_image_get_size_y(ima_ext);
2933
2934 result=cpl_table_new(size);
2935 cpl_table_new_column(result,"YP",CPL_TYPE_DOUBLE);
2936 cpl_table_new_column(result,"REL_ORD",CPL_TYPE_INT);
2937 check(cpl_table_fill_column_window(result,"YP",0,size,-1));
2938 check(cpl_table_fill_column_window(result,"REL_ORD",0,size,-1));
2939
2940 pp=cpl_table_get_data_double(result,"YP");
2941 po=cpl_table_get_data_int(result,"REL_ORD");
2942
2943 row=0;
2944 for(ord=0;ord<ord_num;ord++) {
2945 check(spectrum=cpl_vector_new_from_image_row(ima_ext,ord+1));
2946 check(peaks=xsh_spectrum_detect_peaks(spectrum,line_fwhm,kappa,display));
2947 if(debug_level>XSH_DEBUG_LEVEL_NONE) {
2948 plist=cpl_propertylist_new();
2949 sprintf(ext_val,"%s%d","ext",ord);
2950 cpl_propertylist_append_string(plist,"EXTNAME",ext_val);
2951 if(ord==0) {
2952 cpl_vector_save(spectrum,name_p,CPL_BPP_IEEE_FLOAT,plist,
2953 CPL_IO_DEFAULT);
2954 } else {
2955 cpl_vector_save(spectrum,name_p,CPL_BPP_IEEE_FLOAT,
2956 plist,CPL_IO_EXTEND);
2957 }
2958 xsh_free_propertylist(&plist);
2959 }
2960 if(peaks!=NULL) {
2961 check(sv=cpl_vector_get_size(peaks));
2962 if (sv>0) {
2963 check(pv=cpl_vector_get_data(peaks));
2964 for(i=0;i<sv;i++) {
2965 po[row]=ord;
2966 pp[row]=pv[i];
2967 row++;
2968 }
2969 }
2970 }
2971 xsh_free_vector(&spectrum);
2972 xsh_free_vector(&peaks);
2973 }
2974 check(cpl_table_and_selected_double(result,"YP",CPL_GREATER_THAN,-1));
2975 check(tab_tmp=cpl_table_extract_selected(result));
2976 xsh_free_table(&result);
2977 result=cpl_table_duplicate(tab_tmp);
2978 xsh_free_table(&tab_tmp);
2979
2980 check(cpl_table_erase_invalid_rows(result));
2981
2982 cpl_table_new_column(result,"WEIGHT",CPL_TYPE_INT);
2983 nrows=cpl_table_get_nrow(result);
2984 xsh_msg("size=%d",size);
2985 check(cpl_table_fill_column_window(result,"WEIGHT",0,size,-1));
2986 check(pw=cpl_table_get_data_int(result,"WEIGHT"));
2987
2988 for(i=0;i<nrows;i++) {
2989 pw[i]=i;
2990 }
2991
2992 cleanup:
2993 xsh_free_table(&tab_tmp);
2994 xsh_free_vector(&spectrum);
2995 xsh_free_vector(&peaks);
2996
2997 if (cpl_error_get_code() != CPL_ERROR_NONE) {
2998 return NULL;
2999 } else {
3000 return result;
3001 }
3002
3003}
3004
3005
3006/*--------------------------------------------------------------------------*/
3018/*--------------------------------------------------------------------------*/
3019static cpl_image*
3020xsh_cfg_recover_linear_ext(cpl_frame* raw_frm,
3021 cpl_frame* order_tab_centr,
3022 xsh_instrument* instr,
3023 const int slit,
3024 const double min)
3025
3026{
3027 const char* name=NULL;
3028 cpl_image* input=NULL;
3029
3030 const char* name_o="ima_raw.fits";
3031 const char* name_e="ima_ext.fits";
3032 int sx=0;
3033 int sy=0;
3034 int ord_num=0;
3035 int ord_min_tra=0;
3036 int ord_max_tra=0;
3037
3038 int ord=0;
3039
3040 cpl_image* result=NULL;
3041 double* pou=NULL;
3042 double* pin=NULL;
3043 int i=0;
3044 int j=0;
3045 double x=0;
3046 int s=0;
3047 double flux=0;
3048 int pix=0;
3049 xsh_order_list* order_list = NULL;
3050 cpl_table* tab_centr=NULL;
3051
3052 check(name=cpl_frame_get_filename(raw_frm));
3053 check(input=cpl_image_load(name,CPL_TYPE_DOUBLE,0,0));
3054 check(cpl_image_threshold(input,min,FLT_MAX,0,FLT_MAX));
3055 check(cpl_image_save(input,name_o,CPL_BPP_IEEE_FLOAT,NULL,
3056 CPL_IO_DEFAULT));
3057
3058 xsh_msg("extracting image %s",name_o);
3059
3060 check(sx=cpl_image_get_size_x(input));
3061 check(sy=cpl_image_get_size_y(input));
3062 check(name=cpl_frame_get_filename( order_tab_centr));
3063 check(tab_centr=cpl_table_load(name,1,0));
3064
3065 ord_min_tra=cpl_table_get_column_min(tab_centr,"ABSORDER");
3066 ord_max_tra=cpl_table_get_column_max(tab_centr,"ABSORDER");
3067 xsh_free_table(&tab_centr);
3068
3069 ord_num=ord_max_tra-ord_min_tra+1;
3070
3071 // allocates output image
3072 check(result=cpl_image_new(sy,ord_num,CPL_TYPE_DOUBLE));
3073 check(pou=cpl_image_get_data_double(result));
3074 check(pin=cpl_image_get_data_double(input));
3075
3076 // we get the polynomials to follow the order traces during extraction
3077 check(order_list = xsh_order_list_load(order_tab_centr,instr));
3078 // average extraction
3079
3080 //xsh_msg("ord_num=%d sx=%d sy=%d",ord_num,sx,sy);
3081 // do the linear extraction
3082 for(ord=0;ord<ord_num;ord++) {
3083 for(j=0;j<sy;j++) {
3084 flux=0;
3085 if(cpl_polynomial_get_dimension(order_list->list[ord].cenpoly) <
3087 check(x=cpl_polynomial_eval_1d(order_list->list[ord].cenpoly,j,NULL));
3088 //xsh_msg("%d %ld",j,x);
3089 }
3090 i=(int)(x+0.5);
3091 for(s=-slit;s<=slit;s++) {
3092 pix=j*sx+i+s;
3093 if ( (pix>0) && (pix<sx*sy) ) {
3094 flux+=pin[pix];
3095 //xsh_msg("i=%d j=%d flux=%f",i,j,flux);
3096 }
3097 }
3098 pou[ord*sy+j]=flux;
3099 }
3100 }
3101
3102
3103 check(cpl_image_save(result,name_e,CPL_BPP_IEEE_FLOAT,NULL,
3104 CPL_IO_DEFAULT));
3105
3106 cleanup:
3107 xsh_free_image(&input);
3108 xsh_free_table(&tab_centr);
3109 xsh_order_list_free( &order_list ) ;
3110
3111 if (cpl_error_get_code() != CPL_ERROR_NONE) {
3112 return NULL;
3113 } else {
3114 return result;
3115 }
3116
3117}
3118
3119/*--------------------------------------------------------------------------*/
3130/*--------------------------------------------------------------------------*/
3131static cpl_error_code
3133 cpl_frame* order_tab_centr,
3134 cpl_frame** model_xy_gue) {
3135
3136 cpl_table* tab_xy_guess=NULL;
3137 xsh_order_list* order_list = NULL;
3138 int size=0;
3139 double* pxc=NULL;
3140 double* pyc=NULL;
3141 double* px=NULL;
3142 double* py=NULL;
3143 int* pog=NULL;
3144 int* por=NULL;
3145 int* poa=NULL;
3146 int ord_min_tra=0;
3147 int ord_max_tra=0;
3148
3149 int ord_min_gue=0;
3150 int ord_max_gue=0;
3151 int ord_min_off=0;
3152 int ord_max_off=0;
3153
3154 int ord_rel=0;
3155 //double pre_scan=50;
3156 //double over_scan=50;
3157
3158 const char* name_c=NULL;
3159 const char* name_g=NULL;
3160 int i=0;
3161 cpl_table * tab_centr=NULL;
3162 int sizey=4096;
3163 int j=0;
3164 int ord=0;
3165 int nord=0;
3166
3167 check(name_g=cpl_frame_get_filename(*model_xy_gue));
3168 //xsh_msg("model guesses file=%s",name_g);
3169 check(tab_xy_guess=cpl_table_load(name_g,1,0));
3170
3171 check(size=cpl_table_get_nrow(tab_xy_guess));
3172 check(cpl_table_new_column(tab_xy_guess,"XC",CPL_TYPE_DOUBLE));
3173 check(cpl_table_new_column(tab_xy_guess,"YC",CPL_TYPE_DOUBLE));
3174 check(cpl_table_fill_column_window(tab_xy_guess,"XC",0,size,-1));
3175 check(cpl_table_fill_column_window(tab_xy_guess,"YC",0,size,-1));
3176
3177 check(pxc=cpl_table_get_data_double(tab_xy_guess,"XC"));
3178 check(pyc=cpl_table_get_data_double(tab_xy_guess,"YC"));
3179 check(px=cpl_table_get_data_double(tab_xy_guess,"XG"));
3180 check(py=cpl_table_get_data_double(tab_xy_guess,"YG"));
3181 check(pog=cpl_table_get_data_int(tab_xy_guess,"ABS_ORD"));
3182 check(ord_min_gue=cpl_table_get_column_min(tab_xy_guess,"ABS_ORD"));
3183 check(ord_max_gue=cpl_table_get_column_max(tab_xy_guess,"ABS_ORD"));
3184
3185 if (order_tab_centr!=NULL) {
3186 name_c=cpl_frame_get_filename(order_tab_centr);
3187 xsh_msg("tab centre file=%s",name_c);
3188 check(tab_centr=cpl_table_load(name_c,1,0));
3189 check(ord_min_tra=cpl_table_get_column_min(tab_centr,"ABSORDER"));
3190 check(ord_max_tra=cpl_table_get_column_max(tab_centr,"ABSORDER"));
3191 xsh_free_table(&tab_centr);
3192
3193
3194 xsh_msg("Trace tab order min=%d max=%d",ord_min_tra,ord_max_tra);
3195 check(order_list = xsh_order_list_load(order_tab_centr,instr));
3196 xsh_msg("Guess tab order min=%d max=%d",ord_min_gue,ord_max_gue);
3197 ord_min_off=ord_min_gue-ord_min_tra;
3198 ord_max_off=ord_max_gue-ord_max_tra;
3199 xsh_msg_debug("offset ord min=%d",ord_min_off);
3200 xsh_msg_debug("offset ord max=%d",ord_max_off);
3201
3202 if(ord_min_off!=0) {
3203 xsh_msg_error("The guess line table has lines in an order not traced");
3204 xsh_msg_error("Remove lines from guess at order %d",ord_min_gue);
3205 xsh_msg_error("Or allow xsh_orderpos to trace order %d",ord_min_gue);
3206 xsh_msg_error("(For example changing XSH_SPECTRALFORMAT_TABLE_arm");
3207 cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
3208 goto cleanup;
3209 }
3210
3211 xsh_msg_debug("size=%d ord_min_gue=%d ord_max_gue=%d",
3212 size,ord_min_gue,ord_max_gue);
3213
3214 for(i=0;i<size;i++) {
3215 pyc[i]=py[i];
3216 //xsh_msg("pyc=%f",pyc[i]);
3217 //xsh_msg("abs order=%d",pog[i]);
3218 check( ord_rel = xsh_order_list_get_order( order_list, pog[i] ) ) ;
3219 //xsh_msg("rel order=%d",ord_rel);
3220 ord_rel=pog[i]-ord_min_gue+ord_min_off;
3221 //xsh_msg("rel order=%d",ord_rel);
3222
3223 //xsh_msg("size-1=%d",order_list->size-1);
3224 if(ord_rel>-1) {
3225 if(cpl_polynomial_get_dimension(order_list->list[ord_rel].cenpoly) <
3227 check( pxc[i] = cpl_polynomial_eval_1d(order_list->list[ord_rel].cenpoly,py[i],NULL));
3228 }
3229 }
3230 // order_list->list[order_list->size-1].cenpoly,py[i],NULL));
3231 //xsh_msg("y=%f xfit+prescan=%f",py[i], pxc[i]);
3232 //xsh_msg("y=%f x=%f",py[i], px[i]);
3233 }
3234
3235
3236 //For quality control we also generate ORDER, X and Y columns
3237 //in order tab centres to be compared with the ones of the guess table
3238 nord=ord_max_tra-ord_min_tra+1;
3239 size=nord*sizey;
3240 check(tab_centr=cpl_table_new(nord*sizey));
3241 check(cpl_table_new_column(tab_centr,"X",CPL_TYPE_DOUBLE));
3242 check(cpl_table_new_column(tab_centr,"Y",CPL_TYPE_DOUBLE));
3243 check(cpl_table_new_column(tab_centr,"ORDER",CPL_TYPE_INT));
3244 check(cpl_table_new_column(tab_centr,"ABSORDER",CPL_TYPE_INT));
3245 check(cpl_table_fill_column_window(tab_centr,"X",0,size,-1));
3246 check(cpl_table_fill_column_window(tab_centr,"Y",0,size,-1));
3247 check(cpl_table_fill_column_window(tab_centr,"ORDER",0,size,-1));
3248 check(cpl_table_fill_column_window(tab_centr,"ABSORDER",0,size,-1));
3249 check(px=cpl_table_get_data_double(tab_centr,"X"));
3250 check(py=cpl_table_get_data_double(tab_centr,"Y"));
3251 check(por=cpl_table_get_data_int(tab_centr,"ORDER"));
3252 check(poa=cpl_table_get_data_int(tab_centr,"ABSORDER"));
3253
3254
3255 i=0;
3256 for(ord=0;ord<nord;ord++) {
3257 for(j=0;j<sizey;j++) {
3258
3259 poa[i]=ord+ord_min_tra;
3260 por[i]=ord+1;
3261 py[i]=(double)j;
3262 check(px[i]=cpl_polynomial_eval_1d(order_list->list[ord].cenpoly,py[i],
3263 NULL));
3264 i++;
3265 }
3266 }
3267 check(cpl_table_save(tab_centr,NULL,NULL,"tab_centr.fits",CPL_IO_DEFAULT));
3268
3269 }
3270 check(cpl_table_save(tab_xy_guess, NULL, NULL, name_g, CPL_IO_DEFAULT));
3271
3272 cleanup:
3273
3274 xsh_free_table(&tab_centr);
3275 xsh_free_table(&tab_xy_guess);
3276 xsh_order_list_free( &order_list);
3277 if(cpl_error_get_code() != CPL_ERROR_NONE) {
3279 }
3280 return cpl_error_get_code();
3281
3282}
3283
3284/*--------------------------------------------------------------------------*/
3293/*--------------------------------------------------------------------------*/
3294static cpl_frame*
3295xsh_cfg_recover_gen_xyg_frame(cpl_frame * wave_list,
3296 cpl_frame * config_frame,
3297 xsh_instrument* inst, int prescan)
3298{
3299
3300 cpl_table* lines_tab=NULL ;
3301 cpl_frame* result=NULL;
3302 struct xs_3* p_xs_3_config=NULL;
3303 struct xs_3 xs_3_config;
3304 cpl_table* lines_xyg=NULL;
3305 cpl_propertylist* header=NULL;
3306 char name_o[256];
3307 const char* tag=XSH_GET_TAG_FROM_ARM(XSH_MODEL_GUESS_XY,inst);
3308
3309 sprintf(name_o,"%s%s",tag,".fits");
3310
3311 //Load xsh model configuration
3312
3313 p_xs_3_config=&xs_3_config;
3314 if (xsh_model_config_load_best(config_frame, p_xs_3_config) !=
3315 CPL_ERROR_NONE) {
3316 xsh_msg_error("Cannot load %s as a config",
3317 cpl_frame_get_filename(config_frame)) ;
3318 return NULL ;
3319 }
3320
3321 /* Read the input FITS lines list */
3322 check(lines_tab = cpl_table_load(cpl_frame_get_filename(wave_list), 1, 0)) ;
3323
3324 //Generate x-y model guess
3325 check(xsh_cfg_recover_gen_xyg(lines_tab,p_xs_3_config,inst,prescan,&lines_xyg));
3326 //int i;
3327
3328 // saves the table for debug purposes
3329 header=cpl_propertylist_new();
3330 check( xsh_pfits_set_pcatg(header,tag));
3331 cpl_table_save(lines_xyg, header, NULL,name_o, CPL_IO_DEFAULT);
3332
3333 //Saves the frame as a final product.
3334 result=xsh_frame_product(name_o,tag,CPL_FRAME_TYPE_TABLE,
3335 CPL_FRAME_GROUP_PRODUCT,
3336 CPL_FRAME_LEVEL_FINAL);
3337 cpl_error_reset();
3338
3339 cleanup:
3340 xsh_free_propertylist(&header);
3341 xsh_free_table(&lines_tab);
3342 xsh_free_table(&lines_xyg);
3343
3344
3345 if (cpl_error_get_code() != CPL_ERROR_NONE) {
3346 return NULL;
3347 } else {
3348 return result;
3349 }
3350
3351}
3352
3353/*--------------------------------------------------------------------------*/
3364/*--------------------------------------------------------------------------*/
3365
3366static cpl_error_code
3368 cpl_table * lines_tab,
3369 struct xs_3* p_xs_3_config,
3370 xsh_instrument* inst,int pre_scan,
3371 cpl_table ** lines_xyg)
3372{
3373 double x,y;
3374 float* pw=NULL;
3375 int row=0;
3376
3377 int i=0;
3378 double blaze_wav=0;
3379 double lambda_min=0;
3380 double lambda_max=0;
3381 int morder_cnt=0;
3382 double m_to_mu=1.e6; //conversion meter to microns
3383 int lines_tot;
3384 int prescan=0; //50
3385 if(pre_scan) {
3386 prescan=-50;
3387 }
3388 lines_tot = cpl_table_get_nrow(lines_tab) ;
3389 xsh_msg("lines_tot=%d",lines_tot);
3390 *lines_xyg = cpl_table_new(lines_tot*3);
3391 cpl_table_new_column(*lines_xyg,"WAVELENGTH",CPL_TYPE_DOUBLE);
3392 cpl_table_new_column(*lines_xyg,"XG",CPL_TYPE_DOUBLE);
3393 cpl_table_new_column(*lines_xyg,"YG",CPL_TYPE_DOUBLE);
3394 cpl_table_new_column(*lines_xyg,"ABS_ORD",CPL_TYPE_INT);
3395
3396 pw=cpl_table_get_data_float(lines_tab,"WAVELENGTH");
3397 xsh_msg("order min:%d max: %d",
3398 p_xs_3_config->morder_min,p_xs_3_config->morder_max);
3399
3400 for(i=0;i<lines_tot;i++) {
3401 for (morder_cnt= p_xs_3_config->morder_min;
3402 morder_cnt<=p_xs_3_config->morder_max;
3403 morder_cnt++) {
3404 blaze_wav=2*(sin(-p_xs_3_config->nug))/(morder_cnt*p_xs_3_config->sg);
3405 lambda_max=blaze_wav*((double)(morder_cnt)/((double)(morder_cnt)-0.5));
3406 lambda_min=blaze_wav*((double)(morder_cnt)/(0.5+(double)(morder_cnt)));
3407 lambda_min *=m_to_mu;
3408 lambda_max *=m_to_mu;
3409
3410 //xsh_msg("wave= %f range=[%f,%f]",pw[i],lambda_min,lambda_max);
3411 if(pw[i]> lambda_min*0.98 && pw[i]<1.02*lambda_max) {
3412 check(xsh_model_get_xy(p_xs_3_config,inst,pw[i],
3413 morder_cnt,0.0,&x,&y));
3414 //xsh_msg("At wave %lf nm in order %d on arm %d : x=%lf y=%lf \n",
3415 // pw[i],morder_cnt,xsh_instrument_get_arm(inst),x,y);
3416 cpl_table_set_double(*lines_xyg,"WAVELENGTH",row,pw[i]);
3417 cpl_table_set_int(*lines_xyg,"ABS_ORD",row,morder_cnt);
3418 cpl_table_set_double(*lines_xyg,"XG",row,x-prescan);
3419 cpl_table_set_double(*lines_xyg,"YG",row,y);
3420 row++;
3421 }
3422 }
3423 }
3424/* cpl_table_unselect_all(*lines_xyg); */
3425/* for (i=0;i<lines_tot*3;i++) { */
3426/* if (cpl_table_get_int(*lines_xyg,"ABS_ORD",i,NULL)==0) { */
3427/* cpl_table_select_row(*lines_xyg,i); */
3428/* } */
3429/* else { */
3430/* cpl_table_unselect_row(*lines_xyg,i); */
3431/* } */
3432/* } */
3433/* cpl_table_erase_selected(*lines_xyg); */
3434
3435 cpl_table_erase_invalid(*lines_xyg);
3436
3437 xsh_msg("lines inc. overlap: %" CPL_SIZE_FORMAT "\n",cpl_table_get_nrow(*lines_xyg));
3438
3439 cleanup:
3440 return cpl_error_get_code();
3441
3442}
3443
3444
3445
static int starty
static int endy
static xsh_instrument * instrument
static cpl_error_code xsh_cfg_recover_gen_xyg(cpl_table *lines_tab, struct xs_3 *p_xs_3_config, xsh_instrument *inst, int pre_scan, cpl_table **lines_gue)
static cpl_error_code xsh_cfg_recover_guess_tab_corr_by_ordpos(xsh_instrument *instr, cpl_frame *order_tab_centr, cpl_frame **model_xy_gue)
static cpl_error_code xsh_cfg_recover_measure_line_xy_fit(cpl_frame *raw_frm, cpl_parameterlist *parameters, cpl_frame **model_xy_gue, int debug_level)
static cpl_error_code xsh_cfg_recover_guess_tab_corr_by_user(cpl_parameterlist *parameters, cpl_frame **model_xy_gue)
static int xsh_cfg_recover_create(cpl_plugin *)
Setup the recipe options.
#define RECIPE_CONTACT
static cpl_error_code xsh_cfg_recover_extend_xy_pos_frm(cpl_frame **frm, xsh_instrument *instrument)
static cpl_error_code xsh_cfg_recover_measure_line_xy(cpl_frame *frame, xsh_instrument *inst, cpl_frame *order_tab_centr, cpl_parameterlist *parameters, const char *method, cpl_frame *model_config, cpl_frame **guess, int debug_level)
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
static cpl_table * xsh_cfg_recover_remove_blends(cpl_table *tab_xy_guess, cpl_table *tab_xy_peaks_sel, const int thresh_x, const int thresh_y)
static cpl_table * xsh_cfg_recover_measure_tab_xy_peaks(cpl_image *ima_ext, cpl_parameterlist *parameters)
static cpl_error_code xsh_cfg_recover_driver(cpl_parameterlist *parameters, cpl_frameset *frameset)
static int xsh_cfg_recover_last_step(cpl_parameterlist *parameters, cpl_frameset *frameset, xsh_instrument *instrument, cpl_frameset *raws, cpl_frameset *calib)
Interpret the command line options and execute the data processing.
static int xsh_cfg_recover_destroy(cpl_plugin *)
Destroy what has been created by the 'create' function.
static cpl_frame * xsh_cfg_recover_gen_xyg_frame(cpl_frame *wave_list, cpl_frame *config_frame, xsh_instrument *instr, int prescan)
static char xsh_cfg_recover_description[]
static cpl_image * xsh_cfg_recover_linear_ext(cpl_frame *raw_frm, cpl_frame *order_tab_centr, xsh_instrument *instr, const int slit, const double thresh_min)
static cpl_error_code xsh_cfg_recover_pattern_match(cpl_parameterlist *parameters, cpl_matrix *mat_gue, cpl_matrix *mat_dat, int use_pattern, int use_data, int debug_level)
static cpl_table * xsh_cfg_recover_select_peaks(cpl_table *tab_xy_guess, cpl_table *tab_xy_peaks, const double factor)
static cpl_error_code xsh_cfg_recover_model_THE_create(cpl_frame *config_frame, xsh_instrument *instrument, cpl_frame *wave_list, cpl_frame **THE1, cpl_frame **THE9)
static char xsh_cfg_recover_description_short[]
static cpl_error_code xsh_cfg_recover_prepare_pm_set(cpl_table *tab_pat, cpl_table *tab_dat, cpl_parameterlist *parameters, cpl_matrix **mat_pat, cpl_matrix **mat_dat, int *use_pat, int *use_dat)
#define RECIPE_ID
#define RECIPE_AUTHOR
static int xsh_cfg_recover_exec(cpl_plugin *)
Execute the plugin instance given by the interface.
#define XSH_ORDPOS_POL_DIM_MAX
static cpl_error_code xsh_cfg_recover_add_peaks_xpos(cpl_frame *order_tab_centr, xsh_instrument *instr, cpl_table **tab_xy_peaks)
xsh_order_list * xsh_order_list_load(cpl_frame *frame, xsh_instrument *instr)
load an order list from a frame
int xsh_order_list_get_order(xsh_order_list *list, int absorder)
void xsh_order_list_free(xsh_order_list **list)
free memory associated to an order_list
void xsh_prepare(cpl_frameset *frames, cpl_frame *bpmap, cpl_frame *mbias, const char *prefix, xsh_instrument *instr, const int pre_overscan_corr, const bool flag_neg_and_thresh_pix)
This function transform RAW frames dataset in PRE frames dataset attaching the default bad pixel map ...
Definition: xsh_prepare.c:122
#define XSH_ASSURE_NOT_ILLEGAL(cond)
Definition: xsh_error.h:107
#define assure(CONDITION, ERROR_CODE,...)
Definition: xsh_error.h:54
#define check(COMMAND)
Definition: xsh_error.h:71
#define check_msg(COMMAND,...)
Definition: xsh_error.h:62
#define xsh_error_reset()
Definition: xsh_error.h:87
#define cknull(NULLEXP)
Definition: xsh_error.h:77
void xsh_instrument_set_mode(xsh_instrument *i, XSH_MODE mode)
Set a mode on instrument structure.
const char * xsh_instrument_arm_tostring(xsh_instrument *i)
Get the string associated with an arm.
XSH_ARM xsh_instrument_get_arm(xsh_instrument *i)
Get an arm on instrument structure.
void xsh_instrument_free(xsh_instrument **instrument)
free an instrument structure
cpl_error_code xsh_model_config_load_best(cpl_frame *config_frame, xsh_xs_3 *p_xs_3)
Load the config model table and fill the struct.
Definition: xsh_model_io.c:174
cpl_vector * xsh_model_refining_detect(const cpl_vector *in, int fwhm, double sigma, int display)
Detect the brightest features in a spectrum.
void xsh_model_get_xy(xsh_xs_3 *p_xs_3, xsh_instrument *instr, double lambda_nm, int morder, double ent_slit_pos, double *x, double *y)
Compute the detector location (floating point pixels) of a given wavelength/entrance slit position.
cpl_frame * xsh_model_spectralformat_create(xsh_xs_3 *p_xs_3, const char *tab_filename)
creates the model spectral format table
int xsh_model_first_anneal(cpl_parameterlist *parlist, cpl_frameset *frameset)
Interpret the command line options and execute the data processing.
cpl_frame * xsh_model_THE_create(xsh_xs_3 *p_xs_3, xsh_instrument *instr, const char *line_list, int num_ph, double sep_ph, const char *THE_filename)
Compute the THE table (centroid for each feature in lamp spectrum)
cpl_vector ** xsh_model_locus(struct xs_3 *p_xs_3, xsh_instrument *instr, double ent_slit_pos)
Compute the locus of the spectrum.
cpl_frame * xsh_model_pipe_anneal(cpl_frame *cfg_frame, cpl_frame *resid_frame, int maxit, double ann_fac, int scenario, int rec_id)
Run the annealing (optimisation) algoritm to improve the fit of the model parameter set to a given wa...
int size
int * y
int * x
static SimAnneal s
Definition: xsh_model_sa.c:99
#define xsh_msg_warning(...)
Print an warning message.
Definition: xsh_msg.h:88
#define xsh_msg_debug(...)
Print a debug message.
Definition: xsh_msg.h:99
#define xsh_msg_error(...)
Print an error message.
Definition: xsh_msg.h:62
#define xsh_msg(...)
Print a message on info level.
Definition: xsh_msg.h:121
void xsh_pfits_set_pcatg(cpl_propertylist *plist, const char *value)
Write the PCATG value.
Definition: xsh_pfits.c:1008
void xsh_pfits_set_wavesoltype(cpl_propertylist *plist, const char *value)
Write the WAVESOL TYPE value.
Definition: xsh_pfits.c:3172
cpl_vector * xsh_spectrum_detect_peaks(const cpl_vector *in, int fwhm, double kappa, int display)
Detect the brightest features in a spectrum.
Definition: xsh_spectrum.c:255
cpl_frameset * xsh_subtract_nir_on_off(cpl_frameset *on, cpl_frameset *off, xsh_instrument *instr)
(NIR only) subtract the OFF set of files from the On set of files
Definition: xsh_subtract.c:194
cpl_frame * xsh_subtract_bias(cpl_frame *frame, cpl_frame *bias, xsh_instrument *instr, const char *type, const int pre_overscan_corr, const int save_tmp)
Subtract the master bias frame from PRE frame.
Definition: xsh_subtract.c:120
cpl_frame * xsh_subtract_dark(cpl_frame *frame, cpl_frame *dark, const char *filename, xsh_instrument *instr)
subtract the master dark frame from PRE frame
Definition: xsh_subtract.c:247
void xsh_free_vector(cpl_vector **v)
Deallocate a vector and set the pointer to NULL.
Definition: xsh_utils.c:2284
void xsh_free_parameterlist(cpl_parameterlist **p)
Deallocate a parameter list and set the pointer to NULL.
Definition: xsh_utils.c:2224
void xsh_free_image(cpl_image **i)
Deallocate an image and set the pointer to NULL.
Definition: xsh_utils.c:2116
void xsh_free_frame(cpl_frame **f)
Deallocate a frame and set the pointer to NULL.
Definition: xsh_utils.c:2269
void xsh_free_frameset(cpl_frameset **f)
Deallocate a frame set and set the pointer to NULL.
Definition: xsh_utils.c:2254
cpl_error_code xsh_sort_table_1(cpl_table *t, const char *column, cpl_boolean reverse)
Sort a table by one column.
void xsh_free_array(cpl_array **m)
Deallocate an array and set the pointer to NULL.
Definition: xsh_utils.c:2299
const char * xsh_get_license(void)
Get the pipeline copyright and license.
Definition: xsh_utils.c:1193
char * xsh_stringcat_any(const char *s,...)
Concatenate an arbitrary number of strings.
Definition: xsh_utils.c:1925
void xsh_init(void)
Reset library state.
Definition: xsh_utils.c:1160
void xsh_free_matrix(cpl_matrix **m)
Deallocate a matrix and set the pointer to NULL.
Definition: xsh_utils.c:2209
cpl_error_code xsh_begin(cpl_frameset *frames, const cpl_parameterlist *parameters, xsh_instrument **instrument, cpl_frameset **raws, cpl_frameset **calib, const char *tag_list[], int tag_list_size, const char *recipe_id, unsigned int binary_version, const char *short_descr)
Recipe initialization.
Definition: xsh_utils.c:1244
void xsh_free_table(cpl_table **t)
Deallocate a table and set the pointer to NULL.
Definition: xsh_utils.c:2133
void xsh_free_propertylist(cpl_propertylist **p)
Deallocate a property list and set the pointer to NULL.
Definition: xsh_utils.c:2179
cpl_error_code xsh_end(const char *recipe_id, cpl_frameset *frames, cpl_parameterlist *parameters)
Recipe termination.
Definition: xsh_utils.c:1519
DOUBLE pix
int morder_max
DOUBLE slit[10]
DOUBLE offx
int morder_min
DOUBLE offy
DOUBLE nug
DOUBLE sg
xsh_order * list
cpl_polynomial * cenpoly
@ XSH_ARM_UVB
@ XSH_ARM_NIR
@ XSH_ARM_VIS
@ XSH_MODE_SLIT
#define XSH_RESID_TAB_TABLE_COLNAME_SLITPOSITION
#define XSH_RESID_TAB_TABLE_COLNAME_YTHANNEAL
#define XSH_RESID_TAB_TABLE_COLNAME_ORDER
#define XSH_RESID_TAB_TABLE_COLNAME_YTHPRE
#define XSH_RESID_TAB_TABLE_COLNAME_RESIDYMODEL
#define XSH_RESID_TAB_TABLE_COLNAME_XGAUSS
#define XSH_RESID_TAB_TABLE_COLNAME_WAVELENGTH
#define XSH_RESID_TAB_TABLE_COLNAME_YGAUSS
#define XSH_RESID_TAB_TABLE_COLNAME_SIGMAXGAUSS
#define XSH_RESID_TAB_TABLE_COLNAME_RESIDXMODEL
#define XSH_RESID_TAB_TABLE_COLNAME_XTHCOR
#define XSH_RESID_TAB_TABLE_COLNAME_YTHCOR
#define XSH_RESID_TAB_TABLE_COLNAME_SLITINDEX
#define XSH_RESID_TAB_TABLE_COLNAME_XTHANNEAL
#define XSH_RESID_TAB_TABLE_COLNAME_XTHPRE
#define XSH_RESID_TAB_TABLE_COLNAME_SIGMAYGAUSS
double kappa
Definition: xsh_detmon_lg.c:81
const char * method
Definition: xsh_detmon_lg.c:78
double tolerance
int xsh_print_rec_status(const int val)
Check if an error has happened and returns error kind and location.
Definition: xsh_dfs.c:877
void xsh_add_product_table(cpl_frame *frame, cpl_frameset *frameset, const cpl_parameterlist *parameters, const char *recipe_id, xsh_instrument *instrument, const char *final_prefix)
Save Table product (input frame has several extensions, 1 table per extension)
Definition: xsh_dfs.c:3146
char * xsh_get_tag_from_arm(const char *tag, xsh_instrument *instr)
Find arm specific tag from base and instrument setting.
Definition: xsh_dfs.c:3374
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.
Definition: xsh_dfs.c:930
cpl_frame * xsh_find_frame_with_tag(cpl_frameset *frames, const char *tag, xsh_instrument *instr)
Find frame with a given tag.
Definition: xsh_dfs.c:3347
void xsh_frame_config(const char *fname, const char *tag, cpl_frame_type type, cpl_frame_group group, cpl_frame_level level, cpl_frame **frame)
Define a frame characteristics.
Definition: xsh_dfs.c:900
cpl_frameset * xsh_frameset_extract(const cpl_frameset *frames, const char *tag)
Extract frames with given tag from frameset.
Definition: xsh_dfs.c:983
cpl_frame * xsh_find_master_bpmap(cpl_frameset *set)
find the master bad pixel map in a set of files
Definition: xsh_dfs.c:1621
#define XSH_THEO_TAB_SING
Definition: xsh_dfs.h:1084
#define XSH_MOD_CFG
Definition: xsh_dfs.h:1261
#define XSH_MODEL_GUESS_XY
Definition: xsh_dfs.h:1281
#define XSH_MASTER_BIAS
Definition: xsh_dfs.h:549
#define XSH_MEASURE_LINE_POS_XY
Definition: xsh_dfs.h:1286
#define XSH_MASTER_DARK
Definition: xsh_dfs.h:550
#define XSH_FMTCHK_OFF
Definition: xsh_dfs.h:407
#define XSH_FMTCHK
Definition: xsh_dfs.h:221
#define XSH_FMTCHK_NIR
Definition: xsh_dfs.h:406
#define XSH_GET_TAG_FROM_ARM(TAG, instr)
Definition: xsh_dfs.h:1548
#define XSH_ORDER_TAB_CENTR
Definition: xsh_dfs.h:553
#define XSH_MOD_CFG_FAN
Definition: xsh_dfs.h:1276
#define XSH_ARC_LINE_LIST
Definition: xsh_dfs.h:955
#define XSH_THEO_TAB_MULT
Definition: xsh_dfs.h:1089
cpl_error_code xsh_model_temperature_update_frame(cpl_frame **model_config_frame, cpl_frame *ref_frame, xsh_instrument *instrument, int *found_temp)
cpl_error_code xsh_parameters_decode_bp(const char *recipe_id, cpl_parameterlist *plist, const int ival)
int xsh_parameters_debug_level_get(const char *recipe_id, const cpl_parameterlist *list)
void xsh_parameters_generic(const char *recipe_id, cpl_parameterlist *plist)
#define XSH_WAVESOLTYPE_MODEL
Definition: xsh_pfits.h:214
@ XSH_DEBUG_LEVEL_NONE
Definition: xsh_utils.h:137