MOONS Pipeline Reference Manual 0.13.2
moo_coadd.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_coadd.h"
32#include "moo_fits.h"
33#include "moo_pfits.h"
34#include "moo_badpix.h"
35#include "moo_utils.h"
36/*----------------------------------------------------------------------------*/
41/*----------------------------------------------------------------------------*/
42
45/*-----------------------------------------------------------------------------
46 Function codes
47 -----------------------------------------------------------------------------*/
48typedef struct
49{
50 const char *name;
51 int *indexes;
52} _moo_target;
53
54
55static moo_target_table *
56_moo_coadd_target_table(moo_scilist *scilist)
57{
58 moo_target_table *res = NULL;
59
60 cpl_ensure(scilist != NULL, CPL_ERROR_NULL_INPUT, NULL);
61 int size = moo_scilist_get_size(scilist);
62 cpl_ensure(size > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
63 cpl_errorstate prestate = cpl_errorstate_get();
64
65 moo_sci *first = moo_scilist_get(scilist, 0);
66
68
69 for (int i = 1; i < size; i++) {
70 moo_sci *sci = moo_scilist_get(scilist, i);
72 moo_try_check(moo_target_table_merge(res, ttable), " ");
73 }
74
75moo_try_cleanup:
76 if (!cpl_errorstate_is_equal(prestate)) {
78 res = NULL;
79 }
80 return res;
81}
82
83
84static cpl_error_code
85_moo_create_pheader(cpl_propertylist *header, moo_scilist *scilist)
86{
87 cpl_ensure_code(header != NULL, CPL_ERROR_NULL_INPUT);
88 cpl_ensure_code(scilist != NULL, CPL_ERROR_NULL_INPUT);
89
90 int size = (int)moo_scilist_get_size(scilist);
91 double exptime_sum = 0.0;
92
93 for (int i = 0; i < size; i++) {
94 moo_sci *sci = moo_scilist_get(scilist, i);
95
96 double exptime = moo_pfits_get_exptime(sci->primary_header);
97 exptime_sum += exptime;
98 }
99
100 double pexptime = exptime_sum;
101
102 cpl_propertylist_append_double(header, MOO_PFITS_EXPTIME, pexptime);
103 cpl_propertylist_set_comment(header, MOO_PFITS_EXPTIME,
104 MOO_PFITS_EXPTIME_C);
105 moo_sci *sci = moo_scilist_get(scilist, 0);
106 cpl_propertylist *sci_primary_header = sci->primary_header;
107 cpl_propertylist_copy_property_regexp(header, sci_primary_header,
108 "ESO QC IS*", 0);
109 cpl_propertylist_copy_property(header, sci_primary_header,
110 MOO_PFITS_FLUXCAL);
111 return CPL_ERROR_NONE;
112}
113
114/*----------------------------------------------------------------------------*/
132/*----------------------------------------------------------------------------*/
133moo_sci *
134moo_coadd(moo_scilist *scilist, moo_coadd_params *params, const char *filename)
135{
136 moo_sci *sci = NULL;
137 int ntarget = 0;
138 _moo_target *targets = NULL;
139
140 cpl_ensure(scilist != NULL, CPL_ERROR_NULL_INPUT, NULL);
141 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
142 cpl_ensure(filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
143
144 cpl_errorstate prestate = cpl_errorstate_get();
145
146 unsigned int badpix_level =
148
149 int size = (int)moo_scilist_get_size(scilist);
150 cpl_ensure(size > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
151 cpl_msg_info(__func__, "Coadding %d frames with method %s", size,
152 params->method);
153
154 if (size == 1) {
155 cpl_frame *frame = cpl_frame_new();
156 cpl_frame_set_filename(frame, filename);
157
158 moo_sci *scif = moo_scilist_get(scilist, 0);
159 moo_sci_load(scif, badpix_level);
160 moo_try_check(moo_target_table_remove_coadd_cols(scif->target_table),
161 " ");
162 moo_sci_save(scif, filename);
163 sci = moo_sci_create(frame);
164
165 moo_sci_load(sci, badpix_level);
166
167 cpl_frame_delete(frame);
168 }
169 else {
170 const char **targnames = NULL;
171 moo_try_check(moo_fits_create(filename), " ");
172 moo_try_check(sci = moo_sci_new(), " ");
173 sci->filename = filename;
174 sci->primary_header = cpl_propertylist_new();
175 moo_try_check(_moo_create_pheader(sci->primary_header, scilist), " ");
176
177 moo_target_table *sci_target_table = NULL;
178 moo_try_check(sci_target_table = _moo_coadd_target_table(scilist), " ");
179 sci->target_table = sci_target_table;
180
181 moo_try_check(moo_target_table_remove_coadd_cols(sci_target_table),
182 " ");
183 ntarget = cpl_table_get_nrow(sci_target_table->table);
184
185 moo_try_check(targnames = cpl_table_get_data_string_const(
186 sci_target_table->table, MOO_TARGET_TABLE_TARGNAME),
187 " ");
188
189 targets = cpl_calloc(ntarget, sizeof(_moo_target));
190 int ftarget = 0;
191 for (int i = 0; i < ntarget; i++) {
192 const char *targname = targnames[i];
193
194 targets[i].indexes = cpl_calloc(size, sizeof(int));
195 int nb = 0;
196 double exptimeri = 0;
197 double exptimeyj = 0;
198 double exptimeh = 0;
199
200 for (int j = 0; j < size; j++) {
201 moo_sci *scif = moo_scilist_get(scilist, j);
203 int indextarg = moo_target_table_find_target(ttable, targname);
204 int tindex = moo_target_table_find_index(ttable, targname);
205 targets[i].name = targname;
206 targets[i].indexes[j] = indextarg;
207 if (tindex >= 0) {
208 nb++;
209 ftarget = j;
210 exptimeri +=
211 cpl_table_get_double(ttable->table,
212 MOO_TARGET_TABLE_EXPTIMERI, tindex,
213 NULL);
214 exptimeyj +=
215 cpl_table_get_double(ttable->table,
216 MOO_TARGET_TABLE_EXPTIMEYJ, tindex,
217 NULL);
218 exptimeh += cpl_table_get_double(ttable->table,
219 MOO_TARGET_TABLE_EXPTIMEH,
220 tindex, NULL);
221 }
222 }
223 moo_try_assure(nb > 0, CPL_ERROR_UNSPECIFIED, "Target %s not found",
224 targname);
225
226 cpl_table_set_double(sci_target_table->table,
227 MOO_TARGET_TABLE_EXPTIMERI, i, exptimeri);
228 cpl_table_set_double(sci_target_table->table,
229 MOO_TARGET_TABLE_EXPTIMEYJ, i, exptimeyj);
230 cpl_table_set_double(sci_target_table->table,
231 MOO_TARGET_TABLE_EXPTIMEH, i, exptimeh);
232 }
233
234 cpl_msg_indent_more();
235 moo_sci *first_sci = moo_scilist_get(scilist, ftarget);
236
237 for (int i = 0; i < 3; i++) {
238 moo_sci_single *sci_single = NULL;
239 moo_sci_single *first_sci_single = moo_sci_get_single(first_sci, i);
240
241 if (first_sci_single != NULL) {
242 sci_single = moo_sci_single_new(i);
243 cpl_propertylist *first_header =
244 moo_sci_single_get_header(first_sci_single);
245
246 moo_scilist_load_single(scilist, i, badpix_level);
247 hdrl_image *fimage = moo_sci_single_get_image(first_sci_single);
248
249 int nx = hdrl_image_get_size_x(fimage);
250
251 sci_single->image = hdrl_image_new(nx, ntarget);
252 cpl_propertylist_append(sci_single->header, first_header);
253 sci_single->sky = cpl_image_new(nx, ntarget, CPL_TYPE_DOUBLE);
254 sci_single->qual = cpl_image_new(nx, ntarget, CPL_TYPE_INT);
255
256 for (int j = 0; j < ntarget; j++) {
257 _moo_target target = targets[j];
258 hdrl_imagelist *list = hdrl_imagelist_new();
259 cpl_imagelist *qlist = cpl_imagelist_new();
260 cpl_imagelist *slist = cpl_imagelist_new();
261
262 for (int k = 0; k < size; k++) {
263 int idx = target.indexes[k];
264 moo_sci_single *current_single =
265 moo_scilist_get_single(scilist, k, i);
266 if (idx > 0) {
267 hdrl_image *current =
268 moo_sci_single_get_image(current_single);
269 cpl_image *qcurrent =
270 moo_sci_single_get_qual(current_single);
271 cpl_image *scurrent =
272 moo_sci_single_get_sky(current_single);
273
274 int cnx = hdrl_image_get_size_x(current);
275 hdrl_image *sub =
276 hdrl_image_extract(current, 1, idx, cnx, idx);
277 cpl_image *qsub =
278 cpl_image_extract(qcurrent, 1, idx, cnx, idx);
279 cpl_image *ssub =
280 cpl_image_extract(scurrent, 1, idx, cnx, idx);
281
282 int pos = hdrl_imagelist_get_size(list);
283
284 hdrl_imagelist_set(list, sub, pos);
285 cpl_imagelist_set(qlist, qsub, pos);
286 cpl_imagelist_set(slist, ssub, pos);
287 }
288 }
289 hdrl_image *out = NULL;
290 cpl_image *contrib = NULL;
291 cpl_image *skyout = NULL;
292 cpl_image *qout = NULL;
293
294
295 if (strcmp(params->method, MOO_COADD_METHOD_MEDIAN) == 0) {
296 hdrl_imagelist_collapse_median(list, &out, &contrib);
297 skyout = cpl_imagelist_collapse_median_create(slist);
298 qout = moo_imagelist_collapse_bitwiseor(qlist, list);
299 }
300 else if (strcmp(params->method, MOO_COADD_METHOD_MEAN) ==
301 0) {
302 hdrl_imagelist_collapse_mean(list, &out, &contrib);
303 skyout = cpl_imagelist_collapse_create(slist);
304 qout = moo_imagelist_collapse_bitwiseor(qlist, list);
305 }
306 else {
307 hdrl_imagelist_collapse_sigclip(list,
308 params->clip_kappa,
309 params->clip_kappa,
310 params->clip_niter,
311 &out, &contrib, NULL,
312 NULL);
313 skyout = cpl_imagelist_collapse_sigclip_create(
314 slist, params->clip_kappa, params->clip_kappa, 0.7,
315 CPL_COLLAPSE_MEAN, NULL);
316
317 qout = moo_imagelist_collapse_bitwiseor(qlist, list);
318 }
319
320 hdrl_image_copy(sci_single->image, out, 1, j + 1);
321 cpl_image_copy(sci_single->sky, skyout, 1, j + 1);
322 cpl_image_copy(sci_single->qual, qout, 1, j + 1);
323 hdrl_image_delete(out);
324 cpl_image_delete(qout);
325 cpl_image_delete(skyout);
326 cpl_image_delete(contrib);
327
328 hdrl_imagelist_delete(list);
329 cpl_imagelist_delete(qlist);
330 cpl_imagelist_delete(slist);
331 }
332 }
333 moo_sci_add_single(sci, i, sci_single);
334 }
335
336 moo_sci_add_target_table(sci, sci_target_table);
337 cpl_msg_indent_less();
338 }
339
340 moo_pfits_update_ncoadd(sci->primary_header, size);
341
342moo_try_cleanup:
343 if (targets != NULL) {
344 for (int i = 0; i < ntarget; i++) {
345 cpl_free(targets[i].indexes);
346 }
347 cpl_free(targets);
348 }
349 if (!cpl_errorstate_is_equal(prestate)) {
350 cpl_msg_error(__func__, "Error in coadding frames");
351 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
352 moo_sci_delete(sci);
353 sci = NULL;
354 }
355 return sci;
356}
#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
moo_sci_single * moo_sci_single_new(moo_detector_type type)
Create a new 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_propertylist * moo_sci_single_get_header(moo_sci_single *self)
Get header of 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.
Definition: moo_sci.c:132
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
moo_sci * moo_sci_create(const cpl_frame *frame)
Create a new empty SCI filename.
Definition: moo_sci.c:249
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
moo_sci_single * moo_sci_get_single(moo_sci *self, moo_detector_type type)
Get the type part in SCI and return it.
Definition: moo_sci.c:351
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_sci * moo_scilist_get(moo_scilist *self, int i)
Get the SCI at the position i in the list.
Definition: moo_scilist.c:384
moo_sci_single * moo_scilist_get_single(moo_scilist *self, int i, moo_detector_type type)
Get the SCI SINGLE at the position i in the list for the given detector.
Definition: moo_scilist.c:409
cpl_error_code moo_scilist_load_single(const moo_scilist *self, moo_detector_type type, int level)
Load the type part for all SCI in the scilist.
Definition: moo_scilist.c:439
cpl_size moo_scilist_get_size(const moo_scilist *self)
Get the number of SCI in the scilist.
Definition: moo_scilist.c:198
void moo_target_table_delete(moo_target_table *self)
Delete a moo_target_table.
moo_target_table * moo_target_table_duplicate(moo_target_table *self)
Duplicate an existing target_table.
cpl_error_code moo_target_table_merge(moo_target_table *self, moo_target_table *tomerge)
Merge two TARGET_TABLE.
int moo_target_table_find_index(moo_target_table *self, const char *targname)
find target indexspec in TARGET_TABLE
int moo_target_table_find_target(moo_target_table *self, const char *targname)
find target targindex in TARGET_TABLE
cpl_error_code moo_target_table_remove_coadd_cols(moo_target_table *self)
remove columns for coadd in target_table
moo_sci * moo_coadd(moo_scilist *scilist, moo_coadd_params *params, const char *filename)
Co-add reduced science frames in SCI format.
Definition: moo_coadd.c:134
cpl_error_code moo_pfits_update_ncoadd(cpl_propertylist *plist, int v)
set the ESO PRO NCOADD value
Definition: moo_pfits.c:1336
double moo_pfits_get_exptime(const cpl_propertylist *plist)
find out the EXPTIME value
Definition: moo_pfits.c:1039
cpl_image * moo_imagelist_collapse_bitwiseor(cpl_imagelist *list, hdrl_imagelist *datalist)
get the QUAL resulting in a bitwise OR operation on the QUAL list
Definition: moo_utils.c:1791
the different type of detectors