MOONS Pipeline Reference Manual 0.13.2
moo_loc_single.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_utils.h"
31#include "moo_loc.h"
32#include "moo_loc_single.h"
33#include "moo_fits.h"
34#include "moo_qc.h"
35#include "moo_single.h"
36/*----------------------------------------------------------------------------*/
52/*----------------------------------------------------------------------------*/
53
56/*-----------------------------------------------------------------------------
57 Function codes
58 -----------------------------------------------------------------------------*/
59
60/*----------------------------------------------------------------------------*/
68/*----------------------------------------------------------------------------*/
69moo_loc_single *
71{
72 moo_loc_single *res = cpl_calloc(1, sizeof(moo_loc_single));
73 return res;
74}
75
76/*----------------------------------------------------------------------------*/
87/*----------------------------------------------------------------------------*/
88moo_loc_single *
89moo_loc_single_create(const char *filename, const char *extname)
90{
91 moo_loc_single *res = NULL;
92
93 cpl_ensure(filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
94 cpl_ensure(extname != NULL, CPL_ERROR_NULL_INPUT, NULL);
95
96 res = moo_loc_single_new();
97
98 res->extname = extname;
99 res->filename = filename;
100
101 return res;
102}
103
104
105/*----------------------------------------------------------------------------*/
114/*----------------------------------------------------------------------------*/
115
116void
117moo_loc_single_delete(moo_loc_single *self)
118{
119 if (self != NULL) {
120 if (self->f_centroids != NULL) {
121 cpl_image_delete(self->f_centroids);
122 }
123 if (self->m_centroids != NULL) {
124 cpl_image_delete(self->m_centroids);
125 }
126 if (self->f_wlow != NULL) {
127 cpl_image_delete(self->f_wlow);
128 }
129 if (self->f_wup != NULL) {
130 cpl_image_delete(self->f_wup);
131 }
132 if (self->m_wlow != NULL) {
133 cpl_image_delete(self->m_wlow);
134 }
135 if (self->m_wup != NULL) {
136 cpl_image_delete(self->m_wup);
137 }
138 if (self->flags != NULL) {
139 cpl_image_delete(self->flags);
140 }
141 if (self->header != NULL) {
142 cpl_propertylist_delete(self->header);
143 }
144 cpl_free(self);
145 }
146}
147/*----------------------------------------------------------------------------*/
158/*----------------------------------------------------------------------------*/
159void
160moo_loc_single_save(const moo_loc_single *self,
161 const char *filename,
162 int keep_points)
163{
164 if (self != NULL) {
165 moo_fits_write_extension_image(self->m_centroids, filename,
166 MOO_LOC_SINGLE_MCENTROID, self->extname,
167 CPL_TYPE_FLOAT, self->header);
168 moo_fits_write_extension_image(self->f_centroids, filename,
169 MOO_LOC_SINGLE_FCENTROID, self->extname,
170 CPL_TYPE_FLOAT, self->header);
171 moo_fits_write_extension_image(self->f_wlow, filename,
172 MOO_LOC_SINGLE_WLO, self->extname,
173 CPL_TYPE_FLOAT, self->header);
174 moo_fits_write_extension_image(self->f_wup, filename,
175 MOO_LOC_SINGLE_WUP, self->extname,
176 CPL_TYPE_FLOAT, self->header);
177
178 if (keep_points == 1) {
179 moo_fits_write_extension_image(self->m_wlow, filename,
180 MOO_LOC_SINGLE_MWLO, self->extname,
181 CPL_TYPE_FLOAT, self->header);
182 moo_fits_write_extension_image(self->m_wup, filename,
183 MOO_LOC_SINGLE_MWUP, self->extname,
184 CPL_TYPE_FLOAT, self->header);
185 moo_fits_write_extension_image(self->flags, filename,
186 MOO_LOC_SINGLE_FLAGS, self->extname,
187 CPL_TYPE_INT, NULL);
188 }
189 }
190}
191
192/*----------------------------------------------------------------------------*/
204/*----------------------------------------------------------------------------*/
205cpl_error_code
206moo_loc_single_dump(const moo_loc_single *self, FILE *stream)
207{
208 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
209 cpl_ensure_code(stream != NULL, CPL_ERROR_NULL_INPUT);
210
211 fprintf(stream, "---MOO_LOC_SINGLE\n");
212 fprintf(stream, "filename %s extname %s\n", self->filename, self->extname);
213 fprintf(stream, "mcentroids %p\n", (void *)self->m_centroids);
214 fprintf(stream, "fcentroids %p\n", (void *)self->f_centroids);
215 return CPL_ERROR_NONE;
216}
217
218/*----------------------------------------------------------------------------*/
229/*----------------------------------------------------------------------------*/
230cpl_propertylist *
231moo_loc_single_get_header(moo_loc_single *self)
232{
233 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
234 cpl_ensure(self->filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
235 cpl_ensure(self->extname != NULL, CPL_ERROR_NULL_INPUT, NULL);
236
237 if (self->header == NULL) {
238 self->header = moo_fits_load_extension_header(self->filename,
239 MOO_LOC_SINGLE_MCENTROID,
240 self->extname);
241 if (self->header == NULL) {
242 self->header = cpl_propertylist_new();
243 }
244 }
245 return self->header;
246}
247/*----------------------------------------------------------------------------*/
258/*----------------------------------------------------------------------------*/
259cpl_image *
261{
262 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
263 cpl_ensure(self->filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
264 cpl_ensure(self->extname != NULL, CPL_ERROR_NULL_INPUT, NULL);
265
266 if (self->f_centroids == NULL) {
267 self->f_centroids =
268 moo_fits_load_extension_image(self->filename,
269 MOO_LOC_SINGLE_FCENTROID,
270 self->extname, CPL_TYPE_DOUBLE);
271 }
272 return self->f_centroids;
273}
274
275/*----------------------------------------------------------------------------*/
289/*----------------------------------------------------------------------------*/
290double
292 double x,
293 int indexext,
294 int *rej)
295{
296 double res;
297 int rej1, rej2;
298 cpl_image *fcentroids = moo_loc_single_get_f_centroids(self);
299 int x1 = (int)floor(x);
300 int x2 = (int)ceil(x);
301 double y1 = cpl_image_get(fcentroids, x1, indexext, &rej1);
302 double y2 = cpl_image_get(fcentroids, x2, indexext, &rej2);
303 *rej = rej1 + rej2;
304 res = y1 * (x - x1) + y2 * (x2 - x);
305 return res;
306}
307
308/*----------------------------------------------------------------------------*/
319/*----------------------------------------------------------------------------*/
320cpl_image *
322{
323 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
324 cpl_ensure(self->filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
325 cpl_ensure(self->extname != NULL, CPL_ERROR_NULL_INPUT, NULL);
326
327 if (self->m_centroids == NULL) {
328 self->m_centroids =
329 moo_fits_load_extension_image(self->filename,
330 MOO_LOC_SINGLE_MCENTROID,
331 self->extname, CPL_TYPE_DOUBLE);
332 }
333 return self->m_centroids;
334}
335
336/*----------------------------------------------------------------------------*/
347/*----------------------------------------------------------------------------*/
348cpl_image *
349moo_loc_single_get_f_wlo(moo_loc_single *self)
350{
351 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
352 cpl_ensure(self->filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
353 cpl_ensure(self->extname != NULL, CPL_ERROR_NULL_INPUT, NULL);
354
355 if (self->f_wlow == NULL) {
356 self->f_wlow =
357 moo_fits_load_extension_image(self->filename, MOO_LOC_SINGLE_WLO,
358 self->extname, CPL_TYPE_DOUBLE);
359 }
360 return self->f_wlow;
361}
362
363/*----------------------------------------------------------------------------*/
373/*----------------------------------------------------------------------------*/
374cpl_image *
375moo_loc_single_get_f_wup(moo_loc_single *self)
376{
377 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
378 cpl_ensure(self->filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
379 cpl_ensure(self->extname != NULL, CPL_ERROR_NULL_INPUT, NULL);
380
381 if (self->f_wup == NULL) {
382 self->f_wup =
383 moo_fits_load_extension_image(self->filename, MOO_LOC_SINGLE_WUP,
384 self->extname, CPL_TYPE_DOUBLE);
385 }
386 return self->f_wup;
387}
388
389/*----------------------------------------------------------------------------*/
399/*----------------------------------------------------------------------------*/
400cpl_image *
401moo_loc_single_get_flags(moo_loc_single *self)
402{
403 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
404 cpl_ensure(self->filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
405 cpl_ensure(self->extname != NULL, CPL_ERROR_NULL_INPUT, NULL);
406
407 if (self->flags == NULL) {
408 self->flags =
409 moo_fits_load_extension_image(self->filename, MOO_LOC_SINGLE_FLAGS,
410 self->extname, CPL_TYPE_INT);
411 }
412 return self->flags;
413}
414
415cpl_error_code
416moo_loc_single_compute_qc_guess(moo_loc_single *self, int deg_poly)
417{
418 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
419
420 cpl_image *mc = moo_loc_single_get_m_centroids(self);
421 cpl_image *fc = moo_loc_single_get_f_centroids(self);
422 cpl_image *flo = moo_loc_single_get_f_wlo(self);
423 cpl_image *fup = moo_loc_single_get_f_wup(self);
424
425 cpl_image *flags = moo_loc_single_get_flags(self);
426 cpl_image *diff = cpl_image_subtract_create(mc, fc);
427 cpl_image *width = cpl_image_add_create(flo, fup);
428
429 int nx = cpl_image_get_size_x(diff);
430 int ny = cpl_image_get_size_y(diff);
431
432 cpl_binary *mask_data = cpl_mask_get_data(cpl_image_get_bpm(diff));
433 int *flags_data = cpl_image_get_data(flags);
434 int noutliers_pts = 0;
435 int noutliers_wid = 0;
436 int badpix = 0;
437
438 for (int i = 0; i < nx * ny; i++) {
439 if (flags_data[i] > 0) {
440 mask_data[i] = CPL_BINARY_1;
441 if (flags_data[i] == MOONS_FLAG_YDIFF_OUTLIERS) {
442 noutliers_pts++;
443 }
444 else if (flags_data[i] == MOONS_FLAG_WDIFF_OUTLIERS) {
445 noutliers_wid++;
446 }
447 else if (flags_data[i] == MOONS_FLAG_BADPIX) {
448 badpix++;
449 }
450 }
451 }
452 cpl_image_reject_value(diff, CPL_VALUE_NAN);
453 cpl_image_reject_value(width, CPL_VALUE_NAN);
454
455 double sigma = cpl_image_get_stdev(diff);
456 double median = cpl_image_get_median(diff);
457 double mean = cpl_image_get_mean(diff);
458
459 cpl_propertylist *header = moo_loc_single_get_header(self);
460
461 moo_qc_set_residy_med(header, median);
462 moo_qc_set_residy_sd(header, sigma);
463 moo_qc_set_residy_avg(header, mean);
464 sigma = cpl_image_get_stdev(width);
465 median = cpl_image_get_median(width);
466 mean = cpl_image_get_mean(width);
467 moo_qc_set_widthy_med(header, median);
468 moo_qc_set_widthy_sd(header, sigma);
469 moo_qc_set_widthy_avg(header, mean);
470 moo_qc_set_fit_deg(header, deg_poly);
471 moo_qc_set_noutlier_pts(header, noutliers_pts);
472 moo_qc_set_noutlier_wid(header, noutliers_wid);
473 moo_qc_set_nbadpix(header, badpix);
474 cpl_image_delete(diff);
475 cpl_image_delete(width);
476
477 return CPL_ERROR_NONE;
478}
479
480cpl_error_code
481moo_loc_single_compute_qc_trace(moo_loc_single *self,
482 int deg_poly,
483 moo_loc_single *guess)
484{
485 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
486 cpl_ensure_code(guess != NULL, CPL_ERROR_NULL_INPUT);
487
488 cpl_image *mc = moo_loc_single_get_m_centroids(self);
489 cpl_image *guess_mc = moo_loc_single_get_m_centroids(guess);
490 cpl_image *fc = moo_loc_single_get_f_centroids(self);
491 cpl_image *guess_fc = moo_loc_single_get_f_centroids(guess);
492 cpl_image *flags = moo_loc_single_get_flags(self);
493
494 cpl_ensure_code(guess_mc != NULL, CPL_ERROR_NULL_INPUT);
495
496 cpl_image_reject_value(guess_mc, CPL_VALUE_NAN);
497
498
499 cpl_image *fdiff = cpl_image_subtract_create(fc, guess_fc);
500
501 int nx = cpl_image_get_size_x(mc);
502 int ny = cpl_image_get_size_y(mc);
503
504 cpl_binary *mask_data = cpl_mask_get_data(cpl_image_get_bpm(mc));
505 int *flags_data = cpl_image_get_data(flags);
506 int nbadprofile = 0;
507
508 for (int i = 0; i < nx * ny; i++) {
509 if (flags_data[i] > 0) {
510 mask_data[i] = CPL_BINARY_1;
511 if (flags_data[i] == MOONS_FLAG_BADPROFILE) {
512 nbadprofile++;
513 }
514 }
515 }
516
517 cpl_image *mdiff = cpl_image_subtract_create(mc, guess_mc);
518
519 cpl_image_reject_value(mdiff, CPL_VALUE_NAN);
520 cpl_image_reject_value(fdiff, CPL_VALUE_NAN);
521
522 double sigma = cpl_image_get_stdev(mdiff);
523 double median = cpl_image_get_median(mdiff);
524 double mean = cpl_image_get_mean(mdiff);
525
526 cpl_propertylist *header = moo_loc_single_get_header(self);
527
528 moo_qc_set_shifty_pts_med(header, median);
529 moo_qc_set_shifty_pts_sd(header, sigma);
530 moo_qc_set_shifty_pts_avg(header, mean);
531 moo_qc_set_fit_deg(header, deg_poly);
532 moo_qc_set_nbadprofile(header, nbadprofile);
533
534 sigma = cpl_image_get_stdev(fdiff);
535 median = cpl_image_get_median(fdiff);
536 mean = cpl_image_get_mean(fdiff);
537
538 moo_qc_set_shifty_fit_med(header, median);
539 moo_qc_set_shifty_fit_sd(header, sigma);
540 moo_qc_set_shifty_fit_avg(header, mean);
541
542 cpl_image_delete(fdiff);
543 cpl_image_delete(mdiff);
544
545 return CPL_ERROR_NONE;
546}
547
548/*----------------------------------------------------------------------------*/
559/*----------------------------------------------------------------------------*/
560cpl_mask *
561moo_loc_single_get_ODR(moo_loc_single *self, int size_y)
562{
563 cpl_mask *mask = NULL;
564
565 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
566
567 cpl_image *fc = moo_loc_single_get_f_centroids(self);
568 cpl_image *fwlo = moo_loc_single_get_f_wlo(self);
569 cpl_image *fwup = moo_loc_single_get_f_wup(self);
570
571 int size_x = cpl_image_get_size_x(fc);
572 int nb_fibres = cpl_image_get_size_y(fc);
573
574 mask = cpl_mask_new(size_x, size_y);
575
576 for (int j = 1; j <= nb_fibres; j++) {
577 for (int i = 1; i <= size_x; i++) {
578 int rej;
579 double fcv = cpl_image_get(fc, i, j, &rej);
580 if (!isnan(fcv)) {
581 double ylo = fcv - cpl_image_get(fwlo, i, j, &rej);
582 double yup = fcv + cpl_image_get(fwup, i, j, &rej);
583 int iylo = floor(ylo);
584 int iyup = ceil(yup);
585 for (int k = iylo; k <= iyup; k++) {
586 cpl_mask_set(mask, i, k, CPL_BINARY_1);
587 }
588 }
589 }
590 }
591 cpl_mask_not(mask);
592 return mask;
593}
cpl_error_code moo_fits_write_extension_image(cpl_image *image, const char *filename, const char *name, const char *detectorname, cpl_type type, cpl_propertylist *header)
Write an image as extension in FITS file.
Definition: moo_fits.c:123
cpl_image * moo_fits_load_extension_image(const char *filename, const char *name, const char *detectorname, cpl_type type)
Load an image from FITS file.
Definition: moo_fits.c:311
void moo_loc_single_delete(moo_loc_single *self)
Delete a moo_loc_single.
double moo_loc_single_eval_f_centroids(moo_loc_single *self, double x, int indexext, int *rej)
Get the Y fit centroid for a x value.
void moo_loc_single_save(const moo_loc_single *self, const char *filename, int keep_points)
Save a moo_loc_single to a FITS file.
cpl_error_code moo_loc_single_dump(const moo_loc_single *self, FILE *stream)
Dump structural information of LOC_SINGLE.
moo_loc_single * moo_loc_single_new(void)
Create a new moo_loc_single.
cpl_image * moo_loc_single_get_f_wup(moo_loc_single *self)
Get image of width low.
cpl_image * moo_loc_single_get_f_centroids(moo_loc_single *self)
Get image of fit centroids.
cpl_image * moo_loc_single_get_flags(moo_loc_single *self)
Get image of flags.
cpl_image * moo_loc_single_get_m_centroids(moo_loc_single *self)
Get image of measured centroids.
cpl_propertylist * moo_loc_single_get_header(moo_loc_single *self)
Get header of loc single.
moo_loc_single * moo_loc_single_create(const char *filename, const char *extname)
Create a new moo_loc_single from the given LOC filename.
cpl_image * moo_loc_single_get_f_wlo(moo_loc_single *self)
Get image of width low.
cpl_mask * moo_loc_single_get_ODR(moo_loc_single *self, int size_y)
Get outside data range mask far a DET single.
cpl_error_code moo_qc_set_widthy_sd(cpl_propertylist *plist, double val)
Set the QC.WIDTHY.STD value.
Definition: moo_qc.c:711
cpl_error_code moo_qc_set_shifty_fit_sd(cpl_propertylist *plist, double val)
Set the QC.SHIFTY.FIT.SD value.
Definition: moo_qc.c:913
cpl_error_code moo_qc_set_widthy_med(cpl_propertylist *plist, double val)
Set the QC.WIDTHY.MED value.
Definition: moo_qc.c:682
cpl_error_code moo_qc_set_nbadprofile(cpl_propertylist *plist, int val)
Set the QC.NBADPROFILE value.
Definition: moo_qc.c:1029
cpl_error_code moo_qc_set_noutlier_wid(cpl_propertylist *plist, int val)
Set the QC.NOUTLIER.WID value.
Definition: moo_qc.c:1000
cpl_error_code moo_qc_set_residy_med(cpl_propertylist *plist, double val)
Set the QC.RESIDY.MED value.
Definition: moo_qc.c:596
cpl_error_code moo_qc_set_shifty_pts_avg(cpl_propertylist *plist, double val)
Set the QC.SHIFTY.PTS.AVG value.
Definition: moo_qc.c:797
cpl_error_code moo_qc_set_widthy_avg(cpl_propertylist *plist, double val)
Set the QC.WIDTH.AVG value.
Definition: moo_qc.c:739
cpl_error_code moo_qc_set_residy_avg(cpl_propertylist *plist, double val)
Set the QC.RESIDY.AVG value.
Definition: moo_qc.c:653
cpl_error_code moo_qc_set_shifty_fit_avg(cpl_propertylist *plist, double val)
Set the QC.SHIFTY.FIT.AVG value.
Definition: moo_qc.c:884
cpl_error_code moo_qc_set_shifty_pts_sd(cpl_propertylist *plist, double val)
Set the QC.SHIFTY.PTS.SD value.
Definition: moo_qc.c:826
cpl_error_code moo_qc_set_fit_deg(cpl_propertylist *plist, int val)
Set the QC.RESIDY.AVG value.
Definition: moo_qc.c:942
cpl_error_code moo_qc_set_nbadpix(cpl_propertylist *plist, int val)
Set the QC.NBADPIX value.
Definition: moo_qc.c:1058
cpl_error_code moo_qc_set_noutlier_pts(cpl_propertylist *plist, int val)
Set the QC.NOUTLIER.PTS value.
Definition: moo_qc.c:971
cpl_error_code moo_qc_set_shifty_pts_med(cpl_propertylist *plist, double val)
Set the QC.SHIFTY.PTS.MED value.
Definition: moo_qc.c:768
cpl_error_code moo_qc_set_shifty_fit_med(cpl_propertylist *plist, double val)
Set the QC.SHIFTY.FIT.MED value.
Definition: moo_qc.c:855
cpl_error_code moo_qc_set_residy_sd(cpl_propertylist *plist, double val)
Set the QC.RESIDY.STD value.
Definition: moo_qc.c:625