31#include "moo_sub_sky_stare.h"
32#include "moo_fibres_table.h"
36#include "moo_badpix.h"
38#include "moo_skycorr.h"
53_moo_create_median_sky(cpl_array *sky_indexes,
int *indexrbn, hdrl_image *rbn)
55 hdrl_image *median_sky = NULL;
57 cpl_ensure(rbn != NULL, CPL_ERROR_NULL_INPUT, NULL);
58 cpl_ensure(sky_indexes != NULL, CPL_ERROR_NULL_INPUT, NULL);
60 int nx = hdrl_image_get_size_x(rbn);
61 int nb_sky = (int)cpl_array_get_size(sky_indexes);
64 hdrl_image *allsky_img = hdrl_image_new(nx, nb_sky);
65 if (allsky_img == NULL) {
69 for (
int i = 1; i <= nb_sky; i++) {
70 int idx = cpl_array_get_cplsize(sky_indexes, i - 1, NULL);
71 int rbn_idx = indexrbn[idx];
73 for (
int j = 1; j <= nx; j++) {
75 hdrl_value rbn_img_val =
76 hdrl_image_get_pixel(rbn, j, rbn_idx, &rej);
79 hdrl_image_reject(allsky_img, j, i);
82 hdrl_image_set_pixel(allsky_img, j, i, rbn_img_val);
88 hdrl_image_delete(allsky_img);
91 median_sky = hdrl_image_new(nx, 1);
125 double obj_targalpha,
126 double obj_targdelta,
127 cpl_table *target_table,
128 const char *index_colname,
129 cpl_table *sky_stare_table,
136 int target_table_idx,
138 cpl_array *allsky_indexes)
140 cpl_array *sky_indexes = NULL;
142 cpl_ensure(maxdistslit >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
143 int *indexes = cpl_table_get_data_int(target_table, index_colname);
145 cpl_table_get_data_double(target_table, MOO_FIBRES_TABLE_TARGALPHA);
147 cpl_table_get_data_double(target_table, MOO_FIBRES_TABLE_TARGDELTA);
148 sky_indexes = cpl_array_duplicate(allsky_indexes);
149 int nb_sky = cpl_array_get_size(sky_indexes);
150 int nstart = cpl_table_get_nrow(sky_stare_table);
151 cpl_table_set_size(sky_stare_table, nstart + nb_sky);
152 int nstop = cpl_table_get_nrow(sky_stare_table);
154 for (
int i = nstart; i < nstop; i++) {
155 cpl_table_set_string(sky_stare_table, MOO_SKY_STARE_TARGNAME, i,
157 cpl_table_set_int(sky_stare_table, MOO_SKY_STARE_INDEXTARG, i,
159 cpl_table_set_int(sky_stare_table, MOO_SKY_STARE_INDEXRBN, i,
162 cpl_table_unselect_all(sky_stare_table);
163 cpl_array *obj_sel = NULL;
165 if (maxdistslit >= 0) {
166 cpl_table_select_all(target_table);
167 cpl_table_and_selected_int(target_table, index_colname, CPL_EQUAL_TO,
170 obj_sel = cpl_table_where_selected(target_table);
171 int tobj_idx = cpl_array_get_cplsize(obj_sel, 0, NULL);
172 cpl_array_delete(obj_sel);
175 cpl_table_get_int(target_table, MOO_FIBRES_TABLE_SPECTRO, tobj_idx,
178 for (
int i = 1; i <= nb_sky; i++) {
179 int idx = cpl_array_get_cplsize(sky_indexes, i - 1, NULL);
180 int idx_t = nstart + i - 1;
181 int sky_index = indexes[idx];
182 cpl_table_select_all(target_table);
183 cpl_table_and_selected_int(target_table, index_colname,
184 CPL_EQUAL_TO, sky_index);
185 obj_sel = cpl_table_where_selected(target_table);
186 int tsky_idx = cpl_array_get_cplsize(obj_sel, 0, NULL);
187 cpl_array_delete(obj_sel);
189 const int sky_spectro =
190 cpl_table_get_int(target_table, MOO_FIBRES_TABLE_SPECTRO,
193 cpl_table_set_int(sky_stare_table, MOO_SKY_STARE_SKYINDEXRBN, idx_t,
195 if (obj_spectro == sky_spectro) {
196 int dslit = (int)fabs((
double)sky_index - (double)obj_index);
197 cpl_table_set_int(sky_stare_table, MOO_SKY_STARE_SKYDSLIT,
200 double sky_alpha = targalpha[idx];
201 double sky_delta = targdelta[idx];
203 sky_alpha, sky_delta);
205 cpl_table_select_row(sky_stare_table, idx_t);
206 cpl_array_set_invalid(sky_indexes, i - 1);
209 else if (dslit > maxdistslit) {
210 cpl_table_select_row(sky_stare_table, idx_t);
211 cpl_array_set_invalid(sky_indexes, i - 1);
215 cpl_array_set_invalid(sky_indexes, i - 1);
216 cpl_table_select_row(sky_stare_table, idx_t);
220 int nb_valid_distslit = nb_sky - cpl_array_count_invalid(sky_indexes);
222 if (nb_valid_distslit < min_sky) {
223 cpl_array_delete(sky_indexes);
225 cpl_error_set_message(
226 "sub_sky_stare", CPL_ERROR_EOL,
227 "for indextarg %d after using filter with maxdistslit=%d : "
228 "not enough sky fibre (%d) for object indexrbn: %d",
229 indextarg, maxdistslit, nb_valid_distslit, obj_index);
233 if (f2f != NULL && mintrans > 0) {
234 cpl_array *f2f_sel = NULL;
237 for (
int i = 0; i < nb_sky; i++) {
239 int idx_t = nstart + i;
240 int idx = cpl_array_get_cplsize(sky_indexes, i, &rej);
241 int sky_index = indexes[idx];
243 cpl_table_select_all(f2f->table);
244 cpl_table_and_selected_int(f2f->table, index_colname, CPL_EQUAL_TO,
246 f2f_sel = cpl_table_where_selected(f2f->table);
247 int f2f_sky_idx = cpl_array_get_cplsize(f2f_sel, 0, NULL);
248 cpl_array_delete(f2f_sel);
251 cpl_table_get(f2f->table, f2f_trans_colname, f2f_sky_idx, NULL);
253 cpl_table_set_double(sky_stare_table, MOO_SKY_STARE_SKYTRANS, idx_t,
256 if (sky_trans < mintrans) {
257 cpl_table_select_row(sky_stare_table, idx_t);
258 cpl_array_set_invalid(sky_indexes, i);
264 int nb_valid_trans = nb_sky - cpl_array_count_invalid(sky_indexes);
265 if (nb_valid_trans < min_sky) {
266 cpl_array_delete(sky_indexes);
268 cpl_error_set_message(
269 "sub_sky_stare", CPL_ERROR_EOL,
270 "for indextarg %d after using filter with mintrans=%f : "
271 "not enough sky fibre (%d) for object indexrbn: %d",
272 indextarg, mintrans, nb_valid_trans, obj_index);
277 for (
int i = 0; i < nb_sky; i++) {
279 int idx = cpl_array_get_cplsize(sky_indexes, i, &rej);
280 int idx_t = nstart + i;
283 double sky_alpha = targalpha[idx];
284 double sky_delta = targdelta[idx];
288 d = d * CPL_MATH_DEG_RAD * 60;
289 cpl_table_set_double(sky_stare_table, MOO_SKY_STARE_RADIUS, idx_t,
291 cpl_table_set_double(sky_stare_table, MOO_SKY_STARE_SKYDIST, idx_t,
294 cpl_table_select_row(sky_stare_table, idx_t);
295 cpl_array_set_invalid(sky_indexes, i);
300 int nb_valid = nb_sky - cpl_array_count_invalid(sky_indexes);
302 if (nb_valid >= min_sky) {
303 cpl_table_erase_selected(sky_stare_table);
306 else if (step_r > 0) {
307 cpl_array_delete(sky_indexes);
308 cpl_table_set_size(sky_stare_table, nstart);
311 obj_targdelta, target_table, index_colname,
312 sky_stare_table, type, maxdistslit, mintrans,
313 min_sky, radius + step_r, step_r, target_table_idx,
314 f2f, allsky_indexes);
317 cpl_array_delete(sky_indexes);
319 cpl_error_set_message(
320 "sub_sky_stare", CPL_ERROR_EOL,
322 "filtering distslit: %d valid sky fibre, "
323 "filtering mintrans: %d valid sky fibre, "
324 "after using sky ditance filter with radius=%f : "
325 "not enough sky fibre (%d) for object indexrbn: %d",
326 indextarg, nb_valid_distslit, nb_valid_trans, radius, nb_valid,
333static moo_sci_single *
334_moo_sub_sky_stare_single(moo_rbn_single *obja_rbn_single,
335 cpl_table *obja_fibre_table,
338 moo_rbn_single *objb_rbn_single,
339 cpl_table *objb_fibre_table,
342 const cpl_frame *solflux_frame,
343 const cpl_frame *airglow_group_frame,
344 const cpl_frame *airglow_var_frame,
345 moo_sub_sky_stare_params *params,
346 cpl_array *obja_sky_indexes,
347 cpl_array *objb_sky_indexes,
348 cpl_array *targ_obj_indexes,
349 cpl_propertylist *pheader,
350 const char *filename,
353 moo_sci_single *sci_single = NULL;
354 cpl_array *valid_targets_indexes = NULL;
355 cpl_table *sky_stare_table = NULL;
356 cpl_errorstate prestate = cpl_errorstate_get();
358 cpl_ensure(obja_rbn_single != NULL, CPL_ERROR_NULL_INPUT, NULL);
359 cpl_ensure(objb_rbn_single != NULL, CPL_ERROR_NULL_INPUT, NULL);
360 cpl_ensure(target_table != NULL, CPL_ERROR_NULL_INPUT, NULL);
361 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
362 cpl_ensure(obja_sky_indexes != NULL, CPL_ERROR_NULL_INPUT, NULL);
363 cpl_ensure(objb_sky_indexes != NULL, CPL_ERROR_NULL_INPUT, NULL);
364 cpl_ensure(targ_obj_indexes != NULL, CPL_ERROR_NULL_INPUT, NULL);
366 int nb_target = (int)cpl_array_get_size(targ_obj_indexes);
368 if (nb_target == 0) {
369 cpl_msg_warning(
"sub_sky_stare",
"No targets in stare mode");
370 cpl_table_set_size(target_table->table, 0);
380 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
382 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
384 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
386 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
388 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
390 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
392 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
394 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
396 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
398 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
400 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
402 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
404 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
406 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
408 cpl_propertylist_copy_property(sci_single->header, obja_rbn_single->header,
410 int nx = hdrl_image_get_size_x(obja_rbn_single->image);
412 sci_single->image = hdrl_image_new(nx, nb_target);
413 sci_single->sky = cpl_image_new(nx, nb_target, CPL_TYPE_DOUBLE);
414 sci_single->qual = cpl_image_new(nx, nb_target, CPL_TYPE_INT);
415 sci_single->filename = filename;
417 cpl_image *sci_img = hdrl_image_get_image(sci_single->image);
419 cpl_image_get_bpm(sci_img);
421 cpl_image *sci_err_img = hdrl_image_get_error(sci_single->image);
422 cpl_image *sci_qual_img = sci_single->qual;
425 cpl_table_get_data_int(target_table->table, MOO_TARGET_TABLE_INDEXRBN);
426 int *pindexrbnt = cpl_table_get_data_int(target_table->table,
427 MOO_TARGET_TABLE_PAIREDINDEXRBN);
429 cpl_table_get_data_int(target_table->table, MOO_TARGET_TABLE_INDEXTARG);
430 const char **fibret =
431 cpl_table_get_data_string_const(target_table->table,
432 MOO_TARGET_TABLE_FIBRE);
433 const char **targnames =
434 cpl_table_get_data_string_const(target_table->table,
435 MOO_TARGET_TABLE_TARGNAME);
436 double *targalphat = cpl_table_get_data_double(target_table->table,
437 MOO_TARGET_TABLE_TARGALPHA);
438 double *targdeltat = cpl_table_get_data_double(target_table->table,
439 MOO_TARGET_TABLE_TARGDELTA);
441 const char **obstypet =
442 cpl_table_get_data_string_const(target_table->table,
443 MOO_TARGET_TABLE_OBSTYPE);
445 cpl_table_unselect_all(target_table->table);
446 for (
int i = 0; i < nb_target; i++) {
447 int obj_idx = cpl_array_get_cplsize(targ_obj_indexes, i, NULL);
448 cpl_table_set_int(target_table->table, MOO_TARGET_TABLE_INDEXTARG,
450 cpl_table_set_string(target_table->table, MOO_TARGET_TABLE_SUBSKYMODE,
451 obj_idx, MOO_TARGET_TABLE_SUBSKY_STARE);
452 const char *obstype = obstypet[obj_idx];
453 int is_stare = moo_is_obstype_stare(obstype);
455 cpl_table_set_int(target_table->table, MOO_TARGET_TABLE_NBSKY, obj_idx,
457 cpl_table_set_int(target_table->table, MOO_TARGET_TABLE_MAX_DIST_SLIT,
459 cpl_table_set_double(target_table->table, MOO_TARGET_TABLE_MEDSNRRI_SCI,
462 cpl_table_set_double(target_table->table, MOO_TARGET_TABLE_MEDSNRYJ_SCI,
464 cpl_table_set_double(target_table->table, MOO_TARGET_TABLE_MEDSNRH_SCI,
467 cpl_table_select_row(target_table->table, obj_idx);
471 valid_targets_indexes = cpl_table_where_selected(target_table->table);
472 int nb_valid_targets = cpl_array_get_size(valid_targets_indexes);
473 if (strcmp(params->method, MOO_SUB_SKY_STARE_METHOD_NONE) != 0) {
474 sky_stare_table = cpl_table_new(0);
475 cpl_table_new_column(sky_stare_table, MOO_SKY_STARE_INDEXTARG,
477 cpl_table_new_column(sky_stare_table, MOO_SKY_STARE_TARGNAME,
479 cpl_table_new_column(sky_stare_table, MOO_SKY_STARE_INDEXRBN,
481 cpl_table_new_column(sky_stare_table, MOO_SKY_STARE_SKYINDEXRBN,
483 cpl_table_new_column(sky_stare_table, MOO_SKY_STARE_SKYDSLIT,
485 cpl_table_new_column(sky_stare_table, MOO_SKY_STARE_SKYTRANS,
487 cpl_table_new_column(sky_stare_table, MOO_SKY_STARE_RADIUS,
489 cpl_table_new_column(sky_stare_table, MOO_SKY_STARE_SKYDIST,
492 cpl_table_get_data_int(target_table->table, MOO_TARGET_TABLE_NBSKY);
493 int *maxdslit = cpl_table_get_data_int(target_table->table,
494 MOO_TARGET_TABLE_MAX_DIST_SLIT);
496 cpl_table_get_data_float(target_table->table,
497 MOO_TARGET_TABLE_MAX_DIST_SKY);
499 for (
int i = 0; i < nb_valid_targets; i++) {
500 int idx = cpl_array_get_cplsize(valid_targets_indexes, i, NULL);
501 int indextarg = indexestarg[idx];
502 int indexrbn = indexrbnt[idx];
504 const char *targname = targnames[idx];
505 const char *obstype = obstypet[idx];
506 double obj_targalpha = targalphat[idx];
507 double obj_targdelta = targdeltat[idx];
508 cpl_array *sky_indexes = NULL;
509 cpl_table *obj_table = NULL;
510 cpl_table *allsky_table = target_table->table;
511 cpl_array *allsky_indexes = NULL;
512 const char *allsky_table_indexcol = MOO_FIBRES_TABLE_INDEXRBN;
514 if (strcmp(MOO_OBSTYPE_OBSNODSTARE, obstype) == 0 ||
515 strcmp(MOO_OBSTYPE_OBSPSTARE, obstype) == 0 ||
516 strcmp(MOO_OBSTYPE_SKYRESPSTARE, obstype) == 0 ||
517 (strcmp(MOO_OBSTYPE_OBSSWITCHSTARE, obstype) == 0 &&
519 obj_table = objb_fibre_table;
520 allsky_table = obja_fibre_table;
521 allsky_indexes = obja_sky_indexes;
524 obj_table = obja_fibre_table;
525 allsky_table = objb_fibre_table;
526 allsky_indexes = objb_sky_indexes;
529 cpl_table_select_all(obj_table);
530 cpl_table_and_selected_int(obj_table, MOO_FIBRES_TABLE_INDEXRBN,
531 CPL_EQUAL_TO, indexrbn);
532 cpl_array *sel = cpl_table_where_selected(obj_table);
533 int ft_idx = cpl_array_get_cplsize(sel, 0, NULL);
534 cpl_array_delete(sel);
536 cpl_table_get_string(obj_table, MOO_FIBRES_TABLE_FIBRE, ft_idx);
537 cpl_table_set_string(target_table->table, MOO_TARGET_TABLE_FIBRE,
539 moo_target_table_set_snr(target_table, idx, obj_table, ft_idx);
541 targname, indextarg, indexrbn, obj_targalpha,
542 obj_targdelta, allsky_table,
543 allsky_table_indexcol, sky_stare_table,
544 obja_rbn_single->type, params->maxdistslit,
545 params->min_trans, params->min_sky,
546 params->radius_sky, params->step_r, idx, f2f,
550 int nb_sky = cpl_table_and_selected_int(sky_stare_table,
551 MOO_SKY_STARE_INDEXTARG,
552 CPL_EQUAL_TO, indextarg);
555 float max_dsky = 0.0;
557 cpl_table *subtable =
558 cpl_table_extract_selected(sky_stare_table);
560 cpl_table_get_column_max(subtable, MOO_SKY_STARE_SKYDSLIT);
562 cpl_table_get_column_max(subtable, MOO_SKY_STARE_SKYDIST);
563 int all = cpl_array_get_size(allsky_indexes);
566 "---do %s %d %d %.3f %.3f %s => all:%d, sel:%d, %d",
567 targname, indextarg, indexrbn, obj_targalpha, obj_targdelta,
568 obstype, all, nb_sky, max_dslit);
569 cpl_table_delete(subtable);
572 maxdslit[idx] = max_dslit;
573 maxdsky[idx] = max_dsky;
574 cpl_array_delete(sky_indexes);
585#if (__GNUC__ == 9) && (__GNUC_MINOR__ < 3)
586#pragma omp parallel shared(nb_target, indexrbnt, pindexrbnt, fibret, \
587 indexestarg, target_table, obstypet, ispaired, \
588 nb_valid_targets, valid_targets_indexes, \
589 sky_stare_table, obja_rbn_single, \
590 objb_rbn_single, params, sci_single, \
591 sci_qual_img, crpix1, crval1, cd1_1, sci_img, \
592 sci_err_img, nx, airglow_var_frame, pheader, \
593 solflux_frame, airglow_group_frame, ea, eb)
595#pragma omp parallel default(none) \
596 shared(nb_target, indexrbnt, pindexrbnt, fibret, indexestarg, \
597 target_table, obstypet, ispaired, nb_valid_targets, \
598 valid_targets_indexes, sky_stare_table, obja_rbn_single, \
599 objb_rbn_single, params, sci_single, sci_qual_img, crpix1, \
600 crval1, cd1_1, sci_img, sci_err_img, nx, airglow_var_frame, \
601 pheader, solflux_frame, airglow_group_frame, ea, eb)
607 for (
int i = 0; i < nb_valid_targets; i++) {
608 hdrl_image *median_sky = NULL;
609 int idx = cpl_array_get_cplsize(valid_targets_indexes, i, NULL);
610 int rbn_idx = indexrbnt[idx];
611 int targ_idx = indexestarg[idx];
612 const char *obstype = obstypet[idx];
613 const char *fibre = fibret[idx];
614 moo_rbn_single *obj_rbn_single = NULL;
615 moo_rbn_single *sky_rbn_single = NULL;
616 double sky_rescale = 1.0;
617 const char *method = params->method;
619 if (strcmp(MOO_OBSTYPE_OBSNODSTARE, obstype) == 0 ||
620 strcmp(MOO_OBSTYPE_OBSPSTARE, obstype) == 0 ||
621 strcmp(MOO_OBSTYPE_SKYRESPSTARE, obstype) == 0 ||
622 (strcmp(MOO_OBSTYPE_OBSSWITCHSTARE, obstype) == 0 &&
624 cpl_msg_debug(__func__,
"---do B-A");
625 obj_rbn_single = objb_rbn_single;
626 sky_rbn_single = obja_rbn_single;
629 cpl_msg_debug(__func__,
"---do A-B");
630 obj_rbn_single = obja_rbn_single;
631 sky_rbn_single = objb_rbn_single;
632 sky_rescale = ea / eb;
634 cpl_image *obj_rbn_img =
635 hdrl_image_get_image(obj_rbn_single->image);
636 cpl_image *obj_rbn_err_img =
637 hdrl_image_get_error(obj_rbn_single->image);
638 cpl_image *obj_rbn_qual_img = obj_rbn_single->qual;
639 if (strcmp(method, MOO_SUB_SKY_STARE_METHOD_NONE) == 0) {
640 double *rbn_img_data = cpl_image_get_data_double(obj_rbn_img);
641 for (
int j = 1; j <= nx; j++) {
644 rbn_img_data[j - 1 + (rbn_idx - 1) * nx];
645 double sci_flux = rbn_img_val;
646 cpl_image_set(sci_img, j, targ_idx, sci_flux);
648 cpl_image_get(obj_rbn_err_img, j, rbn_idx, &rej);
649 double err = rbn_err_val;
650 cpl_image_set(sci_err_img, j, targ_idx, err);
651 double rbn_qual_val =
652 cpl_image_get(obj_rbn_qual_img, j, rbn_idx, &rej);
654 cpl_image_set(sci_qual_img, j, targ_idx, rbn_qual_val);
658 cpl_array *sky_indexes = NULL;
659 cpl_table *private_table = cpl_table_duplicate(sky_stare_table);
660 cpl_table_select_all(private_table);
662 cpl_table_get_data_int(private_table,
663 MOO_SKY_STARE_SKYINDEXRBN);
664 int nb_sky = cpl_table_and_selected_int(private_table,
665 MOO_SKY_STARE_INDEXRBN,
666 CPL_EQUAL_TO, rbn_idx);
669 cpl_table *subtable =
670 cpl_table_extract_selected(private_table);
672 cpl_table_get_column_max(subtable,
673 MOO_SKY_STARE_SKYDSLIT);
674 cpl_table_delete(subtable);
676 cpl_msg_debug(__func__,
677 "---do indextarg %d indexrbn %d nb_sky %d "
678 "max_dist_slit %d %d",
679 targ_idx, rbn_idx, nb_sky, max_dslit,
680 cpl_error_get_code());
682 sky_indexes = cpl_table_where_selected(private_table);
684 median_sky = _moo_create_median_sky(sky_indexes, sky_indexrbn,
685 sky_rbn_single->image);
687 hdrl_value srescale = { .data = sky_rescale, .error = 0 };
688 hdrl_image_mul_scalar(median_sky, srescale);
692 "no SKY fibre for fibre indexrbn %d with name %s "
696 cpl_table_delete(private_table);
697 cpl_array_delete(sky_indexes);
699 if (median_sky != NULL) {
700 if (strcmp(method, MOO_SUB_SKY_STARE_METHOD_SIMPLE) == 0) {
701 double *rbn_img_data =
702 cpl_image_get_data_double(obj_rbn_img);
703 for (
int j = 1; j <= nx; j++) {
706 hdrl_image_get_pixel(median_sky, j, 1, &rej);
707 cpl_image_set(sci_single->sky, j, targ_idx,
710 rbn_img_data[j - 1 + (rbn_idx - 1) * nx];
711 double sci_flux = rbn_img_val - sky_val.data;
712 cpl_image_set(sci_img, j, targ_idx, sci_flux);
714 cpl_image_get(obj_rbn_err_img, j, rbn_idx,
716 double err = sqrt(rbn_err_val * rbn_err_val +
717 sky_val.error * sky_val.error);
718 cpl_image_set(sci_err_img, j, targ_idx, err);
719 double rbn_qual_val =
720 cpl_image_get(obj_rbn_qual_img, j, rbn_idx,
723 cpl_image_set(sci_qual_img, j, targ_idx,
728 moo_skycorr(obj_rbn_single->image, median_sky, targ_idx,
729 rbn_idx, crpix1, crval1, cd1_1, pheader,
730 solflux_frame, airglow_group_frame,
731 airglow_var_frame, params->sk,
732 sci_single->image, sci_single->sky);
734 hdrl_image_delete(median_sky);
744 if (sky_stare_table != NULL) {
745 char *sky_stare_table_name =
746 cpl_sprintf(
"SKY_TABLE_%s_%s", obja_rbn_single->extname, filename);
747 cpl_table_save(sky_stare_table, NULL, NULL, sky_stare_table_name,
749 cpl_free(sky_stare_table_name);
752 cpl_array_delete(valid_targets_indexes);
753 cpl_table_delete(sky_stare_table);
754 if (!cpl_errorstate_is_equal(prestate)) {
755 cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_OUTPUT,
756 "Error in sky subtraction %s",
757 obja_rbn_single->extname);
764static cpl_propertylist *
765_moo_create_primary_header(cpl_propertylist *rbn_primary_header)
767 cpl_propertylist *primary_header = NULL;
769 primary_header = cpl_propertylist_new();
770 cpl_propertylist_copy_property(primary_header, rbn_primary_header,
772 cpl_propertylist_copy_property(primary_header, rbn_primary_header,
774 cpl_propertylist_copy_property_regexp(primary_header, rbn_primary_header,
776 cpl_propertylist_copy_property_regexp(primary_header, rbn_primary_header,
778 cpl_propertylist_copy_property(primary_header, rbn_primary_header,
781 return primary_header;
814 const cpl_frame *solflux_frame,
815 const cpl_frame *airglow_group_frame,
816 const cpl_frame *airglow_var_frame,
817 moo_sub_sky_stare_params *params,
818 const char *filename,
823 cpl_ensure(obja_rbn != NULL, CPL_ERROR_NULL_INPUT, NULL);
824 cpl_ensure(objb_rbn != NULL, CPL_ERROR_NULL_INPUT, NULL);
825 cpl_ensure(target_table != NULL, CPL_ERROR_NULL_INPUT, NULL);
826 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
828 cpl_array *objb_sky_indexes = NULL;
829 cpl_array *obja_sky_indexes = NULL;
830 cpl_array *targ_obj_indexes = NULL;
833 cpl_errorstate prestate = cpl_errorstate_get();
835 unsigned int badpix_level =
840 sci->filename = filename;
841 sci->primary_header = _moo_create_primary_header(obja_rbn->primary_header);
844 "Substract sky stare with method %s "
845 "using maxdistslit %d, mintrans %f, and radius (%f+%f) and min sky %d",
846 params->method, params->maxdistslit, params->min_trans,
847 params->radius_sky, params->step_r, params->min_sky);
856 for (
int i = 1; i < 3; i++) {
861 if (obja_rbn_single != NULL) {
862 cpl_propertylist *header =
868 exptimeA[i] = ndit * dit;
870 if (objb_rbn_single != NULL) {
871 cpl_propertylist *header =
877 exptimeB[i] = ndit * dit;
881 moo_target_table_set_exptimes(sci_target_table, exptimeA, exptimeB);
883 sci->target_table = sci_target_table;
892 cpl_msg_indent_more();
899 for (
int i = 0; i < 3; i++) {
900 moo_sci_single *sci_single = NULL;
901 moo_rbn_single *obja_rbn_single =
903 moo_rbn_single *objb_rbn_single = NULL;
905 if (obja_rbn_single != NULL) {
906 cpl_msg_info(__func__,
"Substract sky stare extension %s",
907 obja_rbn_single->extname);
909 double ea = exptimeA[i];
910 double eb = exptimeB[i];
911 moo_try_check(sci_single = _moo_sub_sky_stare_single(
912 obja_rbn_single, obja_fibre_table, ea,
913 sci_target_table, objb_rbn_single,
914 objb_fibre_table, eb, f2f, solflux_frame,
915 airglow_group_frame, airglow_var_frame, params,
916 obja_sky_indexes, objb_sky_indexes,
917 targ_obj_indexes, obja_rbn->primary_header,
923 cpl_msg_indent_less();
924 int nrow = cpl_table_get_nrow(sci_target_table->table);
926 for (
int i = 0; i < nrow; i++) {
927 if (!cpl_table_is_selected(sci_target_table->table, i)) {
928 cpl_table_set_invalid(sci_target_table->table,
929 MOO_TARGET_TABLE_INDEXTARG, i);
933 cpl_table_erase_invalid(sci_target_table->table);
938 cpl_array_delete(obja_sky_indexes);
939 cpl_array_delete(objb_sky_indexes);
940 cpl_array_delete(targ_obj_indexes);
942 if (!cpl_errorstate_is_equal(prestate)) {
946 cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_OUTPUT,
947 "Error in sky subtraction");
#define MOO_BADPIX_OUTSIDE_DATA_RANGE
#define MOO_BADPIX_CALIB_DEFECT
enum _moo_detector_type_ moo_detector_type
The type code type.
const char * moo_f2f_get_trans_colname(moo_f2f *self, moo_detector_type type)
Get transmission column name from table.
cpl_error_code moo_f2f_order_by_indexrbn(moo_f2f *self)
Order F2F by INDEXRBN (ASC)
cpl_error_code moo_fits_create(const char *filename)
Create a new fits file with empty propertylist.
cpl_propertylist * moo_rbn_single_get_header(moo_rbn_single *self)
Get header of rbn single.
moo_rbn_single * moo_rbn_load_single(moo_rbn *self, moo_detector_type type, unsigned int level)
Load the type part in RBN and return it.
moo_rbn_single * moo_rbn_get_single(moo_rbn *self, moo_detector_type type)
Get a RBN single from RBN.
cpl_table * moo_rbn_get_fibre_table(moo_rbn *self)
Get the FIBRE TABLE in RBN.
moo_sci_single * moo_sci_single_new(moo_detector_type type)
Create a new moo_sci_single.
void moo_sci_single_delete(moo_sci_single *self)
Delete a moo_sci_single.
cpl_error_code moo_sci_add_target_table(moo_sci *self, moo_target_table *table)
Add target table to SCI file and update moo_sci structure.
void moo_sci_delete(moo_sci *self)
Delete a moo_sci.
moo_sci * moo_sci_new(void)
Create a new moo_sci.
cpl_error_code moo_sci_add_single(moo_sci *self, moo_detector_type type, moo_sci_single *single)
Add SCI_SINGLE extension to SCI file and update moo_sci structure.
cpl_array * moo_target_table_select_sky_index(moo_target_table *self, moo_rbn *sky_rbn)
get the index of the sky in the target table sort by indexspec
moo_target_table * moo_target_table_duplicate(moo_target_table *self)
Duplicate an existing target_table.
int moo_target_table_xswitch_paired(moo_target_table *self)
get the index of the object in the target table sort by indexrbn
cpl_array * moo_target_table_select_obj_index(moo_target_table *self, int ispaired)
get the index of the object in the target table sort by indexrbn
cpl_array * moo_select_sky(const char *targname, int indextarg, int obj_index, double obj_targalpha, double obj_targdelta, cpl_table *target_table, const char *index_colname, cpl_table *sky_stare_table, moo_detector_type type, int maxdistslit, double mintrans, int min_sky, double radius, double step_r, int target_table_idx, moo_f2f *f2f, cpl_array *allsky_indexes)
This function selects sky fibres around a target object.
moo_sci * moo_sub_sky_stare(moo_rbn *obja_rbn, moo_target_table *target_table, moo_rbn *objb_rbn, moo_f2f *f2f, const cpl_frame *solflux_frame, const cpl_frame *airglow_group_frame, const cpl_frame *airglow_var_frame, moo_sub_sky_stare_params *params, const char *filename, int ispaired)
This function subtracts the sky in wavelength calibrated and extracted science frames obtain in Stare...
int moo_pfits_get_ndit(const cpl_propertylist *plist)
find out the ESO DET NDIT value
double moo_pfits_get_cd1_1(const cpl_propertylist *plist)
find out the CD1_1 value
double moo_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
cpl_error_code moo_pfits_append_hduclass_data(cpl_propertylist *plist, moo_detector_type type, int ntas)
Set the HDUCLASS DATA Keyword.
double moo_pfits_get_crval1(const cpl_propertylist *plist)
find out the CRVAL1 value
double moo_pfits_get_crpix1(const cpl_propertylist *plist)
find out the CRPIX1 value
double moo_pfits_get_exptime(const cpl_propertylist *plist)
find out the EXPTIME value
cpl_error_code moo_skycorr(hdrl_image *rbn, hdrl_image *sky, int indextarg, int indexrbn, double crpix1, double crval1, double cd1_1, cpl_propertylist *header, const cpl_frame *solflux_frame, const cpl_frame *airglow_group_frame, const cpl_frame *airglow_var_frame, moo_skycorr_params *params, hdrl_image *sci, cpl_image *sci_sky)
call the skycorr subtract sky function
double moo_sky_distance(double alpha1, double delta1, double alpha2, double delta2)
Compute sky distance (in rad)
hdrl_image * moo_image_collapse_median_create(hdrl_image *image)
Collapse row of an image using a median and compute associate error.
the different type of detectors