MOONS Pipeline Reference Manual 0.13.2
moo_combine_pair.c
1/*
2 * This file is part of the MOONS Pipeline
3 * Copyright (C) 2002-2016 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27#include <math.h>
28#include <string.h>
29#include <cpl.h>
30
31#include "moo_combine_pair.h"
32#include "moo_sub_sky_stare.h"
33#include "moo_fibres_table.h"
34#include "moo_fits.h"
35#include "moo_pfits.h"
36#include "moo_badpix.h"
37#include "moo_utils.h"
38#include "moo_skycorr.h"
39#include "moo_products.h"
40/*----------------------------------------------------------------------------*/
45/*----------------------------------------------------------------------------*/
46
49/*-----------------------------------------------------------------------------
50 Function codes
51 -----------------------------------------------------------------------------*/
52static moo_sci_single *
53_moo_create_sci2d_single(moo_rbn_single *nod_rbn_single,
54 moo_rbn_single *objb_rbn_single,
55 moo_rbn_single *obja_rbn_single,
56 cpl_table *nod_fibret,
57 moo_target_table *target_table,
58 int ispaired)
59{
60 moo_sci_single *sci_single = NULL;
61
62 cpl_errorstate prestate = cpl_errorstate_get();
63
64 cpl_ensure(nod_rbn_single != NULL, CPL_ERROR_NULL_INPUT, NULL);
65 cpl_ensure(objb_rbn_single != NULL, CPL_ERROR_NULL_INPUT, NULL);
66 cpl_ensure(target_table != NULL, CPL_ERROR_NULL_INPUT, NULL);
67
68 int nb_target = cpl_table_get_nrow(target_table->table);
69
70 if (nb_target > 0) {
71 moo_try_check(sci_single = moo_sci_single_new(nod_rbn_single->type),
72 " ");
73
74 moo_pfits_append_hduclass_data(sci_single->header, sci_single->type,
75 -1);
76 cpl_propertylist_copy_property(sci_single->header,
77 nod_rbn_single->header,
78 MOO_PFITS_CRPIX1);
79 cpl_propertylist_copy_property(sci_single->header,
80 nod_rbn_single->header,
81 MOO_PFITS_CRVAL1);
82 cpl_propertylist_copy_property(sci_single->header,
83 nod_rbn_single->header, MOO_PFITS_CD1_1);
84 cpl_propertylist_copy_property(sci_single->header,
85 nod_rbn_single->header, MOO_PFITS_CD1_2);
86 cpl_propertylist_copy_property(sci_single->header,
87 nod_rbn_single->header,
88 MOO_PFITS_CTYPE1);
89 cpl_propertylist_copy_property(sci_single->header,
90 nod_rbn_single->header,
91 MOO_PFITS_CUNIT1);
92 cpl_propertylist_copy_property(sci_single->header,
93 nod_rbn_single->header, MOO_PFITS_BUNIT);
94 cpl_propertylist_copy_property(sci_single->header,
95 nod_rbn_single->header,
96 MOO_PFITS_CRPIX2);
97 cpl_propertylist_copy_property(sci_single->header,
98 nod_rbn_single->header,
99 MOO_PFITS_CRVAL2);
100 cpl_propertylist_copy_property(sci_single->header,
101 nod_rbn_single->header, MOO_PFITS_CD2_1);
102 cpl_propertylist_copy_property(sci_single->header,
103 nod_rbn_single->header, MOO_PFITS_CD2_2);
104 cpl_propertylist_copy_property(sci_single->header,
105 nod_rbn_single->header,
106 MOO_PFITS_CTYPE2);
107 cpl_propertylist_copy_property(sci_single->header,
108 nod_rbn_single->header,
109 MOO_PFITS_WAVELMIN);
110 cpl_propertylist_copy_property(sci_single->header,
111 nod_rbn_single->header,
112 MOO_PFITS_WAVELMAX);
113 cpl_propertylist_copy_property(sci_single->header,
114 nod_rbn_single->header,
115 MOO_PFITS_SPECBIN);
116 int nx = hdrl_image_get_size_x(nod_rbn_single->image);
117
118 sci_single->image = hdrl_image_new(nx, nb_target);
119 sci_single->sky = cpl_image_new(nx, nb_target, CPL_TYPE_DOUBLE);
120 sci_single->qual = cpl_image_new(nx, nb_target, CPL_TYPE_INT);
121
122 cpl_image *sci_img = hdrl_image_get_image(sci_single->image);
123 /* create the mask if empty */
124 cpl_image_get_bpm(sci_img);
125
126 cpl_image *sci_err_img = hdrl_image_get_error(sci_single->image);
127 cpl_image *sci_qual_img = sci_single->qual;
128
129 cpl_image *objb_rbn_img = hdrl_image_get_image(objb_rbn_single->image);
130 cpl_image *obja_rbn_img = NULL;
131
132 if (obja_rbn_single != NULL) {
133 obja_rbn_img = hdrl_image_get_image(obja_rbn_single->image);
134 }
135
136 cpl_image *nod_rbn_img = hdrl_image_get_image(nod_rbn_single->image);
137 cpl_image *nod_rbn_err_img =
138 hdrl_image_get_error(nod_rbn_single->image);
139 cpl_image *nod_rbn_qual_img = nod_rbn_single->qual;
140
141 const char *transname[] = { MOO_TARGET_TABLE_TRANSRI,
142 MOO_TARGET_TABLE_TRANSYJ,
143 MOO_TARGET_TABLE_TRANSH };
144 const char *ptransname[] = { MOO_TARGET_TABLE_PTRANSRI,
145 MOO_TARGET_TABLE_PTRANSYJ,
146 MOO_TARGET_TABLE_PTRANSH };
147 float *transt =
148 cpl_table_get_data_float(target_table->table,
149 transname[nod_rbn_single->type]);
150 float *ptranst =
151 cpl_table_get_data_float(target_table->table,
152 ptransname[nod_rbn_single->type]);
153 int *indexrbnt = cpl_table_get_data_int(target_table->table,
154 MOO_TARGET_TABLE_INDEXRBN);
155 int *pindexrbnt =
156 cpl_table_get_data_int(target_table->table,
157 MOO_TARGET_TABLE_PAIREDINDEXRBN);
158 char **obstypet = cpl_table_get_data_string(target_table->table,
159 MOO_TARGET_TABLE_OBSTYPE);
160
161 for (int i = 1; i <= nb_target; i++) {
162 int idx = i - 1;
163 int indexrbn = indexrbnt[idx];
164
165 cpl_table_set_int(target_table->table, MOO_TARGET_TABLE_INDEXTARG,
166 idx, i);
167 cpl_table_set_int(target_table->table, MOO_TARGET_TABLE_NBSKY, idx,
168 1);
169 cpl_table_set_int(target_table->table,
170 MOO_TARGET_TABLE_MAX_DIST_SLIT, idx, 0);
171 cpl_table_set_float(target_table->table,
172 MOO_TARGET_TABLE_MAX_DIST_SKY, idx, 0);
173 cpl_table_set_string(target_table->table,
174 MOO_TARGET_TABLE_SUBSKYMODE, idx,
175 MOO_TARGET_TABLE_SUBSKY_NOD);
176
177 cpl_table_select_all(nod_fibret);
178 cpl_table_and_selected_int(nod_fibret, MOO_FIBRES_TABLE_INDEXRBN,
179 CPL_EQUAL_TO, indexrbn);
180 cpl_array *sel = cpl_table_where_selected(nod_fibret);
181 int ft_idx = cpl_array_get_cplsize(sel, 0, NULL);
182 moo_target_table_set_snr(target_table, idx, nod_fibret, ft_idx);
183 cpl_array_delete(sel);
184 }
185/* The following addresses an issue with the gcc9 compiler series prior to
186 * gcc 9.3. These compiler versions require that the variable '__func__'
187 * appears in the data sharing clause if default(none) is used. However
188 * adding it to the data sharing clause breaks older compiler versions
189 * where these variables are pre-determined as shared.
190 * This was fixed in gcc 9.3 and OpenMP 5.1.
191 */
192#ifdef _OPENMP
193#if (__GNUC__ == 9) && (__GNUC_MINOR__ < 3)
194#pragma omp parallel shared(nb_target, indexrbnt, pindexrbnt, transt, ptranst, \
195 obstypet, target_table, nod_rbn_single, \
196 objb_rbn_img, obja_rbn_img, sci_single, \
197 nod_rbn_qual_img, sci_qual_img, nod_rbn_img, \
198 sci_img, nod_rbn_err_img, sci_err_img, nx, \
199 ispaired)
200#else
201#pragma omp parallel default(none) \
202 shared(nb_target, indexrbnt, pindexrbnt, transt, ptranst, obstypet, \
203 target_table, nod_rbn_single, objb_rbn_img, obja_rbn_img, \
204 sci_single, nod_rbn_qual_img, sci_qual_img, nod_rbn_img, \
205 sci_img, nod_rbn_err_img, sci_err_img, nx, ispaired)
206#endif
207 {
208#pragma omp for
209#endif
210 for (int i = 1; i <= nb_target; i++) {
211 int idx = i - 1;
212 int indexrbn = indexrbnt[idx];
213 char *obstype = obstypet[idx];
214
215 if ((strcmp(obstype, MOO_OBSTYPE_OBSPNOD) == 0) ||
216 (strcmp(obstype, MOO_OBSTYPE_OBSPNODSTARE) == 0)) {
217 for (int j = 1; j <= nx; j++) {
218 int rej;
219 double sky_val =
220 cpl_image_get(obja_rbn_img, j, indexrbn, &rej);
221 cpl_image_set(sci_single->sky, j, i, sky_val);
222 double rbn_img_val =
223 cpl_image_get(nod_rbn_img, j, indexrbn, &rej);
224 if (rej) {
225 cpl_image_set(sci_img, j, i, NAN);
226 cpl_image_set(sci_err_img, j, i, NAN);
227 cpl_image_reject(sci_img, j, i);
228 }
229 else {
230 double sci_flux = -rbn_img_val;
231 cpl_image_set(sci_img, j, i, sci_flux);
232 double rbn_err_val =
233 cpl_image_get(nod_rbn_err_img, j, indexrbn,
234 &rej);
235 double err = rbn_err_val;
236 cpl_image_set(sci_err_img, j, i, err);
237 }
238 double rbn_qual_val =
239 cpl_image_get(nod_rbn_qual_img, j, indexrbn, &rej);
240 cpl_image_set(sci_qual_img, j, i, rbn_qual_val);
241 }
242 }
243 else if (strcmp(obstype, MOO_OBSTYPE_OBSSWITCH) == 0) {
244 // double transsum = trans + ptrans;
245 double factor = 1.;
246 cpl_image *sky_img = objb_rbn_img;
247 if (ispaired) {
248 factor = -1;
249 sky_img = obja_rbn_img;
250 }
251 for (int j = 1; j <= nx; j++) {
252 int rej, rerr;
253
254 double sky_val =
255 cpl_image_get(sky_img, j, indexrbn, &rej);
256 cpl_image_set(sci_single->sky, j, i, sky_val);
257
258 double nod_rbn_img_val =
259 factor *
260 cpl_image_get(nod_rbn_img, j, indexrbn, &rej);
261 double nod_rbn_qual_val =
262 cpl_image_get(nod_rbn_qual_img, j, indexrbn, &rerr);
263 double nod_rbn_err_val =
264 cpl_image_get(nod_rbn_err_img, j, indexrbn, &rerr);
265
266 if (rej) {
267 cpl_image_reject(sci_img, j, i);
268 nod_rbn_img_val = NAN;
269 nod_rbn_err_val = NAN;
270 }
271 cpl_image_set(sci_img, j, i, nod_rbn_img_val);
272 cpl_image_set(sci_err_img, j, i, nod_rbn_err_val);
273 cpl_image_set(sci_qual_img, j, i, nod_rbn_qual_val);
274 }
275 }
276 else {
277 for (int j = 1; j <= nx; j++) {
278 int rej;
279
280 double sky_val =
281 cpl_image_get(objb_rbn_img, j, indexrbn, &rej);
282 cpl_image_set(sci_single->sky, j, i, sky_val);
283 double rbn_img_val =
284 cpl_image_get(nod_rbn_img, j, indexrbn, &rej);
285 if (rej) {
286 cpl_image_set(sci_img, j, i, NAN);
287 cpl_image_set(sci_err_img, j, i, NAN);
288 cpl_image_reject(sci_img, j, i);
289 }
290 else {
291 double sci_flux = rbn_img_val;
292 cpl_image_set(sci_img, j, i, sci_flux);
293 double rbn_err_val =
294 cpl_image_get(nod_rbn_err_img, j, indexrbn,
295 &rej);
296 double err = rbn_err_val;
297 cpl_image_set(sci_err_img, j, i, err);
298 }
299 double rbn_qual_val =
300 cpl_image_get(nod_rbn_qual_img, j, indexrbn, &rej);
301 cpl_image_set(sci_qual_img, j, i, rbn_qual_val);
302 }
303 }
304 }
305#ifdef _OPENMP
306 }
307#endif
308 }
309moo_try_cleanup:
310 if (!cpl_errorstate_is_equal(prestate)) {
311 cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_OUTPUT,
312 "Error in combine pair %s",
313 nod_rbn_single->extname);
314 moo_sci_single_delete(sci_single);
315 sci_single = NULL;
316 }
317 return sci_single;
318}
319
320static moo_sci_single *
321_moo_combine_pair_2d_single(moo_rbn_single *nod_rbn_single,
322 moo_rbn_single *objb_rbn_single,
323 moo_rbn_single *obja_rbn_single,
324 cpl_table *nod_fibret,
325 moo_target_table *target_table)
326{
327 moo_sci_single *sci_single = NULL;
328
329 cpl_errorstate prestate = cpl_errorstate_get();
330
331 cpl_ensure(nod_rbn_single != NULL, CPL_ERROR_NULL_INPUT, NULL);
332 cpl_ensure(objb_rbn_single != NULL, CPL_ERROR_NULL_INPUT, NULL);
333 cpl_ensure(target_table != NULL, CPL_ERROR_NULL_INPUT, NULL);
334
335 moo_try_check(sci_single = moo_sci_single_new(nod_rbn_single->type), " ");
336
337 moo_pfits_append_hduclass_data(sci_single->header, sci_single->type, -1);
338 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
339 MOO_PFITS_CRPIX1);
340 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
341 MOO_PFITS_CRVAL1);
342 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
343 MOO_PFITS_CD1_1);
344 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
345 MOO_PFITS_CD1_2);
346 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
347 MOO_PFITS_CTYPE1);
348 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
349 MOO_PFITS_CUNIT1);
350 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
351 MOO_PFITS_BUNIT);
352 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
353 MOO_PFITS_CRPIX2);
354 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
355 MOO_PFITS_CRVAL2);
356 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
357 MOO_PFITS_CD2_1);
358 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
359 MOO_PFITS_CD2_2);
360 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
361 MOO_PFITS_CTYPE2);
362 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
363 MOO_PFITS_BUNIT);
364 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
365 MOO_PFITS_WAVELMIN);
366 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
367 MOO_PFITS_WAVELMAX);
368 cpl_propertylist_copy_property(sci_single->header, nod_rbn_single->header,
369 MOO_PFITS_SPECBIN);
370 int nx = hdrl_image_get_size_x(nod_rbn_single->image);
371 int nb_target = cpl_table_get_nrow(target_table->table);
372
373 sci_single->image = hdrl_image_new(nx, nb_target);
374 sci_single->sky = cpl_image_new(nx, nb_target, CPL_TYPE_DOUBLE);
375 sci_single->qual = cpl_image_new(nx, nb_target, CPL_TYPE_INT);
376
377 cpl_image *sci_img = hdrl_image_get_image(sci_single->image);
378 /* create the mask if empty */
379 cpl_image_get_bpm(sci_img);
380
381 cpl_image *sci_err_img = hdrl_image_get_error(sci_single->image);
382 cpl_image *sci_qual_img = sci_single->qual;
383
384 cpl_image *objb_rbn_img = hdrl_image_get_image(objb_rbn_single->image);
385 cpl_image *obja_rbn_img = hdrl_image_get_image(obja_rbn_single->image);
386
387 cpl_image *nod_rbn_img = hdrl_image_get_image(nod_rbn_single->image);
388 cpl_image *nod_rbn_err_img = hdrl_image_get_error(nod_rbn_single->image);
389 cpl_image *nod_rbn_qual_img = nod_rbn_single->qual;
390
391 const char *transname[] = { MOO_TARGET_TABLE_TRANSRI,
392 MOO_TARGET_TABLE_TRANSYJ,
393 MOO_TARGET_TABLE_TRANSH };
394 const char *ptransname[] = { MOO_TARGET_TABLE_PTRANSRI,
395 MOO_TARGET_TABLE_PTRANSYJ,
396 MOO_TARGET_TABLE_PTRANSH };
397 float *transt = cpl_table_get_data_float(target_table->table,
398 transname[nod_rbn_single->type]);
399 float *ptranst = cpl_table_get_data_float(target_table->table,
400 ptransname[nod_rbn_single->type]);
401 int *indexrbnt =
402 cpl_table_get_data_int(target_table->table, MOO_TARGET_TABLE_INDEXRBN);
403 int *pindexrbnt = cpl_table_get_data_int(target_table->table,
404 MOO_TARGET_TABLE_PAIREDINDEXRBN);
405 char **obstypet = cpl_table_get_data_string(target_table->table,
406 MOO_TARGET_TABLE_OBSTYPE);
407 int *nbskyt =
408 cpl_table_get_data_int(target_table->table, MOO_TARGET_TABLE_NBSKY);
409 int *maxdistslitt = cpl_table_get_data_int(target_table->table,
410 MOO_TARGET_TABLE_MAX_DIST_SLIT);
411 float *maxdistskyt =
412 cpl_table_get_data_float(target_table->table,
413 MOO_TARGET_TABLE_MAX_DIST_SKY);
414 int *pnbskyt =
415 cpl_table_get_data_int(target_table->table, MOO_TARGET_TABLE_PNBSKY);
416 int *pmaxdistslitt =
417 cpl_table_get_data_int(target_table->table,
418 MOO_TARGET_TABLE_PMAX_DIST_SLIT);
419 float *pmaxdistskyt =
420 cpl_table_get_data_float(target_table->table,
421 MOO_TARGET_TABLE_PMAX_DIST_SKY);
422
423 for (int i = 1; i <= nb_target; i++) {
424 int indexrbn = indexrbnt[i - 1];
425 int pindexrbn = pindexrbnt[i - 1];
426
427 cpl_table_set_int(target_table->table, MOO_TARGET_TABLE_INDEXTARG,
428 i - 1, i);
429 cpl_table_set_string(target_table->table, MOO_TARGET_TABLE_SUBSKYMODE,
430 i - 1, MOO_TARGET_TABLE_SUBSKY_NOD);
431 char *obstype = obstypet[i - 1];
432
433 if (strcmp(obstype, MOO_OBSTYPE_OBSPNODSTARE) == 0) {
434 indexrbn = pindexrbn;
435 pnbskyt[i - 1] = 1;
436 pmaxdistslitt[i - 1] = 0;
437 pmaxdistskyt[i - 1] = 0;
438 }
439 else {
440 nbskyt[i - 1] = 1;
441 maxdistslitt[i - 1] = 0;
442 maxdistskyt[i - 1] = 0;
443 }
444 cpl_table_select_all(nod_fibret);
445 cpl_table_and_selected_int(nod_fibret, MOO_FIBRES_TABLE_INDEXRBN,
446 CPL_EQUAL_TO, indexrbn);
447 cpl_array *sel = cpl_table_where_selected(nod_fibret);
448 int ft_idx = cpl_array_get_cplsize(sel, 0, NULL);
449 if (strcmp(obstype, MOO_OBSTYPE_OBSPNODSTARE) == 0) {
450 moo_target_table_set_ft_psnr(target_table, i - 1, nod_fibret,
451 ft_idx);
452 }
453 else {
454 moo_target_table_set_snr(target_table, i - 1, nod_fibret, ft_idx);
455 }
456 cpl_array_delete(sel);
457 if (strcmp(obstype, MOO_OBSTYPE_OBSSWITCH) == 0) {
458 cpl_table_select_all(nod_fibret);
459 cpl_table_and_selected_int(nod_fibret, MOO_FIBRES_TABLE_INDEXRBN,
460 CPL_EQUAL_TO, pindexrbn);
461 cpl_array *sel2 = cpl_table_where_selected(nod_fibret);
462 ft_idx = cpl_array_get_cplsize(sel2, 0, NULL);
463 cpl_array_delete(sel2);
464 moo_target_table_set_ft_psnr(target_table, i - 1, nod_fibret,
465 ft_idx);
466 cpl_table_set_int(target_table->table, MOO_TARGET_TABLE_PNBSKY,
467 i - 1, 1);
468 cpl_table_set_int(target_table->table,
469 MOO_TARGET_TABLE_PMAX_DIST_SLIT, i - 1, 0);
470 cpl_table_set_float(target_table->table,
471 MOO_TARGET_TABLE_PMAX_DIST_SKY, i - 1, 0);
472 }
473 }
474
475/* The following addresses an issue with the gcc9 compiler series prior to
476 * gcc 9.3. These compiler versions require that the variable '__func__'
477 * appears in the data sharing clause if default(none) is used. However
478 * adding it to the data sharing clause breaks older compiler versions
479 * where these variables are pre-determined as shared.
480 * This was fixed in gcc 9.3 and OpenMP 5.1.
481 */
482#ifdef _OPENMP
483#if (__GNUC__ == 9) && (__GNUC_MINOR__ < 3)
484#pragma omp parallel shared(nb_target, indexrbnt, pindexrbnt, transt, ptranst, \
485 obstypet, target_table, nod_rbn_single, \
486 objb_rbn_img, obja_rbn_img, sci_single, \
487 nod_rbn_qual_img, sci_qual_img, nod_rbn_img, \
488 sci_img, nod_rbn_err_img, sci_err_img, nx)
489#else
490#pragma omp parallel default(none) \
491 shared(nb_target, indexrbnt, pindexrbnt, transt, ptranst, obstypet, \
492 target_table, nod_rbn_single, objb_rbn_img, obja_rbn_img, \
493 sci_single, nod_rbn_qual_img, sci_qual_img, nod_rbn_img, \
494 sci_img, nod_rbn_err_img, sci_err_img, nx)
495#endif
496 {
497#pragma omp for
498#endif
499 for (int i = 1; i <= nb_target; i++) {
500 int indexrbn = indexrbnt[i - 1];
501 int pindexrbn = pindexrbnt[i - 1];
502 char *obstype = obstypet[i - 1];
503 float trans = transt[i - 1];
504 float ptrans = ptranst[i - 1];
505
506 if (strcmp(obstype, MOO_OBSTYPE_OBSPNOD) == 0 ||
507 strcmp(obstype, MOO_OBSTYPE_OBSPNODSTARE) == 0) {
508 if (strcmp(obstype, MOO_OBSTYPE_OBSPNODSTARE) == 0) {
509 indexrbn = pindexrbn;
510 }
511 for (int j = 1; j <= nx; j++) {
512 int rej;
513 double sky_val =
514 cpl_image_get(obja_rbn_img, j, indexrbn, &rej);
515 cpl_image_set(sci_single->sky, j, i, sky_val);
516 double rbn_img_val =
517 cpl_image_get(nod_rbn_img, j, indexrbn, &rej);
518 if (rej) {
519 cpl_image_set(sci_img, j, i, NAN);
520 cpl_image_set(sci_err_img, j, i, NAN);
521 cpl_image_reject(sci_img, j, i);
522 }
523 else {
524 double sci_flux = -rbn_img_val;
525 cpl_image_set(sci_img, j, i, sci_flux);
526 double rbn_err_val =
527 cpl_image_get(nod_rbn_err_img, j, indexrbn, &rej);
528 double err = rbn_err_val;
529 cpl_image_set(sci_err_img, j, i, err);
530 }
531 double rbn_qual_val =
532 cpl_image_get(nod_rbn_qual_img, j, indexrbn, &rej);
533 cpl_image_set(sci_qual_img, j, i, rbn_qual_val);
534 }
535 }
536 else if (strcmp(obstype, MOO_OBSTYPE_OBSSWITCH) == 0) {
537 double transsum = trans + ptrans;
538 for (int j = 1; j <= nx; j++) {
539 int rej, prej, rerr;
540 double sci_flux = NAN;
541 double sci_err = NAN;
542
543 double obja_sky_val =
544 cpl_image_get(obja_rbn_img, j, pindexrbn, &rej);
545 double objb_sky_val =
546 cpl_image_get(objb_rbn_img, j, indexrbn, &prej);
547 double sky_val =
548 (ptrans * obja_sky_val + trans * objb_sky_val) /
549 transsum * 2;
550 cpl_image_set(sci_single->sky, j, i, sky_val);
551
552 double nod_rbn_img_val =
553 cpl_image_get(nod_rbn_img, j, indexrbn, &rej);
554 double pnod_rbn_img_val =
555 cpl_image_get(nod_rbn_img, j, pindexrbn, &prej);
556
557 if (rej && prej) {
558 cpl_image_reject(sci_img, j, i);
559
560 int nod_rbn_qual_val =
561 (int)cpl_image_get(nod_rbn_qual_img, j, indexrbn,
562 &rerr);
563 int pnod_rbn_qual_val =
564 (int)cpl_image_get(nod_rbn_qual_img, j, pindexrbn,
565 &rerr);
566 int sci_qual_val = nod_rbn_qual_val | pnod_rbn_qual_val;
567 cpl_image_set(sci_qual_img, j, i, (double)sci_qual_val);
568 }
569 else if (rej) {
570 sci_flux = -2 * pnod_rbn_img_val;
571 double pnod_rbn_err_val =
572 cpl_image_get(nod_rbn_err_img, j, pindexrbn, &rerr);
573 sci_err = 2 * pnod_rbn_err_val;
574
575 int sci_qual_val =
576 (int)cpl_image_get(nod_rbn_qual_img, j, pindexrbn,
577 &rerr);
578 cpl_image_set(sci_qual_img, j, i, (double)sci_qual_val);
579 }
580 else if (prej) {
581 sci_flux = 2 * nod_rbn_img_val;
582 double nod_rbn_err_val =
583 cpl_image_get(nod_rbn_err_img, j, indexrbn, &rerr);
584 sci_err = 2 * nod_rbn_err_val;
585
586 int sci_qual_val =
587 (int)cpl_image_get(nod_rbn_qual_img, j, indexrbn,
588 &rerr);
589 cpl_image_set(sci_qual_img, j, i, (double)sci_qual_val);
590 }
591 else {
592 sci_flux = (nod_rbn_img_val * trans -
593 pnod_rbn_img_val * ptrans) /
594 transsum * 2;
595 double nod_rbn_err_val =
596 cpl_image_get(nod_rbn_err_img, j, indexrbn, &rerr);
597 double pnod_rbn_err_val =
598 cpl_image_get(nod_rbn_err_img, j, pindexrbn, &rerr);
599 sci_err = sqrt((trans * trans * nod_rbn_err_val *
600 nod_rbn_err_val +
601 ptrans * ptrans * pnod_rbn_err_val *
602 pnod_rbn_err_val)) *
603 2 / transsum;
604
605 int nod_rbn_qual_val =
606 (int)cpl_image_get(nod_rbn_qual_img, j, indexrbn,
607 &rerr);
608 int pnod_rbn_qual_val =
609 (int)cpl_image_get(nod_rbn_qual_img, j, pindexrbn,
610 &rerr);
611 int sci_qual_val = nod_rbn_qual_val | pnod_rbn_qual_val;
612 cpl_image_set(sci_qual_img, j, i, (double)sci_qual_val);
613 }
614 cpl_image_set(sci_img, j, i, sci_flux);
615 cpl_image_set(sci_err_img, j, i, sci_err);
616 }
617 }
618 else {
619 for (int j = 1; j <= nx; j++) {
620 int rej;
621 double sky_val =
622 cpl_image_get(objb_rbn_img, j, indexrbn, &rej);
623 cpl_image_set(sci_single->sky, j, i, sky_val);
624 double rbn_img_val =
625 cpl_image_get(nod_rbn_img, j, indexrbn, &rej);
626 if (rej) {
627 cpl_image_set(sci_img, j, i, NAN);
628 cpl_image_set(sci_err_img, j, i, NAN);
629 cpl_image_reject(sci_img, j, i);
630 }
631 else {
632 double sci_flux = rbn_img_val;
633 cpl_image_set(sci_img, j, i, sci_flux);
634 double rbn_err_val =
635 cpl_image_get(nod_rbn_err_img, j, indexrbn, &rej);
636 double err = rbn_err_val;
637 cpl_image_set(sci_err_img, j, i, err);
638 }
639 double rbn_qual_val =
640 cpl_image_get(nod_rbn_qual_img, j, indexrbn, &rej);
641 cpl_image_set(sci_qual_img, j, i, rbn_qual_val);
642 }
643 }
644 }
645#ifdef _OPENMP
646 }
647#endif
648moo_try_cleanup:
649 if (!cpl_errorstate_is_equal(prestate)) {
650 cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_OUTPUT,
651 "Error in combine pair %s",
652 nod_rbn_single->extname);
653 moo_sci_single_delete(sci_single);
654 sci_single = NULL;
655 }
656 return sci_single;
657}
658
659static cpl_propertylist *
660_moo_create_primary_header(cpl_propertylist *rbn_primary_header)
661{
662 cpl_propertylist *primary_header = NULL;
663
664 primary_header = cpl_propertylist_new();
665 cpl_propertylist_copy_property(primary_header, rbn_primary_header,
666 MOO_PFITS_EXPTIME);
667 cpl_propertylist_copy_property(primary_header, rbn_primary_header,
668 MOO_PFITS_MJDOBS);
669 cpl_propertylist_copy_property_regexp(primary_header, rbn_primary_header,
670 "TM*", 0);
671 cpl_propertylist_copy_property_regexp(primary_header, rbn_primary_header,
672 "ESO QC IS*", 0);
673 cpl_propertylist_copy_property(primary_header, rbn_primary_header,
674 MOO_PFITS_FLUXCAL);
675
676 return primary_header;
677}
678
679static moo_sci *
680_moo_combine_pair_2d(moo_rbn *nod_rbn,
681 moo_rbn *objb_rbn,
682 moo_rbn *obja_rbn,
683 moo_target_table *target_table,
684 const char *filename)
685{
686 moo_sci *sci = NULL;
687
688 cpl_ensure(nod_rbn != NULL, CPL_ERROR_NULL_INPUT, NULL);
689 cpl_ensure(objb_rbn != NULL, CPL_ERROR_NULL_INPUT, NULL);
690 cpl_ensure(target_table != NULL, CPL_ERROR_NULL_INPUT, NULL);
691
692 moo_target_table *sci_target_table = NULL;
693
694 cpl_errorstate prestate = cpl_errorstate_get();
695
696 unsigned int badpix_level =
698
699 moo_fits_create(filename);
700 sci = moo_sci_new();
701 sci->filename = filename;
702 sci->primary_header = _moo_create_primary_header(nod_rbn->primary_header);
703
704 cpl_msg_info(__func__, "Combine pair (2D)");
705
706 double exptimeA[3];
707 double exptimeB[3];
708 exptimeA[0] = moo_pfits_get_exptime(nod_rbn->primary_header);
709 exptimeB[0] = moo_pfits_get_exptime(objb_rbn->primary_header);
710
711 for (int i = 1; i < 3; i++) {
712 moo_rbn_single *obja_rbn_single = moo_rbn_get_single(nod_rbn, i);
713 moo_rbn_single *objb_rbn_single = moo_rbn_get_single(nod_rbn, i);
714 exptimeA[i] = 0;
715 exptimeB[i] = 0;
716 if (obja_rbn_single != NULL) {
717 cpl_propertylist *header =
718 moo_rbn_single_get_header(obja_rbn_single);
719
720 double dit = moo_pfits_get_dit(header);
721 int ndit = moo_pfits_get_ndit(header);
722
723 exptimeA[i] = ndit * dit;
724 }
725 if (objb_rbn_single != NULL) {
726 cpl_propertylist *header =
727 moo_rbn_single_get_header(objb_rbn_single);
728
729 double dit = moo_pfits_get_dit(header);
730 int ndit = moo_pfits_get_ndit(header);
731
732 exptimeB[i] = ndit * dit;
733 }
734 }
735 sci_target_table = moo_target_table_duplicate(target_table);
736 moo_target_table_set_exptimes(sci_target_table, exptimeA, exptimeB);
737 cpl_table *nod_ft = moo_rbn_get_fibre_table(nod_rbn);
738
739 sci->target_table = sci_target_table;
740
741 cpl_msg_indent_more();
742
743 for (int i = 0; i < 3; i++) {
744 moo_sci_single *sci_single = NULL;
745 moo_rbn_single *nod_rbn_single =
746 moo_rbn_load_single(nod_rbn, i, badpix_level);
747 moo_rbn_single *objb_rbn_single =
748 moo_rbn_load_single(objb_rbn, i, badpix_level);
749 moo_rbn_single *obja_rbn_single =
750 moo_rbn_load_single(obja_rbn, i, badpix_level);
751 if (nod_rbn_single != NULL) {
752 moo_try_check(sci_single = _moo_combine_pair_2d_single(
753 nod_rbn_single, objb_rbn_single, obja_rbn_single,
754 nod_ft, sci_target_table),
755 " ");
756 }
757 moo_sci_add_single(sci, i, sci_single);
758 }
759 moo_sci_add_target_table(sci, sci_target_table);
760
761moo_try_cleanup:
762 cpl_msg_indent_less();
763
764 if (!cpl_errorstate_is_equal(prestate)) {
765 cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_OUTPUT,
766 "Error in combine pair (2D)");
767 moo_sci_delete(sci);
768 sci = NULL;
769 }
770 return sci;
771}
772
773/*----------------------------------------------------------------------------*/
800/*----------------------------------------------------------------------------*/
801moo_sci *
802moo_combine_pair(moo_rbn *nod_rbn,
803 moo_rbn *sky_rbn,
804 moo_rbn *obj_rbn,
805 moo_target_table *target_table,
806 moo_f2f *f2f,
807 const cpl_frame *solflux_frame,
808 const cpl_frame *airglow_group_frame,
809 const cpl_frame *airglow_var_frame,
810 moo_combine_pair_params *combine_pair_params,
811 moo_sub_sky_stare_params *sky_params,
812 const char *filename,
813 moo_products *products,
814 const cpl_frame *ref_frame)
815{
816 moo_sci *sci1d = NULL;
817 moo_sci *psci1d = NULL;
818 char *sci1d_name = NULL;
819 char *psci1d_name = NULL;
820 char *sci2d_name = NULL;
821 char *psci2d_name = NULL;
822 moo_sci *sci2d = NULL;
823 moo_sci *psci2d = NULL;
824 moo_sci *cpair_sci = NULL;
825
826 cpl_ensure(nod_rbn != NULL, CPL_ERROR_NULL_INPUT, NULL);
827 cpl_ensure(sky_rbn != NULL, CPL_ERROR_NULL_INPUT, NULL);
828 cpl_ensure(target_table != NULL, CPL_ERROR_NULL_INPUT, NULL);
829
830 cpl_errorstate prestate = cpl_errorstate_get();
831
832 cpl_msg_info(__func__, "Combine pair using optimal:%d",
833 combine_pair_params->optimal);
834
835 if (combine_pair_params->optimal == 1) {
836 cpl_msg_info(__func__, "Substract sky (1D)");
837 sci1d_name = cpl_sprintf("1D_%s", filename);
838
839 moo_try_check(sci1d =
840 moo_sub_sky_stare(obj_rbn, target_table, sky_rbn, f2f,
841 solflux_frame, airglow_group_frame,
842 airglow_var_frame, sky_params,
843 sci1d_name, MOO_SCI1D_NOT_PAIRED),
844 " ");
845 if (products != NULL) {
846 moo_try_check(moo_products_add_sci(products, sci1d,
847 CPL_FRAME_LEVEL_TEMPORARY, "1D",
848 sci1d_name, ref_frame),
849 " ");
850 }
851#if MOO_DEBUG_COMBINEPAIR
852 {
853 char *testname = cpl_sprintf("CPAIR_1D_%s", filename);
854 moo_sci_save(sci1d, testname);
855 cpl_free(testname);
856 }
857#endif
858
859 cpl_msg_info(__func__, "Substract sky paired-fibre (1D)");
860
861 psci1d_name = cpl_sprintf("P1D_%s", filename);
862
863 moo_try_check(psci1d =
864 moo_sub_sky_stare(obj_rbn, target_table, sky_rbn, f2f,
865 solflux_frame, airglow_group_frame,
866 airglow_var_frame, sky_params,
867 psci1d_name, MOO_SCI1D_PAIRED),
868 " ");
869 if (products != NULL) {
870 moo_try_check(moo_products_add_sci(products, psci1d,
871 CPL_FRAME_LEVEL_TEMPORARY, "P1D",
872 psci1d_name, ref_frame),
873 " ");
874 }
875#if MOO_DEBUG_COMBINEPAIR
876 {
877 char *testname = cpl_sprintf("CPAIR_P1D_%s", filename);
878 moo_sci_save(psci1d, testname);
879 cpl_free(testname);
880 }
881#endif
882 sci2d_name = cpl_sprintf("2D_%s", filename);
883 psci2d_name = cpl_sprintf("2D_PAIRED_%s", filename);
884
885 psci2d = moo_create_sci2d(nod_rbn, sky_rbn, obj_rbn, target_table,
886 MOO_SCI2D_PAIRED, psci2d_name);
887 sci2d = moo_create_sci2d(nod_rbn, sky_rbn, obj_rbn, target_table,
888 MOO_SCI2D_NOT_PAIRED, sci2d_name);
889 if (products != NULL) {
890 moo_try_check(moo_products_add_sci(products, sci2d,
891 CPL_FRAME_LEVEL_TEMPORARY, "2D",
892 sci2d_name, ref_frame),
893 " ");
894 moo_try_check(moo_products_add_sci(products, psci2d,
895 CPL_FRAME_LEVEL_TEMPORARY, "2D",
896 psci2d_name, ref_frame),
897 " ");
898 }
899 cpl_msg_info("test", "combine all");
900 cpair_sci = moo_combine_pair_sci(target_table, sci1d, psci1d, sci2d,
901 psci2d, filename);
902 }
903 else {
904 moo_try_check(cpair_sci =
905 _moo_combine_pair_2d(nod_rbn, sky_rbn, obj_rbn,
906 target_table, filename),
907 " ");
908 }
909
910moo_try_cleanup:
911 cpl_free(sci1d_name);
912 cpl_free(psci1d_name);
913 cpl_free(sci2d_name);
914 cpl_free(psci2d_name);
915 moo_sci_delete(sci1d);
916 moo_sci_delete(psci1d);
917 moo_sci_delete(psci2d);
918 moo_sci_delete(sci2d);
919 if (!cpl_errorstate_is_equal(prestate)) {
920 cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_OUTPUT,
921 "Error in sky subtraction");
922 moo_sci_delete(cpair_sci);
923 cpair_sci = NULL;
924 }
925 return cpair_sci;
926}
927
928moo_sci *
929moo_create_sci2d(moo_rbn *nod_rbn,
930 moo_rbn *objb_rbn,
931 moo_rbn *obja_rbn,
932 moo_target_table *target_table,
933 int ispaired,
934 const char *filename)
935{
936 moo_sci *sci = NULL;
937
938 cpl_ensure(nod_rbn != NULL, CPL_ERROR_NULL_INPUT, NULL);
939 cpl_ensure(target_table != NULL, CPL_ERROR_NULL_INPUT, NULL);
940
941 moo_target_table *sci_target_table = NULL;
942
943 cpl_errorstate prestate = cpl_errorstate_get();
944 unsigned int badpix_level =
946
947 cpl_msg_info(__func__, "Create SCI (2D) ispaired:%d", ispaired);
948 cpl_table_unselect_all(target_table->table);
949
950 if (ispaired == 0) {
951 /* OBS_SWITCH OBS_NOD OBS_NODSTARE SKYRES_NOD */
952 cpl_table_or_selected_string(target_table->table,
953 MOO_TARGET_TABLE_OBSTYPE, CPL_EQUAL_TO,
954 MOO_OBSTYPE_OBSSWITCH);
955 cpl_table_and_selected_string(target_table->table,
956 MOO_TARGET_TABLE_OBSTYPE,
957 CPL_NOT_EQUAL_TO,
958 MOO_OBSTYPE_OBSSWITCHSTARE);
959
960 cpl_table_or_selected_string(target_table->table,
961 MOO_TARGET_TABLE_OBSTYPE, CPL_EQUAL_TO,
962 MOO_OBSTYPE_OBSNOD);
963 cpl_table_or_selected_string(target_table->table,
964 MOO_TARGET_TABLE_OBSTYPE, CPL_EQUAL_TO,
965 MOO_OBSTYPE_SKYRESNOD);
966 }
967 else {
968 /* OBS_SWITCH OBS_PNOD OBS_PNODSTARE */
969 cpl_table_or_selected_string(target_table->table,
970 MOO_TARGET_TABLE_OBSTYPE, CPL_EQUAL_TO,
971 MOO_OBSTYPE_OBSSWITCH);
972 cpl_table_and_selected_string(target_table->table,
973 MOO_TARGET_TABLE_OBSTYPE,
974 CPL_NOT_EQUAL_TO,
975 MOO_OBSTYPE_OBSSWITCHSTARE);
976
977 cpl_table_or_selected_string(target_table->table,
978 MOO_TARGET_TABLE_OBSTYPE, CPL_EQUAL_TO,
979 MOO_OBSTYPE_OBSPNOD);
980 }
981 cpl_table *ttable = cpl_table_extract_selected(target_table->table);
982 moo_fits_create(filename);
983 sci = moo_sci_new();
984 sci->filename = filename;
985 sci->primary_header = _moo_create_primary_header(nod_rbn->primary_header);
986
987 sci_target_table = moo_target_table_new();
988 sci_target_table->primary_header = cpl_propertylist_new();
989 sci_target_table->table = ttable;
990 sci->target_table = sci_target_table;
991 if (ispaired) {
992 moo_target_table_xswitch_paired(sci_target_table);
993 }
994
995 double exptimeA[3];
996 double exptimeB[3];
997
998 exptimeA[0] = moo_pfits_get_exptime(nod_rbn->primary_header);
999
1000 for (int i = 1; i < 3; i++) {
1001 moo_rbn_single *obja_rbn_single = moo_rbn_get_single(nod_rbn, i);
1002 moo_rbn_single *objb_rbn_single = moo_rbn_get_single(nod_rbn, i);
1003 exptimeA[i] = 0;
1004 exptimeB[i] = 0;
1005 if (obja_rbn_single != NULL) {
1006 cpl_propertylist *header =
1007 moo_rbn_single_get_header(obja_rbn_single);
1008
1009 double dit = moo_pfits_get_dit(header);
1010 int ndit = moo_pfits_get_ndit(header);
1011
1012 exptimeA[i] = ndit * dit;
1013 }
1014 }
1015
1016 moo_target_table_set_exptimes(sci_target_table, exptimeA, exptimeB);
1017
1018 cpl_table *nod_ft = moo_rbn_get_fibre_table(nod_rbn);
1019
1020 cpl_msg_indent_more();
1021
1022 for (int i = 0; i < 3; i++) {
1023 moo_sci_single *sci_single = NULL;
1024 moo_rbn_single *nod_rbn_single = NULL;
1025 moo_rbn_single *obja_rbn_single = NULL;
1026 moo_rbn_single *objb_rbn_single = NULL;
1027
1028 nod_rbn_single = moo_rbn_load_single(nod_rbn, i, badpix_level);
1029 objb_rbn_single = moo_rbn_load_single(objb_rbn, i, badpix_level);
1030
1031 if (nod_rbn_single != NULL) {
1032 if (obja_rbn != NULL) {
1033 obja_rbn_single =
1034 moo_rbn_load_single(obja_rbn, i, badpix_level);
1035 }
1036
1037 moo_try_check(sci_single = _moo_create_sci2d_single(
1038 nod_rbn_single, objb_rbn_single, obja_rbn_single,
1039 nod_ft, sci_target_table, ispaired),
1040 " ");
1041 }
1042 moo_sci_add_single(sci, i, sci_single);
1043 }
1044
1045 moo_sci_add_target_table(sci, sci_target_table);
1046
1047moo_try_cleanup:
1048 cpl_msg_indent_less();
1049
1050 if (!cpl_errorstate_is_equal(prestate)) {
1051 cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_OUTPUT,
1052 "Error in combine pair (2D)");
1053 moo_sci_delete(sci);
1054 sci = NULL;
1055 }
1056 return sci;
1057}
1058
1059static moo_sci_single *
1060_moo_combine_pair_sci_single(moo_target_table *target_table,
1061 moo_sci_single *sci1d,
1062 cpl_table *sci1d_table,
1063 moo_sci_single *psci1d,
1064 cpl_table *psci1d_table,
1065 moo_sci_single *sci2d,
1066 cpl_table *sci2d_table,
1067 moo_sci_single *psci2d,
1068 cpl_table *psci2d_table)
1069{
1070 moo_sci_single *sci_single = NULL;
1071 moo_sci_single *main_sci_single = NULL;
1072 int *sci2d_index = NULL;
1073 int *sci1d_index = NULL;
1074 int *psci2d_index = NULL;
1075 int *psci1d_index = NULL;
1076
1077 cpl_image *sci_img = NULL;
1078 cpl_image *sci_err_img = NULL;
1079 cpl_image *sci_qual_img = NULL;
1080 cpl_image *sci_sky = NULL;
1081
1082 cpl_errorstate prestate = cpl_errorstate_get();
1083
1084 cpl_ensure(target_table != NULL, CPL_ERROR_NULL_INPUT, NULL);
1085
1086 if (sci1d != NULL) {
1087 main_sci_single = sci1d;
1088 }
1089 else if (sci2d != NULL) {
1090 main_sci_single = sci2d;
1091 }
1092 else if (psci1d != NULL) {
1093 main_sci_single = psci1d;
1094 }
1095 else if (psci2d != NULL) {
1096 main_sci_single = psci2d;
1097 }
1098
1099 if (main_sci_single == NULL) {
1100 return NULL;
1101 }
1102
1103 moo_try_check(sci_single = moo_sci_single_new(main_sci_single->type), " ");
1104
1105 moo_pfits_append_hduclass_data(sci_single->header, sci_single->type, -1);
1106 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1107 MOO_PFITS_CRPIX1);
1108 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1109 MOO_PFITS_CRVAL1);
1110 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1111 MOO_PFITS_CD1_1);
1112 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1113 MOO_PFITS_CD1_2);
1114 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1115 MOO_PFITS_CTYPE1);
1116 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1117 MOO_PFITS_CUNIT1);
1118 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1119 MOO_PFITS_BUNIT);
1120 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1121 MOO_PFITS_CRPIX2);
1122 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1123 MOO_PFITS_CRVAL2);
1124 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1125 MOO_PFITS_CD2_1);
1126 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1127 MOO_PFITS_CD2_2);
1128 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1129 MOO_PFITS_CTYPE2);
1130 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1131 MOO_PFITS_BUNIT);
1132 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1133 MOO_PFITS_WAVELMIN);
1134 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1135 MOO_PFITS_WAVELMAX);
1136 cpl_propertylist_copy_property(sci_single->header, main_sci_single->header,
1137 MOO_PFITS_SPECBIN);
1138 int nx = hdrl_image_get_size_x(main_sci_single->image);
1139 int nb_target = cpl_table_get_nrow(target_table->table);
1140
1141 sci_single->image = hdrl_image_new(nx, nb_target);
1142 sci_single->sky = cpl_image_new(nx, nb_target, CPL_TYPE_DOUBLE);
1143 sci_single->qual = cpl_image_new(nx, nb_target, CPL_TYPE_INT);
1144
1145 sci_img = hdrl_image_get_image(sci_single->image);
1146 /* create the mask if empty */
1147 cpl_image_get_bpm(sci_img);
1148
1149 sci_err_img = hdrl_image_get_error(sci_single->image);
1150 sci_qual_img = sci_single->qual;
1151 sci_sky = sci_single->sky;
1152
1153 const char *transname[] = { MOO_TARGET_TABLE_TRANSRI,
1154 MOO_TARGET_TABLE_TRANSYJ,
1155 MOO_TARGET_TABLE_TRANSH };
1156 const char *ptransname[] = { MOO_TARGET_TABLE_PTRANSRI,
1157 MOO_TARGET_TABLE_PTRANSYJ,
1158 MOO_TARGET_TABLE_PTRANSH };
1159 const char *exptimenames[] = { MOO_TARGET_TABLE_EXPTIMERI,
1160 MOO_TARGET_TABLE_EXPTIMEYJ,
1161 MOO_TARGET_TABLE_EXPTIMEH };
1162 const char *exptimename = exptimenames[sci_single->type];
1163
1164 float *transt = cpl_table_get_data_float(target_table->table,
1165 transname[sci_single->type]);
1166 float *ptranst = cpl_table_get_data_float(target_table->table,
1167 ptransname[sci_single->type]);
1168
1169 int *indexrbnt =
1170 cpl_table_get_data_int(target_table->table, MOO_TARGET_TABLE_INDEXRBN);
1171 int *pindexrbnt = cpl_table_get_data_int(target_table->table,
1172 MOO_TARGET_TABLE_PAIREDINDEXRBN);
1173 char **obstypet = cpl_table_get_data_string(target_table->table,
1174 MOO_TARGET_TABLE_OBSTYPE);
1175 sci2d_index = cpl_calloc(nb_target, sizeof(int));
1176 sci1d_index = cpl_calloc(nb_target, sizeof(int));
1177
1178 psci2d_index = cpl_calloc(nb_target, sizeof(int));
1179 psci1d_index = cpl_calloc(nb_target, sizeof(int));
1180
1181 for (int i = 1; i <= nb_target; i++) {
1182 double exptime = NAN;
1183 int idx = i - 1;
1184 sci2d_index[idx] = -1;
1185 psci2d_index[idx] = -1;
1186 sci1d_index[idx] = -1;
1187
1188 cpl_table_set_int(target_table->table, MOO_TARGET_TABLE_INDEXTARG, idx,
1189 i);
1190
1191 int indexrbn = indexrbnt[idx];
1192 int pindexrbn = pindexrbnt[idx];
1193 char *obstype = obstypet[idx];
1194
1195 if (strcmp(obstype, MOO_OBSTYPE_OBSNOD) == 0 ||
1196 strcmp(obstype, MOO_OBSTYPE_SKYRESNOD) == 0) {
1197 cpl_table_select_all(sci2d_table);
1198
1199 int size = cpl_table_and_selected_int(sci2d_table,
1200 MOO_TARGET_TABLE_INDEXRBN,
1201 CPL_EQUAL_TO, indexrbn);
1202 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1203 cpl_array *sel = cpl_table_where_selected(sci2d_table);
1204
1205 int tidx = cpl_array_get_cplsize(sel, 0, NULL);
1206
1207 cpl_array_delete(sel);
1208
1209 exptime =
1210 cpl_table_get_double(sci2d_table, exptimename, tidx, NULL);
1211 sci2d_index[idx] = tidx;
1212 }
1213 else if (strcmp(obstype, MOO_OBSTYPE_OBSPNOD) == 0) {
1214 cpl_table_select_all(psci2d_table);
1215
1216 int size = cpl_table_and_selected_int(psci2d_table,
1217 MOO_TARGET_TABLE_INDEXRBN,
1218 CPL_EQUAL_TO, indexrbn);
1219 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1220 cpl_array *sel = cpl_table_where_selected(psci2d_table);
1221
1222 int tidx = cpl_array_get_cplsize(sel, 0, NULL);
1223
1224 cpl_array_delete(sel);
1225 psci2d_index[idx] = tidx;
1226 }
1227 else if (strcmp(obstype, MOO_OBSTYPE_OBSSWITCH) == 0) {
1228 cpl_table_select_all(sci2d_table);
1229
1230 int size = cpl_table_and_selected_int(sci2d_table,
1231 MOO_TARGET_TABLE_INDEXRBN,
1232 CPL_EQUAL_TO, indexrbn);
1233 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1234 cpl_array *sel = cpl_table_where_selected(sci2d_table);
1235
1236 int tidx = cpl_array_get_cplsize(sel, 0, NULL);
1237
1238 cpl_array_delete(sel);
1239 sci2d_index[idx] = tidx;
1240
1241 cpl_table_select_all(psci2d_table);
1242
1243 size = cpl_table_and_selected_int(psci2d_table,
1244 MOO_TARGET_TABLE_INDEXRBN,
1245 CPL_EQUAL_TO, pindexrbn);
1246 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1247 sel = cpl_table_where_selected(psci2d_table);
1248
1249 tidx = cpl_array_get_cplsize(sel, 0, NULL);
1250 cpl_array_delete(sel);
1251
1252 psci2d_index[idx] = tidx;
1253 }
1254 else if (strcmp(obstype, MOO_OBSTYPE_OBSSWITCHSTARE) == 0) {
1255 cpl_table_select_all(sci1d_table);
1256
1257 int size = cpl_table_and_selected_int(sci1d_table,
1258 MOO_TARGET_TABLE_INDEXRBN,
1259 CPL_EQUAL_TO, indexrbn);
1260 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1261 cpl_array *sel = cpl_table_where_selected(sci1d_table);
1262
1263 int tidx = cpl_array_get_cplsize(sel, 0, NULL);
1264
1265 cpl_array_delete(sel);
1266 sci1d_index[idx] = tidx;
1267
1268 cpl_table_select_all(psci1d_table);
1269
1270 size = cpl_table_and_selected_int(psci1d_table,
1271 MOO_TARGET_TABLE_INDEXRBN,
1272 CPL_EQUAL_TO, pindexrbn);
1273 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1274 sel = cpl_table_where_selected(psci1d_table);
1275
1276 tidx = cpl_array_get_cplsize(sel, 0, NULL);
1277 cpl_array_delete(sel);
1278
1279 psci1d_index[idx] = tidx;
1280 }
1281 else if (strcmp(obstype, MOO_OBSTYPE_OBSNODSTARE) == 0) {
1282 cpl_table_select_all(sci2d_table);
1283
1284 int size = cpl_table_and_selected_int(sci2d_table,
1285 MOO_TARGET_TABLE_INDEXRBN,
1286 CPL_EQUAL_TO, indexrbn);
1287 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1288 cpl_array *sel = cpl_table_where_selected(sci2d_table);
1289
1290 int tidx = cpl_array_get_cplsize(sel, 0, NULL);
1291
1292 cpl_array_delete(sel);
1293 sci2d_index[idx] = tidx;
1294
1295 cpl_table_select_all(psci1d_table);
1296
1297 size = cpl_table_and_selected_int(psci1d_table,
1298 MOO_TARGET_TABLE_INDEXRBN,
1299 CPL_EQUAL_TO, pindexrbn);
1300 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1301 sel = cpl_table_where_selected(psci1d_table);
1302
1303 tidx = cpl_array_get_cplsize(sel, 0, NULL);
1304 cpl_array_delete(sel);
1305
1306 psci1d_index[idx] = tidx;
1307 }
1308 else if (strcmp(obstype, MOO_OBSTYPE_OBSPNODSTARE) == 0) {
1309 cpl_table_select_all(psci2d_table);
1310
1311 int size = cpl_table_and_selected_int(psci2d_table,
1312 MOO_TARGET_TABLE_INDEXRBN,
1313 CPL_EQUAL_TO, pindexrbn);
1314 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1315 cpl_array *sel = cpl_table_where_selected(psci2d_table);
1316
1317 int tidx = cpl_array_get_cplsize(sel, 0, NULL);
1318
1319 cpl_array_delete(sel);
1320 psci2d_index[idx] = tidx;
1321
1322 cpl_table_select_all(sci1d_table);
1323
1324 size = cpl_table_and_selected_int(sci1d_table,
1325 MOO_TARGET_TABLE_INDEXRBN,
1326 CPL_EQUAL_TO, indexrbn);
1327 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1328 sel = cpl_table_where_selected(sci1d_table);
1329
1330 tidx = cpl_array_get_cplsize(sel, 0, NULL);
1331 cpl_array_delete(sel);
1332
1333 sci1d_index[idx] = tidx;
1334 }
1335 else if (strcmp(obstype, MOO_OBSTYPE_OBSSTARE) == 0 ||
1336 strcmp(obstype, MOO_OBSTYPE_SKYRESSTARE) == 0) {
1337 cpl_table_select_all(sci1d_table);
1338
1339 int size = cpl_table_and_selected_int(sci1d_table,
1340 MOO_TARGET_TABLE_INDEXRBN,
1341 CPL_EQUAL_TO, indexrbn);
1342 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1343 cpl_array *sel = cpl_table_where_selected(sci1d_table);
1344
1345 int tidx = cpl_array_get_cplsize(sel, 0, NULL);
1346 exptime =
1347 cpl_table_get_double(sci1d_table, exptimename, tidx, NULL);
1348 cpl_array_delete(sel);
1349 sci1d_index[idx] = tidx;
1350 }
1351 else if (strcmp(obstype, MOO_OBSTYPE_OBSPSTARE) == 0 ||
1352 strcmp(obstype, MOO_OBSTYPE_SKYRESPSTARE) == 0) {
1353 cpl_table_select_all(psci1d_table);
1354
1355 int size = cpl_table_and_selected_int(psci1d_table,
1356 MOO_TARGET_TABLE_INDEXRBN,
1357 CPL_EQUAL_TO, indexrbn);
1358 cpl_ensure(size == 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
1359 cpl_array *sel = cpl_table_where_selected(psci1d_table);
1360
1361 int tidx = cpl_array_get_cplsize(sel, 0, NULL);
1362
1363 cpl_array_delete(sel);
1364 psci1d_index[idx] = tidx;
1365 }
1366 cpl_table_set_double(target_table->table, exptimename, idx, exptime);
1367 }
1368/* The following addresses an issue with the gcc9 compiler series prior to
1369 * gcc 9.3. These compiler versions require that the variable '__func__'
1370 * appears in the data sharing clause if default(none) is used. However
1371 * adding it to the data sharing clause breaks older compiler versions
1372 * where these variables are pre-determined as shared.
1373 * This was fixed in gcc 9.3 and OpenMP 5.1.
1374 */
1375#ifdef _OPENMP
1376#if (__GNUC__ == 9) && (__GNUC_MINOR__ < 3)
1377#pragma omp parallel shared(nb_target, indexrbnt, pindexrbnt, transt, ptranst, \
1378 obstypet, target_table, sci2d, psci2d, sci1d, \
1379 psci1d, sci_single, sci_qual_img, sci_img, \
1380 sci_err_img, sci_sky, nx, sci2d_index, \
1381 psci2d_index, sci1d_index, psci1d_index)
1382#else
1383#pragma omp parallel default(none) \
1384 shared(nb_target, indexrbnt, pindexrbnt, transt, ptranst, obstypet, \
1385 target_table, sci2d, psci2d, sci1d, psci1d, sci_single, \
1386 sci_qual_img, sci_img, sci_err_img, sci_sky, nx, sci2d_index, \
1387 psci2d_index, sci1d_index, psci1d_index)
1388#endif
1389 {
1390#pragma omp for
1391#endif
1392 for (int i = 1; i <= nb_target; i++) {
1393 int idx = i - 1;
1394 cpl_table_set_int(target_table->table, MOO_TARGET_TABLE_INDEXTARG,
1395 idx, i);
1396
1397 char *obstype = obstypet[idx];
1398 float trans = transt[idx];
1399 float ptrans = ptranst[idx];
1400 if (strcmp(obstype, MOO_OBSTYPE_OBSNOD) == 0 ||
1401 strcmp(obstype, MOO_OBSTYPE_SKYRESNOD) == 0) {
1402 int tidx = sci2d_index[idx] + 1;
1403 hdrl_image *himg = moo_sci_single_get_image(sci2d);
1404 cpl_image *fluxes = hdrl_image_get_image(himg);
1405 cpl_image *skyimg = moo_sci_single_get_sky(sci2d);
1406 cpl_image *errs = hdrl_image_get_error(himg);
1407 cpl_image *qualimg = moo_sci_single_get_qual(sci2d);
1408
1409 for (int j = 1; j <= nx; j++) {
1410 int rej;
1411 double err = cpl_image_get(errs, j, tidx, &rej);
1412 double flux = cpl_image_get(fluxes, j, tidx, &rej);
1413 double sky = cpl_image_get(skyimg, j, tidx, &rej);
1414 double qual = cpl_image_get(qualimg, j, tidx, &rej);
1415 cpl_image_set(sci_img, j, i, flux);
1416 cpl_image_set(sci_err_img, j, i, err);
1417 cpl_image_set(sci_sky, j, i, sky);
1418 cpl_image_set(sci_qual_img, j, i, qual);
1419 }
1420 }
1421 else if (strcmp(obstype, MOO_OBSTYPE_OBSPNOD) == 0) {
1422 int tidx = psci2d_index[idx] + 1;
1423 hdrl_image *himg = moo_sci_single_get_image(psci2d);
1424 cpl_image *fluxes = hdrl_image_get_image(himg);
1425 cpl_image *skyimg = moo_sci_single_get_sky(psci2d);
1426 cpl_image *errs = hdrl_image_get_error(himg);
1427 cpl_image *qualimg = moo_sci_single_get_qual(psci2d);
1428
1429 for (int j = 1; j <= nx; j++) {
1430 int rej;
1431 double err = cpl_image_get(errs, j, tidx, &rej);
1432 double flux = cpl_image_get(fluxes, j, tidx, &rej);
1433 double sky = cpl_image_get(skyimg, j, tidx, &rej);
1434 double qual = cpl_image_get(qualimg, j, tidx, &rej);
1435 cpl_image_set(sci_img, j, i, flux);
1436 cpl_image_set(sci_err_img, j, i, err);
1437 cpl_image_set(sci_sky, j, i, sky);
1438 cpl_image_set(sci_qual_img, j, i, qual);
1439 }
1440 }
1441 else if (strcmp(obstype, MOO_OBSTYPE_OBSSWITCH) == 0) {
1442 int tidx = sci2d_index[idx] + 1;
1443 int ptidx = psci2d_index[idx] + 1;
1444
1445 double transsum = trans + ptrans;
1446 hdrl_image *himg = moo_sci_single_get_image(sci2d);
1447 cpl_image *fluxes = hdrl_image_get_image(himg);
1448 cpl_image *skyimg = moo_sci_single_get_sky(sci2d);
1449 cpl_image *errs = hdrl_image_get_error(himg);
1450 cpl_image *qualimg = moo_sci_single_get_qual(sci2d);
1451
1452 hdrl_image *phimg = moo_sci_single_get_image(psci2d);
1453 cpl_image *pfluxes = hdrl_image_get_image(phimg);
1454 cpl_image *pskyimg = moo_sci_single_get_sky(psci2d);
1455 cpl_image *perrs = hdrl_image_get_error(phimg);
1456 cpl_image *pqualimg = moo_sci_single_get_qual(psci2d);
1457
1458 for (int j = 1; j <= nx; j++) {
1459 int rej1;
1460 double err1 = cpl_image_get(errs, j, tidx, &rej1);
1461 double flux1 = cpl_image_get(fluxes, j, tidx, &rej1);
1462 double sky1 = cpl_image_get(skyimg, j, tidx, &rej1);
1463 int qual1 = (int)cpl_image_get(qualimg, j, tidx, &rej1);
1464
1465 int rej2;
1466 double err2 = cpl_image_get(perrs, j, ptidx, &rej2);
1467 double flux2 = cpl_image_get(pfluxes, j, ptidx, &rej2);
1468 double sky2 = cpl_image_get(pskyimg, j, ptidx, &rej2);
1469 int qual2 = (int)cpl_image_get(pqualimg, j, ptidx, &rej2);
1470
1471 int qual = qual1 | qual2;
1472 double flux = NAN;
1473 double err = NAN;
1474 double sky = NAN;
1475
1476 if (!rej1 && !rej2) {
1477 flux = (trans * flux1 + ptrans * flux2) / transsum * 2;
1478
1479 err =
1480 sqrt((trans * err1 * err1 + ptrans * err2 * err2) /
1481 transsum) *
1482 2.;
1483 sky = (trans * sky1 + ptrans * sky2) / transsum * 2;
1484 }
1485
1486 cpl_image_set(sci_img, j, i, flux);
1487 cpl_image_set(sci_err_img, j, i, err);
1488 cpl_image_set(sci_sky, j, i, sky);
1489 cpl_image_set(sci_qual_img, j, i, qual);
1490 }
1491 }
1492 else if (strcmp(obstype, MOO_OBSTYPE_OBSNODSTARE) == 0) {
1493 int tidx = sci2d_index[idx] + 1;
1494 int ptidx = psci1d_index[idx] + 1;
1495
1496 double transsum = trans + ptrans;
1497
1498 hdrl_image *himg = moo_sci_single_get_image(sci2d);
1499 cpl_image *fluxes = hdrl_image_get_image(himg);
1500 cpl_image *skyimg = moo_sci_single_get_sky(sci2d);
1501 cpl_image *errs = hdrl_image_get_error(himg);
1502 cpl_image *qualimg = moo_sci_single_get_qual(sci2d);
1503
1504 hdrl_image *phimg = moo_sci_single_get_image(psci1d);
1505 cpl_image *pfluxes = hdrl_image_get_image(phimg);
1506 cpl_image *pskyimg = moo_sci_single_get_sky(psci1d);
1507 cpl_image *perrs = hdrl_image_get_error(phimg);
1508 cpl_image *pqualimg = moo_sci_single_get_qual(psci1d);
1509
1510 for (int j = 1; j <= nx; j++) {
1511 int rej1;
1512 double err1 = cpl_image_get(errs, j, tidx, &rej1);
1513 double flux1 = cpl_image_get(fluxes, j, tidx, &rej1);
1514 double sky1 = cpl_image_get(skyimg, j, tidx, &rej1);
1515 int qual1 = (int)cpl_image_get(qualimg, j, tidx, &rej1);
1516
1517 int rej2;
1518 double err2 = cpl_image_get(perrs, j, ptidx, &rej2);
1519 double flux2 = cpl_image_get(pfluxes, j, ptidx, &rej2);
1520 double sky2 = cpl_image_get(pskyimg, j, ptidx, &rej2);
1521 int qual2 = (int)cpl_image_get(pqualimg, j, ptidx, &rej2);
1522 int qual = qual1 | qual2;
1523 double flux = NAN;
1524 double err = NAN;
1525 double sky = NAN;
1526
1527 if (rej1) {
1528 if (!rej2) {
1529 flux = flux2 * 2;
1530 err = err2 * 2;
1531 qual = qual2;
1532 }
1533 }
1534 else {
1535 if (!rej2) {
1536 flux =
1537 (trans * flux1 + ptrans * flux2) / transsum * 2;
1538
1539 err = sqrt((trans * err1 * err1 +
1540 ptrans * err2 * err2) /
1541 transsum) *
1542 2.;
1543 sky = (trans * sky1 + ptrans * sky2) / transsum * 2;
1544 }
1545 else {
1546 flux = flux1 * 2;
1547 err = err1 * 2;
1548 qual = qual1;
1549 }
1550 }
1551
1552 cpl_image_set(sci_img, j, i, flux);
1553 cpl_image_set(sci_err_img, j, i, err);
1554 cpl_image_set(sci_sky, j, i, sky);
1555 cpl_image_set(sci_qual_img, j, i, qual);
1556 }
1557 }
1558 else if (strcmp(obstype, MOO_OBSTYPE_OBSPNODSTARE) == 0) {
1559 int ptidx = psci2d_index[idx] + 1;
1560 int tidx = sci1d_index[idx] + 1;
1561
1562 double transsum = trans + ptrans;
1563 hdrl_image *himg = moo_sci_single_get_image(sci1d);
1564 cpl_image *fluxes = hdrl_image_get_image(himg);
1565 cpl_image *skyimg = moo_sci_single_get_sky(sci1d);
1566 cpl_image *errs = hdrl_image_get_error(himg);
1567 cpl_image *qualimg = moo_sci_single_get_qual(sci1d);
1568
1569 hdrl_image *phimg = moo_sci_single_get_image(psci2d);
1570 cpl_image *pfluxes = hdrl_image_get_image(phimg);
1571 cpl_image *pskyimg = moo_sci_single_get_sky(psci2d);
1572 cpl_image *perrs = hdrl_image_get_error(phimg);
1573 cpl_image *pqualimg = moo_sci_single_get_qual(psci2d);
1574
1575 for (int j = 1; j <= nx; j++) {
1576 int rej1;
1577 double err1 = cpl_image_get(errs, j, tidx, &rej1);
1578 double flux1 = cpl_image_get(fluxes, j, tidx, &rej1);
1579 double sky1 = cpl_image_get(skyimg, j, tidx, &rej1);
1580 int qual1 = (int)cpl_image_get(qualimg, j, tidx, &rej1);
1581
1582 int rej2;
1583 double err2 = cpl_image_get(perrs, j, ptidx, &rej2);
1584 double flux2 = cpl_image_get(pfluxes, j, ptidx, &rej2);
1585 double sky2 = cpl_image_get(pskyimg, j, ptidx, &rej2);
1586 int qual2 = (int)cpl_image_get(pqualimg, j, ptidx, &rej2);
1587 int qual = qual1 | qual2;
1588 double flux = NAN;
1589 double err = NAN;
1590 double sky = NAN;
1591
1592 if (rej1) {
1593 if (!rej2) {
1594 flux = flux2 * 2;
1595 err = err2 * 2;
1596 qual = qual2;
1597 }
1598 }
1599 else {
1600 if (!rej2) {
1601 flux =
1602 (trans * flux1 + ptrans * flux2) / transsum * 2;
1603
1604 err = sqrt((trans * err1 * err1 +
1605 ptrans * err2 * err2) /
1606 transsum) *
1607 2.;
1608 sky = (trans * sky1 + ptrans * sky2) / transsum * 2;
1609 }
1610 else {
1611 flux = flux1 * 2;
1612 err = err1 * 2;
1613 qual = qual1;
1614 }
1615 }
1616
1617 cpl_image_set(sci_img, j, i, flux);
1618 cpl_image_set(sci_err_img, j, i, err);
1619 cpl_image_set(sci_sky, j, i, sky);
1620 cpl_image_set(sci_qual_img, j, i, qual);
1621 }
1622 }
1623 else if (strcmp(obstype, MOO_OBSTYPE_OBSSWITCHSTARE) == 0) {
1624 int ptidx = psci1d_index[idx] + 1;
1625 int tidx = sci1d_index[idx] + 1;
1626
1627 double transsum = trans + ptrans;
1628 hdrl_image *himg = moo_sci_single_get_image(sci1d);
1629 cpl_image *fluxes = hdrl_image_get_image(himg);
1630 cpl_image *skyimg = moo_sci_single_get_sky(sci1d);
1631 cpl_image *errs = hdrl_image_get_error(himg);
1632 cpl_image *qualimg = moo_sci_single_get_qual(sci1d);
1633
1634 hdrl_image *phimg = moo_sci_single_get_image(psci1d);
1635 cpl_image *pfluxes = hdrl_image_get_image(phimg);
1636 cpl_image *pskyimg = moo_sci_single_get_sky(psci1d);
1637 cpl_image *perrs = hdrl_image_get_error(phimg);
1638 cpl_image *pqualimg = moo_sci_single_get_qual(psci1d);
1639
1640 for (int j = 1; j <= nx; j++) {
1641 int rej1;
1642 double err1 = cpl_image_get(errs, j, tidx, &rej1);
1643 double flux1 = cpl_image_get(fluxes, j, tidx, &rej1);
1644 double sky1 = cpl_image_get(skyimg, j, tidx, &rej1);
1645 int qual1 = (int)cpl_image_get(qualimg, j, tidx, &rej1);
1646
1647 int rej2;
1648 double err2 = cpl_image_get(perrs, j, ptidx, &rej2);
1649 double flux2 = cpl_image_get(pfluxes, j, ptidx, &rej2);
1650 double sky2 = cpl_image_get(pskyimg, j, ptidx, &rej2);
1651 int qual2 = (int)cpl_image_get(pqualimg, j, ptidx, &rej2);
1652 int qual = qual1 | qual2;
1653 double flux = NAN;
1654 double err = NAN;
1655 double sky = NAN;
1656
1657 if (rej1) {
1658 if (!rej2) {
1659 flux = flux2 * 2;
1660 err = err2 * 2;
1661 qual = qual2;
1662 }
1663 }
1664 else {
1665 if (!rej2) {
1666 flux =
1667 (trans * flux1 + ptrans * flux2) / transsum * 2;
1668
1669 err = sqrt((trans * err1 * err1 +
1670 ptrans * err2 * err2) /
1671 transsum) *
1672 2.;
1673 sky = (trans * sky1 + ptrans * sky2) / transsum * 2;
1674 }
1675 else {
1676 flux = flux1 * 2;
1677 err = err1 * 2;
1678 qual = qual1;
1679 }
1680 }
1681
1682 cpl_image_set(sci_img, j, i, flux);
1683 cpl_image_set(sci_err_img, j, i, err);
1684 cpl_image_set(sci_sky, j, i, sky);
1685 cpl_image_set(sci_qual_img, j, i, qual);
1686 }
1687 }
1688 else if (strcmp(obstype, MOO_OBSTYPE_OBSSTARE) == 0 ||
1689 strcmp(obstype, MOO_OBSTYPE_SKYRESSTARE) == 0) {
1690 int tidx = sci1d_index[idx] + 1;
1691 hdrl_image *himg = moo_sci_single_get_image(sci1d);
1692 cpl_image *fluxes = hdrl_image_get_image(himg);
1693 cpl_image *skyimg = moo_sci_single_get_sky(sci1d);
1694 cpl_image *errs = hdrl_image_get_error(himg);
1695 cpl_image *qualimg = moo_sci_single_get_qual(sci1d);
1696
1697 for (int j = 1; j <= nx; j++) {
1698 int rej;
1699 double err = cpl_image_get(errs, j, tidx, &rej);
1700 double flux = cpl_image_get(fluxes, j, tidx, &rej);
1701 double sky = cpl_image_get(skyimg, j, tidx, &rej);
1702 double qual = cpl_image_get(qualimg, j, tidx, &rej);
1703 cpl_image_set(sci_img, j, i, flux);
1704 cpl_image_set(sci_err_img, j, i, err);
1705 cpl_image_set(sci_sky, j, i, sky);
1706 cpl_image_set(sci_qual_img, j, i, qual);
1707 }
1708 }
1709 else if (strcmp(obstype, MOO_OBSTYPE_OBSPSTARE) == 0 ||
1710 strcmp(obstype, MOO_OBSTYPE_SKYRESPSTARE) == 0) {
1711 int tidx = psci1d_index[idx] + 1;
1712 hdrl_image *himg = moo_sci_single_get_image(psci1d);
1713 cpl_image *fluxes = hdrl_image_get_image(himg);
1714 cpl_image *skyimg = moo_sci_single_get_sky(psci1d);
1715 cpl_image *errs = hdrl_image_get_error(himg);
1716 cpl_image *qualimg = moo_sci_single_get_qual(psci1d);
1717
1718 for (int j = 1; j <= nx; j++) {
1719 int rej;
1720 double err = cpl_image_get(errs, j, tidx, &rej);
1721 double flux = cpl_image_get(fluxes, j, tidx, &rej);
1722 double sky = cpl_image_get(skyimg, j, tidx, &rej);
1723 double qual = cpl_image_get(qualimg, j, tidx, &rej);
1724 cpl_image_set(sci_img, j, i, flux);
1725 cpl_image_set(sci_err_img, j, i, err);
1726 cpl_image_set(sci_sky, j, i, sky);
1727 cpl_image_set(sci_qual_img, j, i, qual);
1728 }
1729 }
1730 }
1731#ifdef _OPENMP
1732 }
1733#endif
1734moo_try_cleanup:
1735 cpl_free(sci2d_index);
1736 cpl_free(sci1d_index);
1737 cpl_free(psci2d_index);
1738 cpl_free(psci1d_index);
1739 if (!cpl_errorstate_is_equal(prestate)) {
1740 moo_sci_single_delete(sci_single);
1741 sci_single = NULL;
1742 }
1743 return sci_single;
1744}
1745moo_sci *
1746moo_combine_pair_sci(moo_target_table *target_table,
1747 moo_sci *sci1d,
1748 moo_sci *psci1d,
1749 moo_sci *sci2d,
1750 moo_sci *psci2d,
1751 const char *filename)
1752{
1753 moo_sci *sci = NULL;
1754 moo_sci *main_sci = NULL;
1755 cpl_table *sci1d_table = NULL;
1756 cpl_table *psci1d_table = NULL;
1757 cpl_table *sci2d_table = NULL;
1758 cpl_table *psci2d_table = NULL;
1759
1760 cpl_ensure(target_table != NULL, CPL_ERROR_NULL_INPUT, NULL);
1761
1762 cpl_errorstate prestate = cpl_errorstate_get();
1763
1764 unsigned int badpix_level =
1766
1767 if (psci1d != NULL) {
1768 main_sci = psci1d;
1769 psci1d_table = moo_sci_get_target_table(psci1d)->table;
1770 }
1771 if (psci2d != NULL) {
1772 main_sci = psci2d;
1773 psci2d_table = moo_sci_get_target_table(psci2d)->table;
1774 }
1775 if (sci2d != NULL) {
1776 main_sci = sci2d;
1777 sci2d_table = moo_sci_get_target_table(sci2d)->table;
1778 }
1779
1780 if (sci1d != NULL) {
1781 main_sci = sci1d;
1782 sci1d_table = moo_sci_get_target_table(sci1d)->table;
1783 }
1784
1785 if (main_sci == NULL) {
1786 return NULL;
1787 }
1788 moo_fits_create(filename);
1789 sci = moo_sci_new();
1790 sci->filename = filename;
1791 sci->primary_header = cpl_propertylist_duplicate(main_sci->primary_header);
1792
1793 cpl_msg_info(__func__, "Combine pair of SCI files");
1794 sci->target_table = target_table;
1795
1796 cpl_msg_indent_more();
1797
1798 for (int i = 0; i < 3; i++) {
1799 moo_sci_single *sci_single = NULL;
1800 moo_sci_single *sci1d_single = NULL;
1801 moo_sci_single *psci1d_single = NULL;
1802 moo_sci_single *sci2d_single = NULL;
1803 moo_sci_single *psci2d_single = NULL;
1804
1805 if (sci1d != NULL) {
1806 sci1d_single = moo_sci_load_single(sci1d, i, badpix_level);
1807 }
1808 if (psci1d != NULL) {
1809 psci1d_single = moo_sci_load_single(psci1d, i, badpix_level);
1810 }
1811 if (sci2d != NULL) {
1812 sci2d_single = moo_sci_load_single(sci2d, i, badpix_level);
1813 }
1814 if (psci2d != NULL) {
1815 psci2d_single = moo_sci_load_single(psci2d, i, badpix_level);
1816 }
1817 moo_try_check(sci_single = _moo_combine_pair_sci_single(
1818 target_table, sci1d_single, sci1d_table,
1819 psci1d_single, psci1d_table, sci2d_single,
1820 sci2d_table, psci2d_single, psci2d_table),
1821 " ");
1822 moo_sci_add_single(sci, i, sci_single);
1823 }
1825
1826moo_try_cleanup:
1827 cpl_msg_indent_less();
1828
1829 if (!cpl_errorstate_is_equal(prestate)) {
1830 cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_OUTPUT,
1831 "Error in combine pair (2D)");
1832 moo_sci_delete(sci);
1833 sci = NULL;
1834 }
1835 return sci;
1836}
1837
#define MOO_BADPIX_OUTSIDE_DATA_RANGE
Definition: moo_badpix.h:62
#define MOO_BADPIX_CALIB_DEFECT
Definition: moo_badpix.h:48
cpl_error_code moo_fits_create(const char *filename)
Create a new fits file with empty propertylist.
Definition: moo_fits.c:533
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.
Definition: moo_rbn.c:360
moo_rbn_single * moo_rbn_get_single(moo_rbn *self, moo_detector_type type)
Get a RBN single from RBN.
Definition: moo_rbn.c:325
cpl_table * moo_rbn_get_fibre_table(moo_rbn *self)
Get the FIBRE TABLE in RBN.
Definition: moo_rbn.c:397
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_image * moo_sci_single_get_sky(moo_sci_single *self)
Get sky of sci single.
hdrl_image * moo_sci_single_get_image(moo_sci_single *self)
Get image of SCI_SINGLE.
cpl_image * moo_sci_single_get_qual(moo_sci_single *self)
Get image of qual.
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.
Definition: moo_sci.c:132
moo_sci_single * moo_sci_load_single(moo_sci *self, moo_detector_type type, int level)
Load the type part in SCI and return it.
Definition: moo_sci.c:323
void moo_sci_delete(moo_sci *self)
Delete a moo_sci.
Definition: moo_sci.c:84
moo_sci * moo_sci_new(void)
Create a new moo_sci.
Definition: moo_sci.c:66
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.
Definition: moo_sci.c:216
void moo_sci_save(moo_sci *self, const char *filename)
Save a moo_sci to a FITS file.
Definition: moo_sci.c:385
moo_target_table * moo_sci_get_target_table(moo_sci *self)
Get the target table of SCI file.
Definition: moo_sci.c:284
moo_target_table * moo_target_table_new(void)
Create a new moo_target_table.
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
moo_sci * moo_combine_pair(moo_rbn *nod_rbn, moo_rbn *sky_rbn, moo_rbn *obj_rbn, moo_target_table *target_table, moo_f2f *f2f, const cpl_frame *solflux_frame, const cpl_frame *airglow_group_frame, const cpl_frame *airglow_var_frame, moo_combine_pair_params *combine_pair_params, moo_sub_sky_stare_params *sky_params, const char *filename, moo_products *products, const cpl_frame *ref_frame)
Combine the extracted spectra from a same objec.
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
Definition: moo_pfits.c:382
double moo_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: moo_pfits.c:362
cpl_error_code moo_pfits_append_hduclass_data(cpl_propertylist *plist, moo_detector_type type, int ntas)
Set the HDUCLASS DATA Keyword.
Definition: moo_pfits.c:1504
double moo_pfits_get_exptime(const cpl_propertylist *plist)
find out the EXPTIME value
Definition: moo_pfits.c:1039
cpl_frame * moo_products_add_sci(moo_products *self, moo_sci *sci, cpl_frame_level level, const char *tag, const char *filename, const cpl_frame *inherit_frame)
create a product from a SCI object
Definition: moo_products.c:420
the different type of detectors