IIINSTRUMENT Pipeline Reference Manual 4.4.3
visir_util_convert_weight.c
1/* $Id: visir_util_convert_weight.c,v 1.16 2012-05-09 11:34:11 jtaylor Exp $
2 *
3 * This file is part of the VISIR Pipeline
4 * Copyright (C) 2011 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: jtaylor $
23 * $Date: 2012-05-09 11:34:11 $
24 * $Revision: 1.16 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*-----------------------------------------------------------------------------
33 Includes
34 -----------------------------------------------------------------------------*/
35
36#include "visir_recipe.h"
37
38/* Verify self-consistency of header files by including system files last */
39#include <string.h>
40
41/*-----------------------------------------------------------------------------
42 Defines
43 -----------------------------------------------------------------------------*/
44
45#define RECIPE_STRING "visir_util_convert_weight"
46
47#define VISIR_FRAME_WEIGHT 0
48#define VISIR_FRAME_ERROR 1
49#define VISIR_FRAME_VARIANCE 2
50
51
52/*-----------------------------------------------------------------------------
53 Private Functions prototypes
54 -----------------------------------------------------------------------------*/
55
56static cpl_error_code visir_util_convert_weight_one(cpl_frameset *,
57 irplib_framelist *,
58 const cpl_frame *, int,
59 const cpl_parameterlist *);
60
61cpl_recipe_define(visir_util_convert_weight, VISIR_BINARY_VERSION,
62 "Lars Lundin", PACKAGE_BUGREPORT, "2011",
63 "Conversion between different weight maps",
64 "The files listed in the Set Of Frames (sof-file) "
65 "must be tagged:\n"
66 "VISIR-weight-map.fits " VISIR_UTIL_WEIGHT_MAP " or\n"
67 "VISIR-error-map.fits " VISIR_UTIL_ERROR_MAP " or\n"
68 "VISIR-variance-map.fits " VISIR_UTIL_VARIANCE_MAP "\n"
69 "VISIR-bpm-file.fits " VISIR_CALIB_BPM " (optional)\n"
70 "\nThe relation between an error e, a weight w and a "
71 "variance v is:\n"
72 "e = sqrt(v) = 1/sqrt(w).\n"
73 "\n"
74 "Depending on the setting of the boolean recipe parameters "
75 "each input file will cause the following product(s) to be "
76 "created (each with a FITS card 'HIERARCH " CPL_DFS_PRO_CATG
77 "' with the specified value)\n"
78 VISIR_UTIL_ERROR_MAP_PROCATG
79 ": An error map, requires input v >= 0, w > 0\n"
80 VISIR_UTIL_WEIGHT_MAP_PROCATG
81 ": A weight map, requires input e > 0, v > 0\n"
82 VISIR_UTIL_VARIANCE_MAP_PROCATG
83 ": A variance map, requires input e >= 0, w > 0\n"
84 "If for a given input the identical output is specified, "
85 "the data unit(s) may still change according to the provided "
86 "bad pixel map\n"
87 "In a weight map product any bad pixel is set to 0.\n"
88 "In a variance or error map product any bad pixel is set to "
89 "the value specified by the relevant recipe option.");
90
91/*----------------------------------------------------------------------------*/
95/*----------------------------------------------------------------------------*/
96
97/*-----------------------------------------------------------------------------
98 Functions code
99 -----------------------------------------------------------------------------*/
100
101
102/*----------------------------------------------------------------------------*/
110/*----------------------------------------------------------------------------*/
111static cpl_error_code
112visir_util_convert_weight_fill_parameterlist(cpl_parameterlist * self)
113{
114 const char * context = PACKAGE "." RECIPE_STRING;
115 cpl_error_code err;
116
117 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
118
119 /* Fill the parameters list */
120
121 /* --error */
122 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING, "error",
123 CPL_TRUE, NULL, context, "Convert to "
124 "error");
125 cpl_ensure_code(!err, err);
126
127
128 /* --weight */
129 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING, "weight",
130 CPL_FALSE, NULL, context, "Convert to "
131 "weight. Bad pixels are seto to 0");
132 cpl_ensure_code(!err, err);
133
134
135 /* --variance */
136 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING, "variance",
137 CPL_FALSE, NULL, context, "Convert to "
138 "variance. Bad pixels are seto to 0");
139 cpl_ensure_code(!err, err);
140
141
142 /* --bad_value */
143 err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
144 "bad_value", FLT_MAX, NULL, context,
145 "The value to use for any bad pixel "
146 "in an error or variance map");
147 cpl_ensure_code(!err, err);
148
149 /* --bad_flag */
150 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
151 "bad_flag", CPL_TRUE, NULL, context,
152 "The value used to flag a bad pixel "
153 "in an input bad pixel map. True: 1. "
154 "False: 0.");
155 cpl_ensure_code(!err, err);
156
157 return CPL_ERROR_NONE;
158}
159
160
161
162/*----------------------------------------------------------------------------*/
169/*----------------------------------------------------------------------------*/
170static int visir_util_convert_weight(cpl_frameset * framelist,
171 const cpl_parameterlist * parlist)
172{
173 cpl_error_code didfail = CPL_ERROR_NONE;
174 irplib_framelist * allframes = NULL;
175 irplib_framelist * rawframes = NULL;
176 const cpl_frame * bpmframe = NULL;
177 int i, n;
178
179
180 /* Identify the RAW and CALIB frames in the input frameset */
181 skip_if (visir_dfs_set_groups(framelist));
182 cpl_fits_set_mode(CPL_FITS_START_CACHING);
183
184 /* Objects observation */
185 allframes = irplib_framelist_cast(framelist);
186 skip_if(allframes == NULL);
187 rawframes = irplib_framelist_extract_regexp(allframes, "^("
188 VISIR_UTIL_WEIGHT_MAP "|"
189 VISIR_UTIL_VARIANCE_MAP "|"
190 VISIR_UTIL_ERROR_MAP ")$",
191 CPL_FALSE);
192 skip_if (rawframes == NULL);
193 bpmframe = cpl_frameset_find_const(framelist, VISIR_CALIB_BPM);
194
195 any_if("Propagating error");
196
197 n = irplib_framelist_get_size(rawframes);
198 for (i = 0; i < n; i++) {
199
200 skip_if (visir_util_convert_weight_one(framelist, rawframes, bpmframe,
201 i, parlist));
202 cpl_fits_set_mode(CPL_FITS_RESTART_CACHING);
203 }
204
205 error_if(didfail, didfail, "Failed to convert data in %d frame(s)", n);
206
207 end_skip;
208
209 irplib_framelist_delete(allframes);
210 irplib_framelist_delete(rawframes);
211
212 return cpl_error_get_code();
213}
214
215
216/*----------------------------------------------------------------------------*/
226/*----------------------------------------------------------------------------*/
227static
228cpl_error_code visir_util_convert_weight_one(cpl_frameset * framelist,
229 irplib_framelist * rawframes,
230 const cpl_frame * bpmframe, int i,
231 const cpl_parameterlist * parlist)
232{
233
234 const int n = irplib_framelist_get_size(rawframes);
235 const cpl_boolean do_w = irplib_parameterlist_get_bool(parlist, PACKAGE,
236 RECIPE_STRING,
237 "weight");
238 const cpl_boolean do_e = irplib_parameterlist_get_bool(parlist, PACKAGE,
239 RECIPE_STRING,
240 "error");
241 const cpl_boolean do_v = irplib_parameterlist_get_bool(parlist, PACKAGE,
242 RECIPE_STRING,
243 "variance");
244 const double bad_val = irplib_parameterlist_get_double(parlist, PACKAGE,
245 RECIPE_STRING,
246 "bad_value");
247
248 const cpl_boolean bad_flag = irplib_parameterlist_get_bool(parlist, PACKAGE,
249 RECIPE_STRING,
250 "bad_flag");
251
252 cpl_errorstate prestate = cpl_errorstate_get();
253 cpl_frameset * products = cpl_frameset_new();
254 cpl_frameset * usedframes = cpl_frameset_new();
255 const cpl_frame * frame = irplib_framelist_get_const(rawframes, i);
256 const char * tag = cpl_frame_get_tag(frame);
257 const int frametype =
258 tag != NULL && !strcmp(tag, VISIR_UTIL_WEIGHT_MAP)
259 ? VISIR_FRAME_WEIGHT : (tag != NULL && !strcmp(tag, VISIR_UTIL_ERROR_MAP)
260 ? VISIR_FRAME_ERROR : VISIR_FRAME_VARIANCE);
261 const char * filename = cpl_frame_get_filename(frame);
262 const int next = cpl_fits_count_extensions(filename);
263 cpl_imagelist * map = NULL;
264 cpl_imagelist * emap = NULL;
265 cpl_imagelist * wmap = NULL;
266 cpl_imagelist * vmap = NULL;
267 const char * bpmname = bpmframe ? cpl_frame_get_filename(bpmframe)
268 : NULL;
269 const int mext = bpmname ? cpl_fits_count_extensions(bpmname)
270 : -1;
271 cpl_image * ibpm = NULL;
272 cpl_image * isqr = NULL;
273 cpl_image * ione = NULL;
274 cpl_image * idiv = NULL;
275 cpl_mask * bpm = NULL;
276 cpl_mask * bpmi = NULL;
277 cpl_propertylist * plist = NULL;
278
279 char * eproname = do_e == CPL_FALSE ? NULL
280 : cpl_sprintf(RECIPE_STRING "_%03d_error" CPL_DFS_FITS, 1+i);
281 char * wproname = do_w == CPL_FALSE ? NULL
282 : cpl_sprintf(RECIPE_STRING "_%03d_weight" CPL_DFS_FITS, 1+i);
283 char * vproname = do_v == CPL_FALSE ? NULL
284 : cpl_sprintf(RECIPE_STRING "_%03d_variance" CPL_DFS_FITS, 1+i);
285 int iext;
286
287 cpl_msg_info(cpl_func, "Converting %d Data unit(s) in frame %d/%d",
288 1+next, 1+i, n);
289
290 any_if("Propagating error");
291
292 if (bpmname != NULL) {
293 error_if(mext != 1 && mext != next, CPL_ERROR_INCOMPATIBLE_INPUT,
294 "Raw file %s has %d extension(s) <=> %d extension(s) of bpm-"
295 "file %s", filename, next, mext, bpmname);
296 }
297
298 for (iext = 0; iext <= next; iext++) {
299
300 /* Do not load the PRO.CATG */
301 cpl_propertylist_delete(plist);
302 plist = cpl_propertylist_load_regexp(filename, iext, CPL_DFS_PRO_CATG,
303 CPL_TRUE);
304 /* Update the headers before saving */
305 visir_dfs_update_header(plist);
306
307 skip_if(plist == NULL);
308
309 if (emap != map) cpl_imagelist_delete(emap);
310 emap = NULL;
311 if (wmap != map) cpl_imagelist_delete(wmap);
312 wmap = NULL;
313 if (vmap != map) cpl_imagelist_delete(vmap);
314 vmap = NULL;
315
316 cpl_imagelist_delete(map);
317 map = cpl_imagelist_load(filename, CPL_TYPE_FLOAT, iext);
318 if (!cpl_errorstate_is_equal(prestate)) {
319 cpl_errorstate_set(prestate);
320 } else {
321 /* FIXME: Use cpl_imagelist_power(map, -0.5);
322 once DFS10528 is fixed */
323 int j;
324 const int m = cpl_imagelist_get_size(map);
325
326 if (iext <= mext) {
327 /* Get new bad pixel map, if any */
328 cpl_image_delete(ibpm);
329 ibpm = cpl_image_load(bpmname, CPL_TYPE_UNSPECIFIED, 0, iext);
330 cpl_mask_delete(bpm);
331 bpm = cpl_mask_threshold_image_create(ibpm, 0.5, DBL_MAX);
332 if (!bad_flag) cpl_mask_not(bpm);
333 skip_if(bpm == NULL);
334 }
335
336 for (j = 0; j < m; j++) {
337 cpl_image * imap = cpl_imagelist_get(map, j);
338
339 /* Reject anything non-positive */
340 cpl_mask_delete(bpmi);
341 bpmi = cpl_mask_threshold_image_create(imap, 0.0, DBL_MAX);
342 bug_if(cpl_mask_not(bpmi));
343
344 /* Reject also any a-priori bad pixels */
345 if (bpm)
346 skip_if(cpl_mask_or(bpmi, bpm));
347
348 bug_if(cpl_image_reject_from_mask(imap, bpmi));
349
350 /* FIXME: Protect division/power from any bad input pixels */
351 bug_if(cpl_image_fill_rejected(imap, 1.0));
352
353 if (frametype == VISIR_FRAME_WEIGHT) {
354
355 if (do_w) {
356 if (wmap == NULL) wmap = map;
357 }
358
359 if (do_v || do_e) {
360 /* Create variance map from weight map */
361
362 if (ione == NULL) {
363 ione = cpl_image_new(cpl_image_get_size_x(imap),
364 cpl_image_get_size_y(imap),
365 CPL_TYPE_FLOAT);
366 cpl_image_add_scalar(ione, 1.0);
367
368 }
369
370 idiv = cpl_image_divide_create(ione, imap);
371
372 /* Division should not create bad pixels,
373 but just be sure */
374 if (cpl_image_get_bpm_const(idiv))
375 bug_if(cpl_mask_or(bpmi,
376 cpl_image_get_bpm_const(idiv)));
377
378 bug_if(cpl_image_reject_from_mask(idiv, bpmi));
379 }
380
381 if (do_v) {
382 if (vmap == NULL)
383 vmap = do_w ? cpl_imagelist_new() : map;
384
385 /* Set/replace image in list */
386 bug_if(cpl_imagelist_set(vmap, idiv, j));
387 idiv = NULL;
388 }
389
390 if (do_e) {
391 if (emap == NULL)
392 emap = do_w || do_v ? cpl_imagelist_new() : map;
393
394 if (do_v) {
395 idiv = cpl_image_power_create(cpl_imagelist_get_const
396 (vmap, j), 0.5);
397 } else {
398 bug_if(cpl_image_power(idiv, 0.5));
399 }
400
401 /* Set/replace image in list */
402 bug_if(cpl_imagelist_set(emap, idiv, j));
403 idiv = NULL;
404 }
405 } else if (frametype == VISIR_FRAME_ERROR) {
406
407 if (do_e) {
408 if (emap == NULL) emap = map;
409 }
410
411 if (do_v) {
412 if (vmap == NULL)
413 vmap = do_e ? cpl_imagelist_new() : map;
414
415 if (do_e) {
416 isqr = cpl_image_power_create(imap, 2.0);
417
418 /* Set image in list */
419 bug_if(cpl_imagelist_set(vmap, isqr, j));
420 isqr = NULL;
421 } else {
422 bug_if(cpl_image_power(imap, 2.0));
423 }
424 }
425
426 if (do_w) {
427 if (wmap == NULL)
428 wmap = do_e || do_v ? cpl_imagelist_new() : map;
429
430 if (ione == NULL) {
431 ione = cpl_image_new(cpl_image_get_size_x(imap),
432 cpl_image_get_size_y(imap),
433 CPL_TYPE_FLOAT);
434 cpl_image_add_scalar(ione, 1.0);
435
436 }
437
438 if (do_v) {
439 idiv = cpl_image_divide_create
440 (ione, cpl_imagelist_get(vmap, j));
441 } else if (do_e) {
442 isqr = cpl_image_power_create(imap, 2.0);
443 idiv = cpl_image_divide_create(ione, isqr);
444 } else {
445 bug_if(cpl_image_power(imap, 2.0));
446 idiv = cpl_image_divide_create(ione, imap);
447 }
448 cpl_image_delete(isqr);
449 isqr = NULL;
450
451 /* Set image in list */
452 bug_if(cpl_imagelist_set(wmap, idiv, j));
453 idiv = NULL;
454 }
455
456 } else if (frametype == VISIR_FRAME_VARIANCE) {
457 if (do_v) {
458 if (vmap == NULL) vmap = map;
459 }
460
461 if (do_w) {
462 if (wmap == NULL)
463 wmap = do_v ? cpl_imagelist_new() : map;
464
465 if (ione == NULL) {
466 ione = cpl_image_new(cpl_image_get_size_x(imap),
467 cpl_image_get_size_y(imap),
468 CPL_TYPE_FLOAT);
469 cpl_image_add_scalar(ione, 1.0);
470
471 }
472
473 idiv = cpl_image_divide_create(ione, imap);
474
475 /* Division should not create bad pixels,
476 but just be sure */
477 if (cpl_image_get_bpm_const(idiv))
478 bug_if(cpl_mask_or(bpmi,
479 cpl_image_get_bpm_const(idiv)));
480
481 bug_if(cpl_image_reject_from_mask(idiv, bpmi));
482
483 /* Set image in list */
484 bug_if(cpl_imagelist_set(wmap, idiv, j));
485 idiv = NULL;
486 }
487
488 if (do_e) {
489 if (emap == NULL)
490 emap = do_v || do_w ? cpl_imagelist_new() : map;
491
492 if (do_v || do_w) {
493 isqr = cpl_image_power_create(imap, 0.5);
494 /* Set/replace image in list */
495 bug_if(cpl_imagelist_set(emap, isqr, j));
496 isqr = NULL;
497
498 } else {
499 bug_if(cpl_image_power(imap, 0.5));
500 }
501 }
502 } else {
503 bug_if(1);
504 }
505
506 /* Set/Zero bad pixels */
507 if (do_w) {
508 bug_if(cpl_image_fill_rejected(cpl_imagelist_get
509 (wmap, j), 0.0));
510 }
511 if (do_e) {
512 bug_if(cpl_image_fill_rejected(cpl_imagelist_get
513 (emap, j), bad_val));
514 }
515 if (do_v) {
516 /* Set bad pixels */
517 bug_if(cpl_image_fill_rejected(cpl_imagelist_get
518 (vmap, j), bad_val));
519 }
520 }
521
522 }
523
524 if (iext == 0) {
525
526 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate
527 (frame)));
528 if (bpmframe != NULL)
529 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate
530 (bpmframe)));
531
532 if (do_w) {
533 if (wmap == NULL) {
534 skip_if(irplib_dfs_save_propertylist(products, parlist,
535 usedframes,
536 RECIPE_STRING,
537 VISIR_UTIL_WEIGHT_MAP_PROCATG,
538 plist, NULL,
539 visir_pipe_id,
540 wproname));
541 } else {
542 skip_if(irplib_dfs_save_imagelist(products, parlist,
543 usedframes, wmap,
544 CPL_BPP_IEEE_FLOAT,
545 RECIPE_STRING,
546 VISIR_UTIL_WEIGHT_MAP_PROCATG,
547 plist, NULL,
548 visir_pipe_id, wproname));
549 }
550 }
551 if (do_e) {
552 if (emap == NULL) {
553 skip_if(irplib_dfs_save_propertylist(products, parlist,
554 usedframes,
555 RECIPE_STRING,
556 VISIR_UTIL_ERROR_MAP_PROCATG,
557 plist, NULL,
558 visir_pipe_id,
559 eproname));
560 } else {
561 skip_if(irplib_dfs_save_imagelist(products, parlist,
562 usedframes, emap,
563 CPL_BPP_IEEE_FLOAT,
564 RECIPE_STRING,
565 VISIR_UTIL_ERROR_MAP_PROCATG,
566 plist, NULL,
567 visir_pipe_id, eproname));
568 }
569 }
570 if (do_v) {
571 if (vmap == NULL) {
572 skip_if(irplib_dfs_save_propertylist(products, parlist,
573 usedframes,
574 RECIPE_STRING,
575 VISIR_UTIL_VARIANCE_MAP_PROCATG,
576 plist, NULL,
577 visir_pipe_id,
578 vproname));
579 } else {
580 skip_if(irplib_dfs_save_imagelist(products, parlist,
581 usedframes, vmap,
582 CPL_BPP_IEEE_FLOAT,
583 RECIPE_STRING,
584 VISIR_UTIL_VARIANCE_MAP_PROCATG,
585 plist, NULL,
586 visir_pipe_id, vproname));
587 }
588 }
589 } else {
590 if (do_w) {
591 if (wmap == NULL) {
592 skip_if(cpl_propertylist_save(plist, wproname,
593 CPL_IO_EXTEND));
594 } else {
595 skip_if(cpl_imagelist_save(wmap, wproname,
596 CPL_BPP_IEEE_FLOAT, plist,
597 CPL_IO_EXTEND));
598 }
599 }
600 if (do_e) {
601 if (emap == NULL) {
602 skip_if(cpl_propertylist_save(plist, eproname,
603 CPL_IO_EXTEND));
604 } else {
605 skip_if(cpl_imagelist_save(emap, eproname,
606 CPL_BPP_IEEE_FLOAT, plist,
607 CPL_IO_EXTEND));
608 }
609 }
610 if (do_v) {
611 if (vmap == NULL) {
612 skip_if(cpl_propertylist_save(plist, vproname,
613 CPL_IO_EXTEND));
614 } else {
615 skip_if(cpl_imagelist_save(vmap, vproname,
616 CPL_BPP_IEEE_FLOAT, plist,
617 CPL_IO_EXTEND));
618 }
619 }
620 }
621 }
622
623 FOR_EACH_FRAMESET_C(frm, products) {
624 cpl_frame * copy = cpl_frame_duplicate(frm);
625 cpl_error_code error = cpl_frameset_insert(framelist, copy);
626
627 if (error) break;
628 }
629 bug_if(frame != NULL);
630
631 end_skip;
632
633 if (emap != map) cpl_imagelist_delete(emap);
634 if (wmap != map) cpl_imagelist_delete(wmap);
635 if (vmap != map) cpl_imagelist_delete(vmap);
636 cpl_imagelist_delete(map);
637 cpl_free(eproname);
638 cpl_free(wproname);
639 cpl_free(vproname);
640 cpl_image_delete(ione);
641 cpl_image_delete(idiv);
642 cpl_image_delete(isqr);
643 cpl_image_delete(ibpm);
644 cpl_mask_delete(bpm);
645 cpl_mask_delete(bpmi);
646 cpl_propertylist_delete(plist);
647 cpl_frameset_delete(usedframes);
648 cpl_frameset_delete(products);
649
650 return cpl_error_get_code();
651
652}
653
654
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: visir_dfs.c:72