MOONS Pipeline Reference Manual 0.13.1
moo_cube.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 <cpl.h>
29#include "moo_pfits.h"
30#include "moo_fits.h"
31#include "moo_qc.h"
32#include "moo_cube.h"
33/*----------------------------------------------------------------------------*/
48/*----------------------------------------------------------------------------*/
49
52/*-----------------------------------------------------------------------------
53 Function codes
54 -----------------------------------------------------------------------------*/
55
56/*----------------------------------------------------------------------------*/
64/*----------------------------------------------------------------------------*/
65moo_cube *
67{
68 moo_cube *res = cpl_calloc(1, sizeof(moo_cube));
69 return res;
70}
71
72
73moo_cube *
74moo_cube_load(const cpl_frame *frame)
75{
76 cpl_ensure(frame != NULL, CPL_ERROR_NULL_INPUT, NULL);
77 const char *filename = cpl_frame_get_filename(frame);
78 cpl_ensure(filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
79
80 cpl_errorstate prev_state = cpl_errorstate_get();
81 moo_cube *res = moo_cube_new();
82
83 for (int i = 0; i < 2; i++) {
84 for (int j = 0; j < 3; j++) {
85 const char *extname = moo_detector_get_extname(j, i + 1);
86 cpl_propertylist *header = NULL;
87 header = moo_fits_load_extension_header(filename, NULL, extname);
88 res->data_header[i * 3 + j] = header;
89 if (header != NULL) {
90 int naxis = moo_pfits_get_naxis(header);
91 if (naxis == 3) {
92 res->data[i * 3 + j] =
93 moo_fits_load_extension_cube(filename, NULL, extname,
94 CPL_TYPE_FLOAT);
95 }
96 }
97 }
98 }
99 if (!cpl_errorstate_is_equal(prev_state)) {
100 moo_cube_delete(res);
101 res = NULL;
102 }
103
104 return res;
105}
106/*----------------------------------------------------------------------------*/
117/*----------------------------------------------------------------------------*/
118cpl_error_code
119moo_cube_set_data(moo_cube *self,
121 int ntas,
122 cpl_imagelist *data,
123 cpl_propertylist *header)
124{
125 cpl_ensure_code(ntas >= 1 && ntas <= 2, CPL_ERROR_ILLEGAL_INPUT);
126 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
127 cpl_ensure_code(header != NULL, CPL_ERROR_NULL_INPUT);
128
129 self->data[(ntas - 1) * 3 + type] = data;
130 self->data_header[(ntas - 1) * 3 + type] = header;
131
132 return CPL_ERROR_NONE;
133}
134/*----------------------------------------------------------------------------*/
145/*----------------------------------------------------------------------------*/
146cpl_error_code
147moo_cube_add_data(moo_cube *self,
148 cpl_imagelist *list,
150 int ntas)
151{
152 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
153 cpl_ensure_code(self->filename != NULL, CPL_ERROR_NULL_INPUT);
154 cpl_error_code status = CPL_ERROR_NONE;
155 cpl_errorstate prev_state = cpl_errorstate_get();
156 const char *extname = moo_detector_get_extname(type, ntas);
157 cpl_propertylist *header = cpl_propertylist_new();
158 cpl_propertylist_append_string(header, MOO_PFITS_EXTNAME, extname);
159
160 if (list != NULL) {
161 cpl_imagelist_save(list, self->filename, CPL_TYPE_FLOAT, header,
162 CPL_IO_EXTEND);
163 }
164 else {
165 cpl_propertylist_save(header, self->filename, CPL_IO_EXTEND);
166 }
167 moo_cube_set_data(self, type, ntas, list, header);
168
169 if (!cpl_errorstate_is_equal(prev_state)) {
170 cpl_msg_error("moo_cube", "Error for adding data to %s %s (%s)",
171 self->filename, extname,
172 cpl_error_get_message_default(cpl_error_get_code()));
173 cpl_msg_info("test", "test debug cube");
174 status = cpl_error_get_code();
175 }
176 return status;
177}
178
179/*----------------------------------------------------------------------------*/
189/*----------------------------------------------------------------------------*/
190void
191moo_cube_save(moo_cube *self, const char *filename)
192{
193 if (self != NULL) {
194 cpl_propertylist_save(self->primary_header, filename, CPL_IO_CREATE);
195 for (int i = 0; i < 2; i++) {
196 for (int j = 0; j < 3; j++) {
197 const char *extname = moo_detector_get_extname(j, i + 1);
198 moo_fits_write_extension_cube(self->data[i * 3 + j], filename,
199 NULL, extname, CPL_TYPE_FLOAT,
200 self->data_header[i * 3 + j]);
201 }
202 }
203 }
204}
205
206/*----------------------------------------------------------------------------*/
207static cpl_error_code
208_moo_coefs_normalise(cpl_imagelist *coefs, cpl_image *flux, cpl_image *exptime)
209{
210 if (coefs != NULL && flux != NULL && exptime != NULL) {
211 int size = cpl_imagelist_get_size(coefs);
212
213 for (int k = 0; k < size; k++) {
214 cpl_image *coef = cpl_imagelist_get(coefs, k);
215 cpl_image_divide(coef, flux);
216 }
217
218
219 for (int k = 1; k < size; k++) {
220 cpl_image *coef = cpl_imagelist_get(coefs, k);
221 cpl_image *power = cpl_image_power_create(exptime, k);
222 cpl_image_multiply(coef, power);
223 cpl_image_delete(power);
224 }
225 }
226 return CPL_ERROR_NONE;
227}
228/*----------------------------------------------------------------------------*/
236/*----------------------------------------------------------------------------*/
237cpl_error_code
238moo_cube_normalise(moo_cube *self, moo_saturate_map *map)
239{
240 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
241 cpl_ensure_code(map != NULL, CPL_ERROR_NULL_INPUT);
242 for (int i = 0; i < 6; i++) {
243 _moo_coefs_normalise(self->data[i], map->flux[i], map->exptime[i]);
244 }
245 return CPL_ERROR_NONE;
246}
247
248
249/*----------------------------------------------------------------------------*/
250static cpl_imagelist *
251_moo_cube_merge(cpl_imagelist *coefsa,
252 cpl_image *fluxa,
253 cpl_imagelist *coefsb,
254 cpl_image *fluxb)
255{
256 cpl_imagelist *result = NULL;
257
258 if (coefsa != NULL && coefsb != NULL) {
259 int size = cpl_imagelist_get_size(coefsa);
260 result = cpl_imagelist_duplicate(coefsa);
261 cpl_image *coefa = cpl_imagelist_get(coefsa, 0);
262 cpl_image *coefb = cpl_imagelist_get(coefsb, 0);
263 int nx = cpl_image_get_size_x(coefa);
264 int ny = cpl_image_get_size_y(coefa);
265 for (int j = 1; j <= ny; j++) {
266 for (int i = 1; i <= nx; i++) {
267 int reja = cpl_image_is_rejected(coefa, i, j);
268 int rejb = cpl_image_is_rejected(coefb, i, j);
269 if (reja) {
270 if (!rejb) {
271 for (int k = 0; k < size; k++) {
272 int rej;
273 cpl_image *ib = cpl_imagelist_get(coefsb, k);
274 cpl_image *rb = cpl_imagelist_get(result, k);
275 double v = cpl_image_get(ib, i, j, &rej);
276 cpl_image_set(rb, i, j, v);
277 }
278 }
279 }
280 else {
281 if (!rejb) {
282 int rej;
283 double fa = cpl_image_get(fluxa, i, j, &rej);
284 double fb = cpl_image_get(fluxb, i, j, &rej);
285 if (fa < fb) {
286 for (int k = 0; k < size; k++) {
287 cpl_image *ib = cpl_imagelist_get(coefsb, k);
288 cpl_image *rb = cpl_imagelist_get(result, k);
289 double v = cpl_image_get(ib, i, j, &rej);
290 cpl_image_set(rb, i, j, v);
291 }
292 }
293 }
294 }
295 }
296 }
297 }
298 return result;
299}
300/*----------------------------------------------------------------------------*/
310/*----------------------------------------------------------------------------*/
311moo_cube *
312moo_cube_merge(moo_cube *cubea,
313 moo_saturate_map *saturatea,
314 moo_cube *cubeb,
315 moo_saturate_map *saturateb)
316{
317 moo_cube *result = NULL;
318 cpl_ensure(cubea != NULL, CPL_ERROR_NULL_INPUT, NULL);
319 cpl_ensure(saturatea != NULL, CPL_ERROR_NULL_INPUT, NULL);
320 cpl_ensure(cubeb != NULL, CPL_ERROR_NULL_INPUT, NULL);
321 cpl_ensure(saturateb != NULL, CPL_ERROR_NULL_INPUT, NULL);
322
323 result = moo_cube_new();
324 result->primary_header = cpl_propertylist_duplicate(cubea->primary_header);
325 for (int i = 0; i < 6; i++) {
326 result->data[i] = _moo_cube_merge(cubea->data[i], saturatea->flux[i],
327 cubeb->data[i], saturateb->flux[i]);
328 }
329 return result;
330}
331/*----------------------------------------------------------------------------*/
340/*----------------------------------------------------------------------------*/
341
342void
343moo_cube_delete(moo_cube *self)
344{
345 if (self != NULL) {
346 int i;
347 if (self->primary_header != NULL) {
348 cpl_propertylist_delete(self->primary_header);
349 }
350 for (i = 0; i < 6; i++) {
351 if (self->data[i] != NULL) {
352 cpl_imagelist_delete(self->data[i]);
353 }
354 if (self->data_header[i] != NULL) {
355 cpl_propertylist_delete(self->data_header[i]);
356 }
357 }
358 cpl_free(self->filename);
359 cpl_free(self);
360 }
361}
moo_cube * moo_cube_new(void)
Create a new moo_cube.
Definition: moo_cube.c:66
cpl_error_code moo_cube_add_data(moo_cube *self, cpl_imagelist *list, moo_detector_type type, int ntas)
Add CPL_IMAGELIST extension to CUBE filename and update moo_cube structure.
Definition: moo_cube.c:147
void moo_cube_delete(moo_cube *self)
Delete a moo_cube.
Definition: moo_cube.c:343
moo_cube * moo_cube_merge(moo_cube *cubea, moo_saturate_map *saturatea, moo_cube *cubeb, moo_saturate_map *saturateb)
Merging two cubes.
Definition: moo_cube.c:312
cpl_error_code moo_cube_normalise(moo_cube *self, moo_saturate_map *map)
Normalise a moo_cube using saturate map.
Definition: moo_cube.c:238
void moo_cube_save(moo_cube *self, const char *filename)
Save a moo_cube to a FITS file.
Definition: moo_cube.c:191
cpl_error_code moo_cube_set_data(moo_cube *self, moo_detector_type type, int ntas, cpl_imagelist *data, cpl_propertylist *header)
set cube data for relevant extension
Definition: moo_cube.c:119
const char * moo_detector_get_extname(moo_detector_type type, int ntas)
Get the extension name of a detector.
Definition: moo_detector.c:137
enum _moo_detector_type_ moo_detector_type
The type code type.
Definition: moo_detector.h:64
cpl_imagelist * moo_fits_load_extension_cube(const char *filename, const char *name, const char *detectorname, cpl_type type)
Load a cube from FITS file.
Definition: moo_fits.c:455
cpl_error_code moo_fits_write_extension_cube(cpl_imagelist *cube, const char *filename, const char *name, const char *detectorname, cpl_type type, cpl_propertylist *header)
Write a cube as extension in FITS file.
Definition: moo_fits.c:250
int moo_pfits_get_naxis(const cpl_propertylist *plist)
find out the NAXIS value
Definition: moo_pfits.c:980