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");
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_frame(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;
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();
605 cpl_imagelist_delete(ilist);
607 cpl_vector_delete(offsets);
608 cpl_msg_indent_less();
626 cpl_msg_info(fctid,
"Create the nodded images");
627 cpl_msg_indent_more();
628 if ((nodded = naco_spc_jitter_nodded(abba, abba_off,
629 &nodded_off_x))==NULL) {
630 cpl_msg_error(fctid,
"cannot create the nodded images");
631 cpl_imagelist_delete(abba);
632 cpl_vector_delete(abba_off);
633 cpl_msg_indent_less();
636 cpl_imagelist_delete(abba);
637 cpl_msg_indent_less();
640 nima = cpl_imagelist_get_size(nodded);
641 naco_spc_jitter_config.throws = cpl_vector_new(nima);
642 for (i=0 ; i<nima/2 ; i++) {
643 throw = fabs( (cpl_vector_get(abba_off, 2*i))-
644 (cpl_vector_get(abba_off, 2*i+1)));
645 cpl_vector_set(naco_spc_jitter_config.throws, 2*i,
throw);
646 cpl_vector_set(naco_spc_jitter_config.throws, 2*i+1,
throw);
648 cpl_vector_delete(abba_off);
652 cpl_msg_info(fctid,
"Correct the distortion on nodded images");
653 cpl_msg_indent_more();
654 if ((nodded_warped = naco_spc_jitter_distor(nodded, arc)) == NULL) {
655 cpl_msg_error(fctid,
"cannot correct the distortion");
656 cpl_imagelist_delete(nodded);
657 cpl_vector_delete(nodded_off_x);
658 cpl_msg_indent_less();
661 cpl_imagelist_delete(nodded);
662 nodded = nodded_warped;
663 cpl_msg_indent_less();
667 if (naco_spc_jitter_config.saa_refine) {
668 cpl_msg_info(fctid,
"Refine the offsets");
669 pnodded_off_x = cpl_vector_get_data(nodded_off_x);
670 for (i=0 ; i<cpl_imagelist_get_size(nodded) ; i++) {
671 new_offset = naco_spc_jitter_refine_offset(
672 cpl_imagelist_get(nodded, 0),
673 cpl_imagelist_get(nodded, i));
674 if (new_offset > 5000) {
675 cpl_msg_debug(fctid,
"cannot refine the offset - keep %g",
678 if (fabs(new_offset-pnodded_off_x[i]) <
679 NACO_SPC_JITTER_OFFSET_ERR) {
680 cpl_msg_debug(fctid,
"refined offset : %g (old was %g)",
681 new_offset, pnodded_off_x[i]);
682 pnodded_off_x[i] = new_offset;
685 "refined offset %g too different - keep %g",
686 new_offset, pnodded_off_x[i]);
694 nodded_off_y = cpl_vector_duplicate(nodded_off_x);
695 cpl_vector_fill(nodded_off_y, 0.0);
696 nodded_offsets = cpl_bivector_wrap_vectors(nodded_off_x, nodded_off_y);
698 cpl_msg_info(fctid,
"Apply the shift and add on the nodded frames");
699 nima = cpl_imagelist_get_size(nodded);
700 if ((combined = cpl_geom_img_offset_saa(nodded, nodded_offsets,
702 (
int)(naco_spc_jitter_config.saa_rej_low * nima),
703 (
int)(naco_spc_jitter_config.saa_rej_high * nima),
704 CPL_GEOM_FIRST, NULL, NULL)) == NULL) {
705 cpl_msg_error(fctid,
"Cannot shift and add group");
706 cpl_imagelist_delete(nodded);
707 cpl_bivector_unwrap_vectors(nodded_offsets);
708 cpl_vector_delete(nodded_off_x);
709 cpl_vector_delete(nodded_off_y);
712 cpl_imagelist_delete(nodded);
713 cpl_bivector_unwrap_vectors(nodded_offsets);
714 cpl_vector_delete(nodded_off_x);
715 cpl_vector_delete(nodded_off_y);
726 static cpl_vector * naco_spc_jitter_get_offsets(cpl_frameset * rawframes)
728 const char * fctid =
"naco_spc_jitter_get_offsets";
729 cpl_vector * offsets;
732 cpl_frame * cur_frame;
733 cpl_propertylist * plist;
737 if (rawframes == NULL)
return NULL;
740 nraw = cpl_frameset_get_size(rawframes);
743 offsets = cpl_vector_new(nraw);
744 pvect = cpl_vector_get_data(offsets);
745 for (i=0 ; i<nraw ; i++) {
746 cur_frame = cpl_frameset_get_frame(rawframes, i);
747 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(cur_frame),
749 cpl_msg_error(fctid,
"cannot get property list");
750 cpl_vector_delete(offsets);
754 if (cpl_error_get_code()) {
755 cpl_msg_error(fctid,
"cannot get the offset from the header");
756 cpl_vector_delete(offsets);
757 cpl_propertylist_delete(plist);
760 cpl_propertylist_delete(plist);
804 static int * naco_spc_jitter_classif(
805 cpl_vector * offsets,
808 const char * fctid =
"naco_spc_jitter_classif";
811 double offset_thresh;
812 cpl_vector * tmp_vec;
818 if (offsets == NULL)
return NULL;
821 nraw = cpl_vector_get_size(offsets);
824 tmp_vec = cpl_vector_duplicate(offsets);
825 cpl_vector_sort(tmp_vec, 1);
826 pvect = cpl_vector_get_data(tmp_vec);
827 if (pvect[0] == pvect[nraw-1]) {
828 cpl_msg_error(fctid,
"Only one offset in the list - abort");
829 cpl_vector_delete(tmp_vec);
832 offset_thresh = (pvect[0] + pvect[nraw-1]) / 2.0;
833 cpl_vector_delete(tmp_vec);
836 pvect = cpl_vector_get_data(offsets);
838 groups = cpl_calloc(nraw,
sizeof(
int));
846 (!off_comp(pvect[i], pvect[i+j], offset_thresh))) j++;
848 if (i+j >= nraw) i = nraw;
852 while ((i+j+k < nraw)
853 && (!off_comp(pvect[i+j], pvect[i+j+k], offset_thresh))
857 for (l=i+j+k ; l<nraw ; l++) {
858 if (off_comp(pvect[i+j], pvect[l], offset_thresh)) {
864 if (last_group == 0) {
865 for (l=0 ; l<j ; l++) groups[i+l] = *ngroups + 1;
866 for (l=0 ; l<k ; l++) groups[i+j+l] = *ngroups + 2;
870 for (l=0 ; l<j ; l++) groups[i+l] = *ngroups + 1;
871 for (l=0 ; l<nraw - (i+j) ; l++) groups[i+j+l] =*ngroups + 2;
880 cpl_msg_error(fctid,
"Odd number of groups found");
920 static cpl_imagelist * naco_spc_jitter_saa_groups(
921 cpl_imagelist * ilist,
922 cpl_vector * offsets,
925 cpl_vector ** abba_off)
927 const char * fctid =
"naco_spc_jitter_saa_groups";
928 cpl_imagelist * abba;
929 cpl_imagelist * group_list;
931 cpl_image ** combined;
932 cpl_bivector * group_off;
941 if ((ilist == NULL) || (offsets == NULL) || (groups == NULL))
return NULL;
944 nima = cpl_imagelist_get_size(ilist);
945 poffsets = cpl_vector_get_data(offsets);
948 abba = cpl_imagelist_new();
949 *abba_off = cpl_vector_new(ngroups);
950 pabba_off = cpl_vector_get_data(*abba_off);
953 for (i=0 ; i<ngroups ; i++) {
957 group_list = cpl_imagelist_new();
959 for (j=0 ; j<nima ; j++) {
960 if (i+1 == groups[j]) {
962 if (k==0) pabba_off[i] = poffsets[j];
964 if (fabs(pabba_off[i]-poffsets[j]) > 1e-3) saa = 1;
966 tmp_ima = cpl_image_duplicate(cpl_imagelist_get(ilist, j));
967 cpl_imagelist_set(group_list, tmp_ima, k);
975 group_off = cpl_bivector_new(k);
976 cpl_vector_fill(cpl_bivector_get_y(group_off), 0.0);
977 pgroup_off = cpl_bivector_get_x_data(group_off);
979 for (j=0 ; j<nima ; j++) {
980 if (i+1 == groups[j]) {
981 pgroup_off[k] = poffsets[j];
985 cpl_vector_subtract_scalar(cpl_bivector_get_x(group_off),
988 cpl_msg_debug(fctid,
"Apply shift-and-add for group %d", i+1);
989 if ((combined = cpl_geom_img_offset_saa(group_list,
990 group_off, CPL_KERNEL_DEFAULT, 0, 0,
991 CPL_GEOM_FIRST)) == NULL) {
992 cpl_msg_error(fctid,
"Cannot shift and add group nb %d", i+1);
993 cpl_imagelist_delete(group_list);
994 cpl_bivector_delete(group_off);
995 cpl_imagelist_delete(abba);
996 cpl_vector_delete(*abba_off);
999 cpl_bivector_delete(group_off);
1000 cpl_image_delete(combined[1]);
1001 cpl_imagelist_set(abba, combined[0], i);
1005 cpl_msg_debug(fctid,
"Apply averaging for group %d", i+1);
1006 if ((tmp_ima = cpl_imagelist_collapse_create(group_list)) == NULL) {
1007 cpl_msg_error(fctid,
"Cannot average group nb %d", i+1);
1008 cpl_imagelist_delete(group_list);
1009 cpl_imagelist_delete(abba);
1010 cpl_vector_delete(*abba_off);
1013 cpl_imagelist_set(abba, tmp_ima, i);
1015 cpl_imagelist_delete(group_list);
1029 static int naco_spc_jitter_wavecal(
1034 const char * fctid =
"naco_spc_jitter_wavecal";
1035 cpl_table * arc_tab;
1037 cpl_frame * cur_frame;
1038 const char * cur_fname;
1045 cpl_msg_info(fctid,
"Get the wavelength from the ARC file");
1046 if ((arc_tab = cpl_table_load(arc, 1, 0)) == NULL) {
1047 cpl_msg_error(fctid,
"Cannot load the arc table");
1048 naco_spc_jitter_config.wavecal_out = -1;
1051 naco_spc_jitter_config.wavecal_a0 =
1052 cpl_table_get_double(arc_tab,
"WL_coefficients", 0, NULL);
1053 naco_spc_jitter_config.wavecal_a1 =
1054 cpl_table_get_double(arc_tab,
"WL_coefficients", 1, NULL);
1055 naco_spc_jitter_config.wavecal_a2 =
1056 cpl_table_get_double(arc_tab,
"WL_coefficients", 2, NULL);
1057 naco_spc_jitter_config.wavecal_a3 =
1058 cpl_table_get_double(arc_tab,
"WL_coefficients", 3, NULL);
1059 cpl_table_delete(arc_tab);
1060 naco_spc_jitter_config.wavecal_out = 2;
1061 naco_spc_jitter_config.wavecal_cc = -1.0;
1066 cur_frame = cpl_frameset_get_frame(raw, 0);
1067 cur_fname = cpl_frame_get_filename(cur_frame);
1070 cpl_msg_info(fctid,
"Compute the physical model");
1071 cpl_msg_indent_more();
1073 cpl_msg_error(fctid,
"cannot compute the physical model");
1074 naco_spc_jitter_config.wavecal_out = -1;
1075 cpl_msg_indent_less();
1078 cpl_msg_info(fctid,
"f(x)=%g + %g*x + %g*x^2 + %g*x^3",
1079 phdisprel[0], phdisprel[1], phdisprel[2], phdisprel[3]);
1080 naco_spc_jitter_config.wavecal_a0 = phdisprel[0];
1081 naco_spc_jitter_config.wavecal_a1 = phdisprel[1];
1082 naco_spc_jitter_config.wavecal_a2 = phdisprel[2];
1083 naco_spc_jitter_config.wavecal_a3 = phdisprel[3];
1084 naco_spc_jitter_config.wavecal_cc = -1.0;
1085 naco_spc_jitter_config.wavecal_out = 0;
1086 cpl_msg_indent_less();
1089 if (naco_spc_jitter_config.wavecal_in == 1) {
1091 if ((slit_width = naco_get_slitwidth(cur_fname)) == -1) {
1092 cpl_msg_warning(fctid,
"cannot get the slit width");
1093 cpl_free(phdisprel);
1097 if ((order = naco_find_order(cur_fname)) == -1) {
1098 cpl_msg_warning(fctid,
"cannot get the order");
1099 cpl_free(phdisprel);
1103 cpl_msg_info(fctid,
"Compute the wavelength with the sky lines");
1104 cpl_msg_indent_more();
1106 naco_spc_jitter_config.wavecal_rej_bottom,
1107 naco_spc_jitter_config.wavecal_rej_top,
1108 naco_spc_jitter_config.wavecal_rej_left,
1109 naco_spc_jitter_config.wavecal_rej_right,
1110 naco_has_thermal(cur_fname) > 0,
1111 "oh", slit_width, order,
1112 (
int)(cpl_msg_get_level() == CPL_MSG_DEBUG),
1113 phdisprel)) == NULL) {
1114 cpl_msg_error(fctid,
"cannot compute the dispersion relation");
1115 cpl_free(phdisprel);
1116 cpl_msg_indent_less();
1119 cpl_msg_info(fctid,
"Cross correlation factor: %g", disprel->cc);
1120 cpl_msg_info(fctid,
"f(x)=%g + %g*x + %g*x^2 + %g*x^3",
1121 disprel->poly[0], disprel->poly[1], disprel->poly[2],
1123 naco_spc_jitter_config.wavecal_a0 = disprel->poly[0];
1124 naco_spc_jitter_config.wavecal_a1 = disprel->poly[1];
1125 naco_spc_jitter_config.wavecal_a2 = disprel->poly[2];
1126 naco_spc_jitter_config.wavecal_a3 = disprel->poly[3];
1127 naco_spc_jitter_config.wavecal_cc = disprel->cc;
1128 naco_spc_jitter_config.wavecal_out = 1;
1129 if (disprel->poly != NULL) cpl_free(disprel->poly);
1131 cpl_msg_indent_less();
1133 cpl_free(phdisprel);
1170 static cpl_imagelist * naco_spc_jitter_nodded(
1171 cpl_imagelist * abba,
1172 cpl_vector * abba_off,
1173 cpl_vector ** nodded_off)
1175 const char * fctid =
"naco_spc_jitter_nodded";
1176 cpl_imagelist * nodded;
1177 cpl_image * tmp_ima;
1180 double * pnodded_off;
1185 if ((abba == NULL) || (abba_off == NULL))
return NULL;
1188 nima = cpl_imagelist_get_size(abba);
1190 cpl_msg_error(fctid,
"Number of images should be even");
1195 *nodded_off = cpl_vector_duplicate(abba_off);
1197 nodded = cpl_imagelist_new();
1198 for (i=0 ; i<(nima/2) ; i++) {
1200 tmp_ima = cpl_image_duplicate(cpl_imagelist_get(abba, 2*i));
1201 cpl_image_subtract(tmp_ima, cpl_imagelist_get(abba, 2*i+1));
1202 cpl_imagelist_set(nodded, tmp_ima, 2*i);
1204 tmp_ima = cpl_image_duplicate(cpl_imagelist_get(abba, 2*i+1));
1205 cpl_image_subtract(tmp_ima, cpl_imagelist_get(abba, 2*i));
1206 cpl_imagelist_set(nodded, tmp_ima, 2*i+1);
1210 ref_off = cpl_vector_get(*nodded_off, 0);
1211 cpl_vector_subtract_scalar(*nodded_off, ref_off);
1223 static cpl_imagelist * naco_spc_jitter_distor(
1224 cpl_imagelist * ilist,
1227 const char * fctid =
"naco_spc_jitter_distor";
1228 cpl_polynomial * arc_poly;
1229 cpl_polynomial * sttr_poly;
1232 cpl_vector * profile;
1233 cpl_imagelist * warped_list;
1238 if (ilist == NULL)
return NULL;
1239 if (arc == NULL)
return NULL;
1242 arc_poly = cpl_polynomial_new(2);
1244 cpl_msg_info(fctid,
"Get the arc distortion from the file");
1245 if ((tab = cpl_table_load(arc, 1, 0)) == NULL) {
1246 cpl_msg_error(fctid,
"cannot load the arc table");
1247 cpl_polynomial_delete(arc_poly);
1250 for (i=0 ; i<cpl_table_get_nrow(tab) ; i++) {
1251 pow[0] = cpl_table_get_int(tab,
"Degree_of_x", i, NULL);
1252 pow[1] = cpl_table_get_int(tab,
"Degree_of_y", i, NULL);
1253 cpl_polynomial_set_coeff(arc_poly, pow,
1254 cpl_table_get_double(tab,
"poly2d_coef", i, NULL));
1256 cpl_table_delete(tab);
1258 cpl_msg_info(fctid,
"Use the ID polynomial for the arc dist");
1261 cpl_polynomial_set_coeff(arc_poly, pow, 1.0);
1265 sttr_poly = cpl_polynomial_new(2);
1266 cpl_msg_info(fctid,
"Use the ID polynomial for the startrace dist");
1269 cpl_polynomial_set_coeff(sttr_poly, pow, 1.0);
1272 profile = cpl_vector_new(CPL_KERNEL_DEF_SAMPLES);
1273 cpl_vector_fill_kernel_profile(profile, CPL_KERNEL_DEFAULT,
1274 CPL_KERNEL_DEF_WIDTH);
1277 warped_list = cpl_imagelist_new();
1278 for (i=0 ; i<cpl_imagelist_get_size(ilist) ; i++) {
1279 warped = cpl_image_duplicate(cpl_imagelist_get(ilist, i));
1280 if (cpl_image_warp_polynomial(warped, cpl_imagelist_get(ilist, i),
1281 arc_poly, sttr_poly, profile, CPL_KERNEL_DEF_WIDTH, profile,
1282 CPL_KERNEL_DEF_WIDTH) != CPL_ERROR_NONE) {
1283 cpl_msg_error(fctid,
"cannot correct the distortion");
1284 cpl_image_delete(warped);
1285 cpl_polynomial_delete(arc_poly);
1286 cpl_polynomial_delete(sttr_poly);
1287 cpl_vector_delete(profile);
1290 cpl_imagelist_set(warped_list, warped, i);
1292 cpl_vector_delete(profile);
1293 cpl_polynomial_delete(arc_poly);
1294 cpl_polynomial_delete(sttr_poly);
1306 static double naco_spc_jitter_refine_offset(
1313 if (ima1 == NULL)
return 10000.0;
1314 if (ima2 == NULL)
return 10000.0;
1335 static cpl_table * naco_spc_jitter_extract(cpl_image * combined)
1337 const char * fctid =
"naco_spc_jitter_extract";
1338 int le_dist, ri_dist, le_width, ri_width, spec_pos;
1341 int le_side, ri_side;
1350 cpl_bivector * toplot;
1356 if (combined == NULL)
return NULL;
1359 nx = cpl_image_get_size_x(combined);
1360 ny = cpl_image_get_size_y(combined);
1361 le_dist = naco_spc_jitter_config.extr_sky_le_dist;
1362 ri_dist = naco_spc_jitter_config.extr_sky_ri_dist;
1363 le_width = naco_spc_jitter_config.extr_sky_le_width;
1364 ri_width = naco_spc_jitter_config.extr_sky_ri_width;
1365 spec_pos = naco_spc_jitter_config.extr_spec_pos;
1369 if (naco_spc_jitter_config.throws == NULL) {
1370 cpl_msg_error(fctid,
"Need a throw value to detect the spectra !!");
1374 for (i=0 ; i<cpl_vector_get_size(naco_spc_jitter_config.throws) ; i++){
1375 throw = (int)cpl_vector_get(naco_spc_jitter_config.throws, i);
1377 TWO_SHADOWS, 0.0, 1, &pos)) == 0)
break;
1379 ONE_SHADOW, 0.0, 1, &pos)) == 0)
break;
1382 cpl_msg_error(fctid,
"Cannot detect the spectrum");
1385 spec_pos = (int)pos;
1386 cpl_msg_info(fctid,
"Spectrum detected at x = %d", spec_pos);
1392 le_side = spec_pos - (int)(naco_spc_jitter_config.extr_spec_width/2);
1393 ri_side = le_side + naco_spc_jitter_config.extr_spec_width;
1394 if ((le_side < 1) || (ri_side > nx)) {
1395 cpl_msg_error(fctid,
"Spectrum zone falls outside the image");
1399 if (le_dist < 0) le_dist = 2 * naco_spc_jitter_config.extr_spec_width;
1400 if (ri_dist < 0) ri_dist = 2 * naco_spc_jitter_config.extr_spec_width;
1401 sky_pos[1] = spec_pos - le_dist;
1402 sky_pos[0] = sky_pos[1] - le_width;
1403 sky_pos[2] = spec_pos + ri_dist;
1404 sky_pos[3] = sky_pos[2] + ri_width;
1407 sky = cpl_vector_new(nx);
1408 psky = cpl_vector_get_data(sky);
1409 if (((sky_pos[0] < 1) || (le_width == 0)) &&
1410 ((sky_pos[3] <= nx) && (ri_width > 0))) {
1411 for (i=0 ; i<ny ; i++) {
1412 psky[i] = cpl_image_get_median_window(combined, sky_pos[2], i+1,
1415 }
else if (((sky_pos[3] > nx) || (ri_width == 0))
1416 && ((sky_pos[0] > 0) && (le_width > 0))) {
1417 for (i=0 ; i<ny ; i++) {
1418 psky[i] = cpl_image_get_median_window(combined, sky_pos[0], i+1,
1421 }
else if ((le_width != 0) && (ri_width != 0)
1422 && (sky_pos[0] > 0) && (sky_pos[3] <= nx)) {
1423 for (i=0 ; i<ny ; i++) {
1424 psky[i] = cpl_image_get_median_window(combined, sky_pos[2], i+1,
1426 psky[i] += cpl_image_get_median_window(combined, sky_pos[0], i+1,
1435 spec = cpl_vector_new(ny);
1436 pspec = cpl_vector_get_data(spec);
1437 for (i=0 ; i<ny ; i++) {
1438 pspec[i] = cpl_image_get_flux_window(combined, le_side, i+1, ri_side,
1440 pspec[i] -= psky[i] * naco_spc_jitter_config.extr_spec_width;
1444 wl = cpl_vector_new(ny);
1445 pwl = cpl_vector_get_data(wl);
1446 for (i=0 ; i<ny ; i++) {
1457 if (naco_spc_jitter_config.display) {
1458 toplot = cpl_bivector_wrap_vectors(wl, spec);
1459 cpl_plot_bivector(NULL,
"t 'Spectrum' w lines", NULL, toplot);
1460 cpl_bivector_unwrap_vectors(toplot);
1461 toplot = cpl_bivector_wrap_vectors(wl, sky);
1462 cpl_plot_bivector(NULL,
"t 'Sky' w lines", NULL, toplot);
1463 cpl_bivector_unwrap_vectors(toplot);
1467 out = cpl_table_new(nx);
1468 cpl_table_new_column(out,
"Y_coordinate", CPL_TYPE_DOUBLE);
1469 cpl_table_new_column(out,
"Extracted_spectrum_value", CPL_TYPE_DOUBLE);
1470 cpl_table_new_column(out,
"Sky_spectrum", CPL_TYPE_DOUBLE);
1471 for (i=0 ; i<nx ; i++) {
1472 cpl_table_set_double(out,
"Y_coordinate", i, pwl[i]);
1473 cpl_table_set_double(out,
"Extracted_spectrum_value", i, pspec[i]);
1474 cpl_table_set_double(out,
"Sky_spectrum", i, psky[i]);
1476 cpl_vector_delete(wl);
1477 cpl_vector_delete(spec);
1478 cpl_vector_delete(sky);
1492 static int naco_spc_jitter_save(
1493 const cpl_image * ima,
1494 const cpl_table * tab,
1495 cpl_parameterlist * parlist,
1498 const char * fctid =
"naco_spc_jitter_save";
1501 cpl_propertylist * plist;
1502 cpl_propertylist * qclist;
1503 cpl_propertylist * paflist;
1504 cpl_frame * ref_frame;
1505 cpl_frame * product_frame;
1510 ref_frame = cpl_frameset_get_frame(set, 0);
1516 sprintf(name_o,
"naco_spc_jitter_combined.fits");
1517 cpl_msg_info(fctid,
"Writing %s" , name_o);
1520 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
1522 cpl_msg_error(fctid,
"getting header from reference frame");
1527 paflist = cpl_propertylist_new();
1528 cpl_propertylist_copy_property_regexp(paflist, plist,
1529 "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
1530 "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
1531 "ESO INS GRAT WLEN|ESO INS OPTI1 ID|ESO OBS ID|ESO OBS TARG NAME)$", 0);
1534 product_frame = cpl_frame_new();
1535 cpl_frame_set_filename(product_frame, name_o);
1536 cpl_frame_set_tag(product_frame, NACO_SPC_JITTER_COMB);
1537 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_IMAGE);
1538 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
1539 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
1542 if (cpl_dfs_setup_product_header(plist, product_frame, set, parlist,
1543 "naco_spc_jitter", PACKAGE
"/" PACKAGE_VERSION,
1544 "PRO-1.15") != CPL_ERROR_NONE) {
1545 cpl_msg_warning(fctid,
"Problem in the product DFS-compliance");
1550 cpl_propertylist_append_double(plist,
"ESO QC DISPCO1",
1551 naco_spc_jitter_config.wavecal_a0);
1552 cpl_propertylist_append_double(plist,
"ESO QC DISPCO2",
1553 naco_spc_jitter_config.wavecal_a1);
1554 cpl_propertylist_append_double(plist,
"ESO QC DISPCO3",
1555 naco_spc_jitter_config.wavecal_a2);
1556 cpl_propertylist_append_double(plist,
"ESO QC DISPCO4",
1557 naco_spc_jitter_config.wavecal_a3);
1558 cpl_propertylist_append_double(plist,
"ESO QC WLEN",
1559 naco_spc_jitter_config.wavecal_a0 +
1560 naco_spc_jitter_config.wavecal_a1 * 512 +
1561 naco_spc_jitter_config.wavecal_a2 * 512 * 512 +
1562 naco_spc_jitter_config.wavecal_a3 * 512 * 512 * 512);
1563 cpl_propertylist_append_double(plist,
"ESO QC DISP XCORR",
1564 naco_spc_jitter_config.wavecal_cc);
1565 if (naco_spc_jitter_config.wavecal_out == 0) {
1566 cpl_propertylist_append_string(plist,
"ESO QC WLMETHOD",
1568 }
else if (naco_spc_jitter_config.wavecal_out == 1) {
1569 cpl_propertylist_append_string(plist,
"ESO QC WLMETHOD",
1571 }
else if (naco_spc_jitter_config.wavecal_out == 2) {
1572 cpl_propertylist_append_string(plist,
"ESO QC WLMETHOD",
1577 qclist = cpl_propertylist_new();
1578 cpl_propertylist_copy_property_regexp(qclist, plist,
"ESO QC", 0);
1581 cpl_propertylist_update_double(plist,
"CRVAL1",
1582 naco_spc_jitter_config.wavecal_a0);
1583 cpl_propertylist_update_double(plist,
"CRVAL2", 1.0);
1584 cpl_propertylist_update_double(plist,
"CRPIX1", 1.0);
1585 cpl_propertylist_update_double(plist,
"CRPIX2", 1.0);
1586 cpl_propertylist_update_double(plist,
"CDELT1",
1587 naco_spc_jitter_config.wavecal_a1);
1588 cpl_propertylist_update_double(plist,
"CDELT2", 1.0);
1589 cpl_propertylist_update_string(plist,
"CTYPE1",
"LINEAR");
1590 cpl_propertylist_update_string(plist,
"CTYPE2",
"LINEAR");
1591 cpl_propertylist_insert_after_double(plist,
"CTYPE2",
"CD1_1",
1592 naco_spc_jitter_config.wavecal_a1);
1593 cpl_propertylist_insert_after_double(plist,
"CD1_1",
"CD1_2", 1.0);
1596 cpl_image_save(ima, name_o, CPL_BPP_DEFAULT, plist, CPL_IO_DEFAULT);
1597 cpl_propertylist_delete(plist);
1600 cpl_frameset_insert(set, product_frame);
1607 sprintf(name_o,
"naco_spc_jitter_extracted.tfits");
1608 cpl_msg_info(fctid,
"Writing %s" , name_o);
1611 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
1613 cpl_msg_error(fctid,
"getting header from reference frame");
1614 cpl_propertylist_delete(paflist);
1615 cpl_propertylist_delete(qclist);
1620 product_frame = cpl_frame_new();
1621 cpl_frame_set_filename(product_frame, name_o);
1622 cpl_frame_set_tag(product_frame, NACO_SPC_JITTER_EXTR);
1623 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_TABLE);
1624 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
1625 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
1628 if (cpl_dfs_setup_product_header(plist, product_frame, set, parlist,
1629 "naco_spc_jitter", PACKAGE
"/" PACKAGE_VERSION,
1630 "PRO-1.15") != CPL_ERROR_NONE){
1631 cpl_msg_warning(fctid,
"Problem in the product DFS-compliance");
1636 cpl_table_save(tab, plist, NULL, name_o, CPL_IO_DEFAULT);
1637 cpl_propertylist_delete(plist);
1640 cpl_frameset_insert(set, product_frame);
1648 sprintf(name_o,
"naco_spc_jitter.paf");
1649 cpl_msg_info(fctid,
"Writing %s" , name_o);
1652 if ((paf = irplib_paf_print_header(name_o,
1653 "NACO/naco_spc_jitter",
1654 "QC file")) == NULL) {
1655 cpl_msg_error(fctid,
"cannot open file [%s] for output", name_o);
1656 cpl_propertylist_delete(paflist);
1657 cpl_propertylist_delete(qclist);
1662 if (irplib_propertylist_dump_paf(paflist, paf) != CPL_ERROR_NONE) {
1663 cpl_msg_error(fctid,
"cannot dump the keys in PAF file");
1664 cpl_propertylist_delete(paflist);
1665 cpl_propertylist_delete(qclist);
1669 cpl_propertylist_delete(paflist);
1672 if (irplib_propertylist_dump_paf(qclist, paf) != CPL_ERROR_NONE) {
1673 cpl_msg_error(fctid,
"cannot dump the QC keys in PAF file");
1674 cpl_propertylist_delete(qclist);
1678 cpl_propertylist_delete(qclist);
1694 static int off_comp(
double off1,
double off2,
double thresh)
1696 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
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.
int irplib_spectrum_find_brightest(const cpl_image *in, int offset, spec_shadows shadows, double min_bright, int orient, double *pos)
Finds the brightest spectrum in an image.
int irplib_compare_tags(cpl_frame *frame1, cpl_frame *frame2)
Comparison function to identify different input frames.
double * naco_get_disprel_estimate(const char *filename, int poly_deg)
Estimate the instrument wavelength range.