46 #include "irplib_utils.h"
47 #include "irplib_std.h"
48 #include "irplib_spectrum.h"
50 #include "naco_utils.h"
51 #include "naco_physicalmodel.h"
52 #include "naco_wavelength.h"
53 #include "naco_pfits.h"
60 #define NACO_SPC_JITTER_OFFSET_ERR 10
66 static int naco_spc_jitter_create(cpl_plugin *);
67 static int naco_spc_jitter_exec(cpl_plugin *);
68 static int naco_spc_jitter_destroy(cpl_plugin *);
69 static int naco_spc_jitter(cpl_parameterlist *, cpl_frameset *);
70 static cpl_image ** naco_spc_jitter_combine(cpl_frameset *,
char *,
char *,
72 static cpl_vector * naco_spc_jitter_get_offsets(cpl_frameset *);
73 static int * naco_spc_jitter_classif(cpl_vector *,
int *);
74 static int off_comp(
double,
double,
double);
75 static cpl_imagelist * naco_spc_jitter_saa_groups(cpl_imagelist *,
76 cpl_vector *,
int *,
int, cpl_vector **);
77 static int naco_spc_jitter_wavecal(
char *, cpl_image *, cpl_frameset *);
78 static cpl_imagelist * naco_spc_jitter_nodded(cpl_imagelist *, cpl_vector *,
80 static cpl_imagelist * naco_spc_jitter_distor(cpl_imagelist *,
char *);
81 static double naco_spc_jitter_refine_offset(cpl_image *, cpl_image *);
82 static cpl_table * naco_spc_jitter_extract(cpl_image *);
83 static int naco_spc_jitter_save(
const cpl_image *,
const cpl_table *,
84 cpl_parameterlist *, cpl_frameset *);
95 int wavecal_rej_bottom;
98 int wavecal_rej_right;
104 int extr_sky_ri_width;
105 int extr_sky_le_width;
106 int extr_sky_ri_dist;
107 int extr_sky_le_dist;
117 } naco_spc_jitter_config;
119 static char naco_spc_jitter_description[] =
120 "naco_spc_jitter -- NACO spectro jitter recipe\n"
121 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
122 "raw-file.fits "NACO_SPC_JITTER_RAW
" or\n"
123 "flat-file.fits "NACO_CALIB_SPFLAT
" or\n"
124 "arc-file.fits "NACO_CALIB_ARC
" or\n"
125 "arc_wl-file.fits "NACO_CALIB_ARC_WL
"\n";
146 int cpl_plugin_get_info(cpl_pluginlist * list)
148 cpl_recipe * recipe = cpl_calloc(1,
sizeof(*recipe));
149 cpl_plugin * plugin = &recipe->interface;
151 cpl_plugin_init(plugin,
154 CPL_PLUGIN_TYPE_RECIPE,
156 "Spectro jitter recipe",
157 naco_spc_jitter_description,
160 cpl_get_license(PACKAGE_NAME,
"2002, 2003, 2005"),
161 naco_spc_jitter_create,
162 naco_spc_jitter_exec,
163 naco_spc_jitter_destroy);
165 cpl_pluginlist_append(list, plugin);
180 static int naco_spc_jitter_create(cpl_plugin * plugin)
186 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
187 recipe = (cpl_recipe *)plugin;
191 recipe->parameters = cpl_parameterlist_new();
195 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.wavecal",
196 CPL_TYPE_STRING,
"Wavelength method: phy or sky",
197 "naco.naco_spc_jitter",
"sky");
198 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wavecal");
199 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
200 cpl_parameterlist_append(recipe->parameters, p);
202 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.wavecal_rej",
203 CPL_TYPE_STRING,
"left right bottom top rejections",
204 "naco.naco_spc_jitter",
"-1 -1 50 50");
205 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wc_rej");
206 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
207 cpl_parameterlist_append(recipe->parameters, p);
209 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.saa_refine",
210 CPL_TYPE_BOOL,
"flag to refine the offsets",
211 "naco.naco_spc_jitter", TRUE);
212 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"saa_refine");
213 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
214 cpl_parameterlist_append(recipe->parameters, p);
216 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.saa_rej",
217 CPL_TYPE_STRING,
"low and high rejections in percent",
218 "naco.naco_spc_jitter",
"0.1 0.1");
219 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"saa_rej");
220 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
221 cpl_parameterlist_append(recipe->parameters, p);
223 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.spec_pos",
224 CPL_TYPE_INT,
"spectrum position",
"naco.naco_spc_jitter", -1);
225 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"spec_pos");
226 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
227 cpl_parameterlist_append(recipe->parameters, p);
229 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.spec_width",
230 CPL_TYPE_INT,
"spectrum width",
"naco.naco_spc_jitter", 10);
231 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"spec_width");
232 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
233 cpl_parameterlist_append(recipe->parameters, p);
235 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.sky_ri_width",
236 CPL_TYPE_INT,
"sky width right to the spectrum",
237 "naco.naco_spc_jitter", 10);
238 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky_ri_width");
239 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
240 cpl_parameterlist_append(recipe->parameters, p);
242 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.sky_le_width",
243 CPL_TYPE_INT,
"sky width left to the spectrum",
244 "naco.naco_spc_jitter", 10);
245 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky_le_width");
246 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
247 cpl_parameterlist_append(recipe->parameters, p);
249 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.sky_ri_dist",
250 CPL_TYPE_INT,
"sky distance right to the spectrum",
251 "naco.naco_spc_jitter", -1);
252 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky_ri_dist");
253 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
254 cpl_parameterlist_append(recipe->parameters, p);
256 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.sky_le_dist",
257 CPL_TYPE_INT,
"sky distance left to the spectrum",
258 "naco.naco_spc_jitter", -1);
259 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sky_le_dist");
260 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
261 cpl_parameterlist_append(recipe->parameters, p);
263 p = cpl_parameter_new_value(
"naco.naco_spc_jitter.display",
264 CPL_TYPE_BOOL,
"flag to make plots",
"naco.naco_spc_jitter",
266 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"display");
267 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
268 cpl_parameterlist_append(recipe->parameters, p);
279 static int naco_spc_jitter_exec(cpl_plugin * plugin)
284 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
285 recipe = (cpl_recipe *)plugin;
288 return naco_spc_jitter(recipe->parameters, recipe->frames);
298 static int naco_spc_jitter_destroy(cpl_plugin * plugin)
303 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
304 recipe = (cpl_recipe *)plugin;
307 cpl_parameterlist_delete(recipe->parameters);
319 static int naco_spc_jitter(
320 cpl_parameterlist * parlist,
321 cpl_frameset * framelist)
323 const char * fctid =
"naco_spc_jitter";
325 cpl_propertylist * plist;
329 cpl_frameset * rawframes;
333 cpl_frame * cur_frame;
335 cpl_frameset * cur_set;
336 cpl_image ** combined;
337 cpl_table * extracted;
346 naco_spc_jitter_config.wavecal_out = -1;
347 naco_spc_jitter_config.wavecal_cc = -1.0;
348 naco_spc_jitter_config.throws = NULL;
352 par = cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.wavecal");
353 sval = cpl_parameter_get_string(par);
354 if (!strcmp(sval,
"phy")) naco_spc_jitter_config.wavecal_in = 0;
355 else if (!strcmp(sval,
"sky")) naco_spc_jitter_config.wavecal_in = 1;
357 cpl_msg_error(fctid,
"Invalid value for wavecal option");
361 par = cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.wavecal_rej");
362 sval = cpl_parameter_get_string(par);
363 if (sscanf(sval,
"%d %d %d %d",
364 &naco_spc_jitter_config.wavecal_rej_left,
365 &naco_spc_jitter_config.wavecal_rej_right,
366 &naco_spc_jitter_config.wavecal_rej_bottom,
367 &naco_spc_jitter_config.wavecal_rej_top) != 4) {
371 par = cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.saa_refine");
372 naco_spc_jitter_config.saa_refine = cpl_parameter_get_bool(par);
375 par = cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.saa_rej");
376 sval = cpl_parameter_get_string(par);
377 if (sscanf(sval,
"%lg %lg",
378 &naco_spc_jitter_config.saa_rej_low,
379 &naco_spc_jitter_config.saa_rej_high) != 2) {
384 par=cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.spec_pos");
385 naco_spc_jitter_config.extr_spec_pos = cpl_parameter_get_int(par);
387 par=cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.spec_width");
388 naco_spc_jitter_config.extr_spec_width = cpl_parameter_get_int(par);
390 par=cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.sky_ri_width");
391 naco_spc_jitter_config.extr_sky_ri_width = cpl_parameter_get_int(par);
393 par=cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.sky_le_width");
394 naco_spc_jitter_config.extr_sky_le_width = cpl_parameter_get_int(par);
396 par=cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.sky_ri_dist");
397 naco_spc_jitter_config.extr_sky_ri_dist = cpl_parameter_get_int(par);
399 par=cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.sky_le_dist");
400 naco_spc_jitter_config.extr_sky_le_dist = cpl_parameter_get_int(par);
402 par = cpl_parameterlist_find(parlist,
"naco.naco_spc_jitter.display");
403 naco_spc_jitter_config.display = cpl_parameter_get_bool(par);
407 cpl_msg_error(fctid,
"Cannot identify RAW and CALIB frames");
412 if ((labels = cpl_frameset_labelise(framelist, irplib_compare_tags,
413 &nlabels)) == NULL) {
414 cpl_msg_error(fctid,
"Cannot labelise the input frames");
419 for (i=0 ; i<nlabels ; i++) {
420 cur_set = cpl_frameset_extract(framelist, labels, i);
421 cur_frame = cpl_frameset_get_position(cur_set, 0);
422 tag = (
char*)cpl_frame_get_tag(cur_frame);
423 if (!strcmp(tag, NACO_SPC_JITTER_RAW)) {
425 rawframes = cpl_frameset_duplicate(cur_set);
426 }
else if (!strcmp(tag, NACO_CALIB_SPFLAT)) {
429 flat = cpl_strdup(cpl_frame_get_filename(cur_frame));
430 }
else if (!strcmp(tag, NACO_CALIB_ARC)) {
433 arc = cpl_strdup(cpl_frame_get_filename(cur_frame));
434 }
else if (!strcmp(tag, NACO_CALIB_ARC_WL)) {
436 naco_spc_jitter_config.wavecal_in = 2;
438 arc_wl = cpl_strdup(cpl_frame_get_filename(cur_frame));
440 cpl_frameset_delete(cur_set);
445 if (rawframes == NULL) {
446 cpl_msg_error(fctid,
"Cannot find the raw frames in the input list");
447 if (flat) cpl_free(flat);
448 if (arc) cpl_free(arc);
449 if (arc_wl) cpl_free(arc_wl);
454 cpl_msg_info(fctid,
"Create the combined image");
455 cpl_msg_indent_more();
456 if ((combined = naco_spc_jitter_combine(rawframes, flat, arc,
458 cpl_msg_error(fctid,
"Cannot combine the images");
459 if (flat) cpl_free(flat);
460 if (arc) cpl_free(arc);
461 if (arc_wl) cpl_free(arc_wl);
462 cpl_frameset_delete(rawframes);
463 if (naco_spc_jitter_config.throws)
464 cpl_vector_delete(naco_spc_jitter_config.throws);
465 cpl_msg_indent_less();
468 cpl_frameset_delete(rawframes);
469 if (flat) cpl_free(flat);
470 if (arc) cpl_free(arc);
471 if (arc_wl) cpl_free(arc_wl);
472 cpl_msg_indent_less();
475 cpl_msg_info(fctid,
"Extract the spectrum");
476 cpl_msg_indent_more();
477 if ((extracted = naco_spc_jitter_extract(combined[0])) == NULL) {
478 cpl_msg_error(fctid,
"Cannot extract the spectrum");
480 if (naco_spc_jitter_config.throws)
481 cpl_vector_delete(naco_spc_jitter_config.throws);
482 cpl_msg_indent_less();
485 cpl_msg_info(fctid,
"Save the products");
486 cpl_msg_indent_more();
487 if (naco_spc_jitter_save(combined[0], extracted, parlist,
489 cpl_msg_error(fctid,
"Cannot save the products");
490 cpl_image_delete(combined[0]);
491 cpl_image_delete(combined[1]);
493 cpl_table_delete(extracted);
494 cpl_msg_indent_less();
497 cpl_table_delete(extracted);
498 cpl_image_delete(combined[0]);
499 cpl_image_delete(combined[1]);
501 cpl_msg_indent_less();
516 static cpl_image ** naco_spc_jitter_combine(
517 cpl_frameset * rawframes,
522 const char * fctid =
"naco_spc_jitter_combine";
523 cpl_imagelist * ilist;
524 cpl_imagelist * corrected;
527 cpl_vector * offsets;
530 cpl_imagelist * abba;
531 cpl_vector * abba_off = NULL;
532 cpl_imagelist * nodded;
533 cpl_vector * nodded_off_x;
534 cpl_vector * nodded_off_y;
536 cpl_table * extracted;
538 double * pnodded_off_x;
539 cpl_imagelist * nodded_warped;
540 cpl_bivector * nodded_offsets;
541 cpl_image ** combined;
547 if (rawframes == NULL)
return NULL;
550 cpl_msg_info(fctid,
"Load the data");
551 cpl_msg_indent_more();
552 if ((ilist = cpl_imagelist_load_frameset(rawframes, CPL_TYPE_FLOAT,
554 cpl_msg_error(fctid,
"cannot load the data");
555 cpl_msg_indent_less();
558 cpl_msg_indent_less();
562 cpl_msg_info(fctid,
"Apply the flatfield correction");
563 if ((tmp_im = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, 0)) == NULL) {
564 cpl_msg_warning(fctid,
"cannot load the flat field");
566 if (cpl_imagelist_divide_image(ilist, tmp_im) != CPL_ERROR_NONE) {
567 cpl_msg_warning(fctid,
"cannot apply the flat field");
569 cpl_image_delete(tmp_im);
574 cpl_msg_info(fctid,
"Get the offsets");
575 if ((offsets = naco_spc_jitter_get_offsets(rawframes)) == NULL) {
576 cpl_msg_error(fctid,
"cannot get the offsets");
577 cpl_imagelist_delete(ilist);
582 cpl_msg_info(fctid,
"Classify in groups");
583 cpl_msg_indent_more();
584 if ((groups = naco_spc_jitter_classif(offsets, &ngroups)) == NULL) {
585 cpl_msg_error(fctid,
"cannot classify the data");
586 cpl_imagelist_delete(ilist);
587 cpl_vector_delete(offsets);
588 cpl_msg_indent_less();
591 cpl_msg_indent_less();
594 cpl_msg_info(fctid,
"Shift and add each group to one image");
595 cpl_msg_indent_more();
596 if ((abba = naco_spc_jitter_saa_groups(ilist, offsets, groups,
597 ngroups, &abba_off)) == NULL) {
598 cpl_msg_error(fctid,
"cannot shift and add groups");
599 cpl_imagelist_delete(ilist);
600 cpl_vector_delete(offsets);
602 cpl_msg_indent_less();
603 cpl_vector_delete(abba_off);
606 cpl_imagelist_delete(ilist);
608 cpl_vector_delete(offsets);
609 cpl_msg_indent_less();
627 cpl_msg_info(fctid,
"Create the nodded images");
628 cpl_msg_indent_more();
629 if ((nodded = naco_spc_jitter_nodded(abba, abba_off,
630 &nodded_off_x))==NULL) {
631 cpl_msg_error(fctid,
"cannot create the nodded images");
632 cpl_imagelist_delete(abba);
633 cpl_vector_delete(abba_off);
634 cpl_msg_indent_less();
637 cpl_imagelist_delete(abba);
638 cpl_msg_indent_less();
641 nima = cpl_imagelist_get_size(nodded);
642 naco_spc_jitter_config.throws = cpl_vector_new(nima);
643 for (i=0 ; i<nima/2 ; i++) {
644 throw = fabs( (cpl_vector_get(abba_off, 2*i))-
645 (cpl_vector_get(abba_off, 2*i+1)));
646 cpl_vector_set(naco_spc_jitter_config.throws, 2*i,
throw);
647 cpl_vector_set(naco_spc_jitter_config.throws, 2*i+1,
throw);
649 cpl_vector_delete(abba_off);
653 cpl_msg_info(fctid,
"Correct the distortion on nodded images");
654 cpl_msg_indent_more();
655 if ((nodded_warped = naco_spc_jitter_distor(nodded, arc)) == NULL) {
656 cpl_msg_error(fctid,
"cannot correct the distortion");
657 cpl_imagelist_delete(nodded);
658 cpl_vector_delete(nodded_off_x);
659 cpl_msg_indent_less();
662 cpl_imagelist_delete(nodded);
663 nodded = nodded_warped;
664 cpl_msg_indent_less();
668 if (naco_spc_jitter_config.saa_refine) {
669 cpl_msg_info(fctid,
"Refine the offsets");
670 pnodded_off_x = cpl_vector_get_data(nodded_off_x);
671 for (i=0 ; i<cpl_imagelist_get_size(nodded) ; i++) {
672 new_offset = naco_spc_jitter_refine_offset(
673 cpl_imagelist_get(nodded, 0),
674 cpl_imagelist_get(nodded, i));
675 if (new_offset > 5000) {
676 cpl_msg_debug(fctid,
"cannot refine the offset - keep %g",
679 if (fabs(new_offset-pnodded_off_x[i]) <
680 NACO_SPC_JITTER_OFFSET_ERR) {
681 cpl_msg_debug(fctid,
"refined offset : %g (old was %g)",
682 new_offset, pnodded_off_x[i]);
683 pnodded_off_x[i] = new_offset;
686 "refined offset %g too different - keep %g",
687 new_offset, pnodded_off_x[i]);
695 nodded_off_y = cpl_vector_duplicate(nodded_off_x);
696 cpl_vector_fill(nodded_off_y, 0.0);
697 nodded_offsets = cpl_bivector_wrap_vectors(nodded_off_x, nodded_off_y);
699 cpl_msg_info(fctid,
"Apply the shift and add on the nodded frames");
700 nima = cpl_imagelist_get_size(nodded);
701 if ((combined = cpl_geom_img_offset_saa(nodded, nodded_offsets,
703 (
int)(naco_spc_jitter_config.saa_rej_low * nima),
704 (
int)(naco_spc_jitter_config.saa_rej_high * nima),
705 CPL_GEOM_FIRST, NULL, NULL)) == NULL) {
706 cpl_msg_error(fctid,
"Cannot shift and add group");
707 cpl_imagelist_delete(nodded);
708 cpl_bivector_unwrap_vectors(nodded_offsets);
709 cpl_vector_delete(nodded_off_x);
710 cpl_vector_delete(nodded_off_y);
713 cpl_imagelist_delete(nodded);
714 cpl_bivector_unwrap_vectors(nodded_offsets);
715 cpl_vector_delete(nodded_off_x);
716 cpl_vector_delete(nodded_off_y);
727 static cpl_vector * naco_spc_jitter_get_offsets(cpl_frameset * rawframes)
729 const char * fctid =
"naco_spc_jitter_get_offsets";
730 cpl_vector * offsets;
733 cpl_frame * cur_frame;
734 cpl_propertylist * plist;
738 if (rawframes == NULL)
return NULL;
741 nraw = cpl_frameset_get_size(rawframes);
744 offsets = cpl_vector_new(nraw);
745 pvect = cpl_vector_get_data(offsets);
746 for (i=0 ; i<nraw ; i++) {
747 cur_frame = cpl_frameset_get_position(rawframes, i);
748 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(cur_frame),
750 cpl_msg_error(fctid,
"cannot get property list");
751 cpl_vector_delete(offsets);
755 if (cpl_error_get_code()) {
756 cpl_msg_error(fctid,
"cannot get the offset from the header");
757 cpl_vector_delete(offsets);
758 cpl_propertylist_delete(plist);
761 cpl_propertylist_delete(plist);
805 static int * naco_spc_jitter_classif(
806 cpl_vector * offsets,
809 const char * fctid =
"naco_spc_jitter_classif";
812 double offset_thresh;
813 cpl_vector * tmp_vec;
819 if (offsets == NULL)
return NULL;
822 nraw = cpl_vector_get_size(offsets);
825 tmp_vec = cpl_vector_duplicate(offsets);
826 cpl_vector_sort(tmp_vec, 1);
827 pvect = cpl_vector_get_data(tmp_vec);
828 if (pvect[0] == pvect[nraw-1]) {
829 cpl_msg_error(fctid,
"Only one offset in the list - abort");
830 cpl_vector_delete(tmp_vec);
833 offset_thresh = (pvect[0] + pvect[nraw-1]) / 2.0;
834 cpl_vector_delete(tmp_vec);
837 pvect = cpl_vector_get_data(offsets);
839 groups = cpl_calloc(nraw,
sizeof(
int));
847 (!off_comp(pvect[i], pvect[i+j], offset_thresh))) j++;
849 if (i+j >= nraw) i = nraw;
853 while ((i+j+k < nraw)
854 && (!off_comp(pvect[i+j], pvect[i+j+k], offset_thresh))
858 for (l=i+j+k ; l<nraw ; l++) {
859 if (off_comp(pvect[i+j], pvect[l], offset_thresh)) {
865 if (last_group == 0) {
866 for (l=0 ; l<j ; l++) groups[i+l] = *ngroups + 1;
867 for (l=0 ; l<k ; l++) groups[i+j+l] = *ngroups + 2;
871 for (l=0 ; l<j ; l++) groups[i+l] = *ngroups + 1;
872 for (l=0 ; l<nraw - (i+j) ; l++) groups[i+j+l] =*ngroups + 2;
881 cpl_msg_error(fctid,
"Odd number of groups found");
921 static cpl_imagelist * naco_spc_jitter_saa_groups(
922 cpl_imagelist * ilist,
923 cpl_vector * offsets,
926 cpl_vector ** abba_off)
928 const char * fctid =
"naco_spc_jitter_saa_groups";
929 cpl_imagelist * abba;
930 cpl_imagelist * group_list;
932 cpl_image ** combined;
933 cpl_bivector * group_off;
942 if ((ilist == NULL) || (offsets == NULL) || (groups == NULL))
return NULL;
945 nima = cpl_imagelist_get_size(ilist);
946 poffsets = cpl_vector_get_data(offsets);
949 abba = cpl_imagelist_new();
950 *abba_off = cpl_vector_new(ngroups);
951 pabba_off = cpl_vector_get_data(*abba_off);
954 for (i=0 ; i<ngroups ; i++) {
958 group_list = cpl_imagelist_new();
960 for (j=0 ; j<nima ; j++) {
961 if (i+1 == groups[j]) {
963 if (k==0) pabba_off[i] = poffsets[j];
965 if (fabs(pabba_off[i]-poffsets[j]) > 1e-3) saa = 1;
967 tmp_ima = cpl_image_duplicate(cpl_imagelist_get(ilist, j));
968 cpl_imagelist_set(group_list, tmp_ima, k);
976 group_off = cpl_bivector_new(k);
977 cpl_vector_fill(cpl_bivector_get_y(group_off), 0.0);
978 pgroup_off = cpl_bivector_get_x_data(group_off);
980 for (j=0 ; j<nima ; j++) {
981 if (i+1 == groups[j]) {
982 pgroup_off[k] = poffsets[j];
986 cpl_vector_subtract_scalar(cpl_bivector_get_x(group_off),
989 cpl_msg_debug(fctid,
"Apply shift-and-add for group %d", i+1);
990 if ((combined = cpl_geom_img_offset_saa(group_list,
991 group_off, CPL_KERNEL_DEFAULT, 0, 0,
992 CPL_GEOM_FIRST)) == NULL) {
993 cpl_msg_error(fctid,
"Cannot shift and add group nb %d", i+1);
994 cpl_imagelist_delete(group_list);
995 cpl_bivector_delete(group_off);
996 cpl_imagelist_delete(abba);
997 cpl_vector_delete(*abba_off);
1000 cpl_bivector_delete(group_off);
1001 cpl_image_delete(combined[1]);
1002 cpl_imagelist_set(abba, combined[0], i);
1006 cpl_msg_debug(fctid,
"Apply averaging for group %d", i+1);
1007 if ((tmp_ima = cpl_imagelist_collapse_create(group_list)) == NULL) {
1008 cpl_msg_error(fctid,
"Cannot average group nb %d", i+1);
1009 cpl_imagelist_delete(group_list);
1010 cpl_imagelist_delete(abba);
1011 cpl_vector_delete(*abba_off);
1014 cpl_imagelist_set(abba, tmp_ima, i);
1016 cpl_imagelist_delete(group_list);
1030 static int naco_spc_jitter_wavecal(
1035 const char * fctid =
"naco_spc_jitter_wavecal";
1036 cpl_table * arc_tab;
1038 cpl_frame * cur_frame;
1039 const char * cur_fname;
1040 computed_disprel * disprel;
1046 cpl_msg_info(fctid,
"Get the wavelength from the ARC file");
1047 if ((arc_tab = cpl_table_load(arc, 1, 0)) == NULL) {
1048 cpl_msg_error(fctid,
"Cannot load the arc table");
1049 naco_spc_jitter_config.wavecal_out = -1;
1052 naco_spc_jitter_config.wavecal_a0 =
1053 cpl_table_get_double(arc_tab,
"WL_coefficients", 0, NULL);
1054 naco_spc_jitter_config.wavecal_a1 =
1055 cpl_table_get_double(arc_tab,
"WL_coefficients", 1, NULL);
1056 naco_spc_jitter_config.wavecal_a2 =
1057 cpl_table_get_double(arc_tab,
"WL_coefficients", 2, NULL);
1058 naco_spc_jitter_config.wavecal_a3 =
1059 cpl_table_get_double(arc_tab,
"WL_coefficients", 3, NULL);
1060 cpl_table_delete(arc_tab);
1061 naco_spc_jitter_config.wavecal_out = 2;
1062 naco_spc_jitter_config.wavecal_cc = -1.0;
1067 cur_frame = cpl_frameset_get_position(raw, 0);
1068 cur_fname = cpl_frame_get_filename(cur_frame);
1071 cpl_msg_info(fctid,
"Compute the physical model");
1072 cpl_msg_indent_more();
1074 cpl_msg_error(fctid,
"cannot compute the physical model");
1075 naco_spc_jitter_config.wavecal_out = -1;
1076 cpl_msg_indent_less();
1079 cpl_msg_info(fctid,
"f(x)=%g + %g*x + %g*x^2 + %g*x^3",
1080 phdisprel[0], phdisprel[1], phdisprel[2], phdisprel[3]);
1081 naco_spc_jitter_config.wavecal_a0 = phdisprel[0];
1082 naco_spc_jitter_config.wavecal_a1 = phdisprel[1];
1083 naco_spc_jitter_config.wavecal_a2 = phdisprel[2];
1084 naco_spc_jitter_config.wavecal_a3 = phdisprel[3];
1085 naco_spc_jitter_config.wavecal_cc = -1.0;
1086 naco_spc_jitter_config.wavecal_out = 0;
1087 cpl_msg_indent_less();
1090 if (naco_spc_jitter_config.wavecal_in == 1) {
1092 if ((slit_width = naco_get_slitwidth(cur_fname)) == -1) {
1093 cpl_msg_warning(fctid,
"cannot get the slit width");
1094 cpl_free(phdisprel);
1098 if ((order = naco_find_order(cur_fname)) == -1) {
1099 cpl_msg_warning(fctid,
"cannot get the order");
1100 cpl_free(phdisprel);
1104 cpl_msg_info(fctid,
"Compute the wavelength with the sky lines");
1105 cpl_msg_indent_more();
1107 naco_spc_jitter_config.wavecal_rej_bottom,
1108 naco_spc_jitter_config.wavecal_rej_top,
1109 naco_spc_jitter_config.wavecal_rej_left,
1110 naco_spc_jitter_config.wavecal_rej_right,
1111 naco_has_thermal(cur_fname) > 0,
1112 "oh", slit_width, order,
1113 (
int)(cpl_msg_get_level() == CPL_MSG_DEBUG),
1114 phdisprel)) == NULL) {
1115 cpl_msg_error(fctid,
"cannot compute the dispersion relation");
1116 cpl_free(phdisprel);
1117 cpl_msg_indent_less();
1120 cpl_msg_info(fctid,
"Cross correlation factor: %g", disprel->cc);
1121 cpl_msg_info(fctid,
"f(x)=%g + %g*x + %g*x^2 + %g*x^3",
1122 disprel->poly[0], disprel->poly[1], disprel->poly[2],
1124 naco_spc_jitter_config.wavecal_a0 = disprel->poly[0];
1125 naco_spc_jitter_config.wavecal_a1 = disprel->poly[1];
1126 naco_spc_jitter_config.wavecal_a2 = disprel->poly[2];
1127 naco_spc_jitter_config.wavecal_a3 = disprel->poly[3];
1128 naco_spc_jitter_config.wavecal_cc = disprel->cc;
1129 naco_spc_jitter_config.wavecal_out = 1;
1130 if (disprel->poly != NULL) cpl_free(disprel->poly);
1132 cpl_msg_indent_less();
1134 cpl_free(phdisprel);
1171 static cpl_imagelist * naco_spc_jitter_nodded(
1172 cpl_imagelist * abba,
1173 cpl_vector * abba_off,
1174 cpl_vector ** nodded_off)
1176 const char * fctid =
"naco_spc_jitter_nodded";
1177 cpl_imagelist * nodded;
1178 cpl_image * tmp_ima;
1181 double * pnodded_off;
1186 if ((abba == NULL) || (abba_off == NULL))
return NULL;
1189 nima = cpl_imagelist_get_size(abba);
1191 cpl_msg_error(fctid,
"Number of images should be even");
1196 *nodded_off = cpl_vector_duplicate(abba_off);
1198 nodded = cpl_imagelist_new();
1199 for (i=0 ; i<(nima/2) ; i++) {
1201 tmp_ima = cpl_image_duplicate(cpl_imagelist_get(abba, 2*i));
1202 cpl_image_subtract(tmp_ima, cpl_imagelist_get(abba, 2*i+1));
1203 cpl_imagelist_set(nodded, tmp_ima, 2*i);
1205 tmp_ima = cpl_image_duplicate(cpl_imagelist_get(abba, 2*i+1));
1206 cpl_image_subtract(tmp_ima, cpl_imagelist_get(abba, 2*i));
1207 cpl_imagelist_set(nodded, tmp_ima, 2*i+1);
1211 ref_off = cpl_vector_get(*nodded_off, 0);
1212 cpl_vector_subtract_scalar(*nodded_off, ref_off);
1224 static cpl_imagelist * naco_spc_jitter_distor(
1225 cpl_imagelist * ilist,
1228 const char * fctid =
"naco_spc_jitter_distor";
1229 cpl_polynomial * arc_poly;
1230 cpl_polynomial * sttr_poly;
1233 cpl_vector * profile;
1234 cpl_imagelist * warped_list;
1239 if (ilist == NULL)
return NULL;
1240 if (arc == NULL)
return NULL;
1243 arc_poly = cpl_polynomial_new(2);
1245 cpl_msg_info(fctid,
"Get the arc distortion from the file");
1246 if ((tab = cpl_table_load(arc, 1, 0)) == NULL) {
1247 cpl_msg_error(fctid,
"cannot load the arc table");
1248 cpl_polynomial_delete(arc_poly);
1251 for (i=0 ; i<cpl_table_get_nrow(tab) ; i++) {
1252 pow[0] = cpl_table_get_int(tab,
"Degree_of_x", i, NULL);
1253 pow[1] = cpl_table_get_int(tab,
"Degree_of_y", i, NULL);
1254 cpl_polynomial_set_coeff(arc_poly, pow,
1255 cpl_table_get_double(tab,
"poly2d_coef", i, NULL));
1257 cpl_table_delete(tab);
1259 cpl_msg_info(fctid,
"Use the ID polynomial for the arc dist");
1262 cpl_polynomial_set_coeff(arc_poly, pow, 1.0);
1266 sttr_poly = cpl_polynomial_new(2);
1267 cpl_msg_info(fctid,
"Use the ID polynomial for the startrace dist");
1270 cpl_polynomial_set_coeff(sttr_poly, pow, 1.0);
1273 profile = cpl_vector_new(CPL_KERNEL_DEF_SAMPLES);
1274 cpl_vector_fill_kernel_profile(profile, CPL_KERNEL_DEFAULT,
1275 CPL_KERNEL_DEF_WIDTH);
1278 warped_list = cpl_imagelist_new();
1279 for (i=0 ; i<cpl_imagelist_get_size(ilist) ; i++) {
1280 warped = cpl_image_duplicate(cpl_imagelist_get(ilist, i));
1281 if (cpl_image_warp_polynomial(warped, cpl_imagelist_get(ilist, i),
1282 arc_poly, sttr_poly, profile, CPL_KERNEL_DEF_WIDTH, profile,
1283 CPL_KERNEL_DEF_WIDTH) != CPL_ERROR_NONE) {
1284 cpl_msg_error(fctid,
"cannot correct the distortion");
1285 cpl_image_delete(warped);
1286 cpl_polynomial_delete(arc_poly);
1287 cpl_polynomial_delete(sttr_poly);
1288 cpl_vector_delete(profile);
1291 cpl_imagelist_set(warped_list, warped, i);
1293 cpl_vector_delete(profile);
1294 cpl_polynomial_delete(arc_poly);
1295 cpl_polynomial_delete(sttr_poly);
1307 static double naco_spc_jitter_refine_offset(
1314 if (ima1 == NULL)
return 10000.0;
1315 if (ima2 == NULL)
return 10000.0;
1318 if (irplib_spectrum_find_brightest(ima1, 0.0, NO_SHADOW, 0.0, 1,
1322 if (irplib_spectrum_find_brightest(ima2, 0.0, NO_SHADOW, 0.0, 1,
1336 static cpl_table * naco_spc_jitter_extract(cpl_image * combined)
1338 const char * fctid =
"naco_spc_jitter_extract";
1339 int le_dist, ri_dist, le_width, ri_width, spec_pos;
1342 int le_side, ri_side;
1351 cpl_bivector * toplot;
1357 if (combined == NULL)
return NULL;
1360 nx = cpl_image_get_size_x(combined);
1361 ny = cpl_image_get_size_y(combined);
1362 le_dist = naco_spc_jitter_config.extr_sky_le_dist;
1363 ri_dist = naco_spc_jitter_config.extr_sky_ri_dist;
1364 le_width = naco_spc_jitter_config.extr_sky_le_width;
1365 ri_width = naco_spc_jitter_config.extr_sky_ri_width;
1366 spec_pos = naco_spc_jitter_config.extr_spec_pos;
1370 if (naco_spc_jitter_config.throws == NULL) {
1371 cpl_msg_error(fctid,
"Need a throw value to detect the spectra !!");
1375 for (i=0 ; i<cpl_vector_get_size(naco_spc_jitter_config.throws) ; i++){
1376 throw = (int)cpl_vector_get(naco_spc_jitter_config.throws, i);
1377 if ((res = irplib_spectrum_find_brightest(combined,
throw,
1378 TWO_SHADOWS, 0.0, 1, &pos)) == 0)
break;
1379 if ((res = irplib_spectrum_find_brightest(combined,
throw,
1380 ONE_SHADOW, 0.0, 1, &pos)) == 0)
break;
1383 cpl_msg_error(fctid,
"Cannot detect the spectrum");
1386 spec_pos = (int)pos;
1387 cpl_msg_info(fctid,
"Spectrum detected at x = %d", spec_pos);
1393 le_side = spec_pos - (int)(naco_spc_jitter_config.extr_spec_width/2);
1394 ri_side = le_side + naco_spc_jitter_config.extr_spec_width;
1395 if ((le_side < 1) || (ri_side > nx)) {
1396 cpl_msg_error(fctid,
"Spectrum zone falls outside the image");
1400 if (le_dist < 0) le_dist = 2 * naco_spc_jitter_config.extr_spec_width;
1401 if (ri_dist < 0) ri_dist = 2 * naco_spc_jitter_config.extr_spec_width;
1402 sky_pos[1] = spec_pos - le_dist;
1403 sky_pos[0] = sky_pos[1] - le_width;
1404 sky_pos[2] = spec_pos + ri_dist;
1405 sky_pos[3] = sky_pos[2] + ri_width;
1408 sky = cpl_vector_new(nx);
1409 psky = cpl_vector_get_data(sky);
1410 if (((sky_pos[0] < 1) || (le_width == 0)) &&
1411 ((sky_pos[3] <= nx) && (ri_width > 0))) {
1412 for (i=0 ; i<ny ; i++) {
1413 psky[i] = cpl_image_get_median_window(combined, sky_pos[2], i+1,
1416 }
else if (((sky_pos[3] > nx) || (ri_width == 0))
1417 && ((sky_pos[0] > 0) && (le_width > 0))) {
1418 for (i=0 ; i<ny ; i++) {
1419 psky[i] = cpl_image_get_median_window(combined, sky_pos[0], i+1,
1422 }
else if ((le_width != 0) && (ri_width != 0)
1423 && (sky_pos[0] > 0) && (sky_pos[3] <= nx)) {
1424 for (i=0 ; i<ny ; i++) {
1425 psky[i] = cpl_image_get_median_window(combined, sky_pos[2], i+1,
1427 psky[i] += cpl_image_get_median_window(combined, sky_pos[0], i+1,
1436 spec = cpl_vector_new(ny);
1437 pspec = cpl_vector_get_data(spec);
1438 for (i=0 ; i<ny ; i++) {
1439 pspec[i] = cpl_image_get_flux_window(combined, le_side, i+1, ri_side,
1441 pspec[i] -= psky[i] * naco_spc_jitter_config.extr_spec_width;
1445 wl = cpl_vector_new(ny);
1446 pwl = cpl_vector_get_data(wl);
1447 for (i=0 ; i<ny ; i++) {
1458 if (naco_spc_jitter_config.display) {
1459 toplot = cpl_bivector_wrap_vectors(wl, spec);
1460 cpl_plot_bivector(NULL,
"t 'Spectrum' w lines", NULL, toplot);
1461 cpl_bivector_unwrap_vectors(toplot);
1462 toplot = cpl_bivector_wrap_vectors(wl, sky);
1463 cpl_plot_bivector(NULL,
"t 'Sky' w lines", NULL, toplot);
1464 cpl_bivector_unwrap_vectors(toplot);
1468 out = cpl_table_new(nx);
1469 cpl_table_new_column(out,
"Y_coordinate", CPL_TYPE_DOUBLE);
1470 cpl_table_new_column(out,
"Extracted_spectrum_value", CPL_TYPE_DOUBLE);
1471 cpl_table_new_column(out,
"Sky_spectrum", CPL_TYPE_DOUBLE);
1472 for (i=0 ; i<nx ; i++) {
1473 cpl_table_set_double(out,
"Y_coordinate", i, pwl[i]);
1474 cpl_table_set_double(out,
"Extracted_spectrum_value", i, pspec[i]);
1475 cpl_table_set_double(out,
"Sky_spectrum", i, psky[i]);
1477 cpl_vector_delete(wl);
1478 cpl_vector_delete(spec);
1479 cpl_vector_delete(sky);
1493 static int naco_spc_jitter_save(
1494 const cpl_image * ima,
1495 const cpl_table * tab,
1496 cpl_parameterlist * parlist,
1499 const char * fctid =
"naco_spc_jitter_save";
1502 cpl_propertylist * plist;
1503 cpl_propertylist * qclist;
1504 cpl_propertylist * paflist;
1505 cpl_frame * ref_frame;
1506 cpl_frame * product_frame;
1511 ref_frame = cpl_frameset_get_position(set, 0);
1517 sprintf(name_o,
"naco_spc_jitter_combined.fits");
1518 cpl_msg_info(fctid,
"Writing %s" , name_o);
1521 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
1523 cpl_msg_error(fctid,
"getting header from reference frame");
1528 paflist = cpl_propertylist_new();
1529 cpl_propertylist_copy_property_regexp(paflist, plist,
1530 "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
1531 "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
1532 "ESO INS GRAT WLEN|ESO INS OPTI1 ID|ESO OBS ID|ESO OBS TARG NAME)$", 0);
1535 product_frame = cpl_frame_new();
1536 cpl_frame_set_filename(product_frame, name_o);
1537 cpl_frame_set_tag(product_frame, NACO_SPC_JITTER_COMB);
1538 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_IMAGE);
1539 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
1540 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
1543 if (cpl_dfs_setup_product_header(plist, product_frame, set, parlist,
1544 "naco_spc_jitter", PACKAGE
"/" PACKAGE_VERSION,
1545 "PRO-1.15") != CPL_ERROR_NONE) {
1546 cpl_msg_warning(fctid,
"Problem in the product DFS-compliance");
1551 cpl_propertylist_append_double(plist,
"ESO QC DISPCO1",
1552 naco_spc_jitter_config.wavecal_a0);
1553 cpl_propertylist_append_double(plist,
"ESO QC DISPCO2",
1554 naco_spc_jitter_config.wavecal_a1);
1555 cpl_propertylist_append_double(plist,
"ESO QC DISPCO3",
1556 naco_spc_jitter_config.wavecal_a2);
1557 cpl_propertylist_append_double(plist,
"ESO QC DISPCO4",
1558 naco_spc_jitter_config.wavecal_a3);
1559 cpl_propertylist_append_double(plist,
"ESO QC WLEN",
1560 naco_spc_jitter_config.wavecal_a0 +
1561 naco_spc_jitter_config.wavecal_a1 * 512 +
1562 naco_spc_jitter_config.wavecal_a2 * 512 * 512 +
1563 naco_spc_jitter_config.wavecal_a3 * 512 * 512 * 512);
1564 cpl_propertylist_append_double(plist,
"ESO QC DISP XCORR",
1565 naco_spc_jitter_config.wavecal_cc);
1566 if (naco_spc_jitter_config.wavecal_out == 0) {
1567 cpl_propertylist_append_string(plist,
"ESO QC WLMETHOD",
1569 }
else if (naco_spc_jitter_config.wavecal_out == 1) {
1570 cpl_propertylist_append_string(plist,
"ESO QC WLMETHOD",
1572 }
else if (naco_spc_jitter_config.wavecal_out == 2) {
1573 cpl_propertylist_append_string(plist,
"ESO QC WLMETHOD",
1578 qclist = cpl_propertylist_new();
1579 cpl_propertylist_copy_property_regexp(qclist, plist,
"ESO QC", 0);
1582 cpl_propertylist_update_double(plist,
"CRVAL1",
1583 naco_spc_jitter_config.wavecal_a0);
1584 cpl_propertylist_update_double(plist,
"CRVAL2", 1.0);
1585 cpl_propertylist_update_double(plist,
"CRPIX1", 1.0);
1586 cpl_propertylist_update_double(plist,
"CRPIX2", 1.0);
1587 cpl_propertylist_update_double(plist,
"CDELT1",
1588 naco_spc_jitter_config.wavecal_a1);
1589 cpl_propertylist_update_double(plist,
"CDELT2", 1.0);
1590 cpl_propertylist_update_string(plist,
"CTYPE1",
"LINEAR");
1591 cpl_propertylist_update_string(plist,
"CTYPE2",
"LINEAR");
1592 cpl_propertylist_insert_after_double(plist,
"CTYPE2",
"CD1_1",
1593 naco_spc_jitter_config.wavecal_a1);
1594 cpl_propertylist_insert_after_double(plist,
"CD1_1",
"CD1_2", 1.0);
1597 cpl_image_save(ima, name_o, CPL_BPP_DEFAULT, plist, CPL_IO_DEFAULT);
1598 cpl_propertylist_delete(plist);
1601 cpl_frameset_insert(set, product_frame);
1608 sprintf(name_o,
"naco_spc_jitter_extracted.tfits");
1609 cpl_msg_info(fctid,
"Writing %s" , name_o);
1612 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
1614 cpl_msg_error(fctid,
"getting header from reference frame");
1615 cpl_propertylist_delete(paflist);
1616 cpl_propertylist_delete(qclist);
1621 product_frame = cpl_frame_new();
1622 cpl_frame_set_filename(product_frame, name_o);
1623 cpl_frame_set_tag(product_frame, NACO_SPC_JITTER_EXTR);
1624 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_TABLE);
1625 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
1626 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
1629 if (cpl_dfs_setup_product_header(plist, product_frame, set, parlist,
1630 "naco_spc_jitter", PACKAGE
"/" PACKAGE_VERSION,
1631 "PRO-1.15") != CPL_ERROR_NONE){
1632 cpl_msg_warning(fctid,
"Problem in the product DFS-compliance");
1637 cpl_table_save(tab, plist, NULL, name_o, CPL_IO_DEFAULT);
1638 cpl_propertylist_delete(plist);
1641 cpl_frameset_insert(set, product_frame);
1649 sprintf(name_o,
"naco_spc_jitter.paf");
1650 cpl_msg_info(fctid,
"Writing %s" , name_o);
1653 if ((paf = irplib_paf_print_header(name_o,
1654 "NACO/naco_spc_jitter",
1655 "QC file")) == NULL) {
1656 cpl_msg_error(fctid,
"cannot open file [%s] for output", name_o);
1657 cpl_propertylist_delete(paflist);
1658 cpl_propertylist_delete(qclist);
1663 if (irplib_propertylist_dump_paf(paflist, paf) != CPL_ERROR_NONE) {
1664 cpl_msg_error(fctid,
"cannot dump the keys in PAF file");
1665 cpl_propertylist_delete(paflist);
1666 cpl_propertylist_delete(qclist);
1670 cpl_propertylist_delete(paflist);
1673 if (irplib_propertylist_dump_paf(qclist, paf) != CPL_ERROR_NONE) {
1674 cpl_msg_error(fctid,
"cannot dump the QC keys in PAF file");
1675 cpl_propertylist_delete(qclist);
1679 cpl_propertylist_delete(qclist);
1695 static int off_comp(
double off1,
double off2,
double thresh)
1697 if (((off1>thresh) && (off2<thresh)) || ((off1<thresh) && (off2>thresh)))
int naco_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
double naco_pfits_get_cumoffsetx(const cpl_propertylist *self)
find out the cumulative offset in X
double * naco_get_disprel_estimate(const char *filename, int poly_deg)
Estimate the instrument wavelength range.
computed_disprel * naco_spectro_compute_disprel(const cpl_image *in, int discard_lo, int discard_hi, int discard_le, int discard_ri, int remove_thermal, const char *table_name, double slit_width, int order, int output_ascii, double *phdisprel)
Compute a 3rd degree dispersion relation.